# Integer Overflow {% hint style="success" %} Impara e pratica l'hacking su AWS:[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)\ Impara e pratica l'hacking su GCP: [**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)
Sostieni HackTricks * Controlla i [**piani di abbonamento**](https://github.com/sponsors/carlospolop)! * **Unisciti al** 💬 [**gruppo Discord**](https://discord.gg/hRep4RUj7f) o al [**gruppo telegram**](https://t.me/peass) o **seguici** su **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.** * **Condividi trucchi di hacking inviando PR a** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
{% endhint %} ## Informazioni di Base Al centro di un **overflow di interi** c'è il limite imposto dalla **dimensione** dei tipi di dati nella programmazione informatica e dall'**interpretazione** dei dati. Ad esempio, un **intero non firmato a 8 bit** può rappresentare valori da **0 a 255**. Se si tenta di memorizzare il valore 256 in un intero non firmato a 8 bit, esso si riavvolge a 0 a causa della limitazione della sua capacità di memorizzazione. Allo stesso modo, per un **intero non firmato a 16 bit**, che può contenere valori da **0 a 65.535**, aggiungere 1 a 65.535 riavvolgerà il valore a 0. Inoltre, un **intero firmato a 8 bit** può rappresentare valori da **-128 a 127**. Questo perché un bit è utilizzato per rappresentare il segno (positivo o negativo), lasciando 7 bit per rappresentare la magnitudine. Il numero più negativo è rappresentato come **-128** (binario `10000000`), e il numero più positivo è **127** (binario `01111111`). ### Valori massimi Per potenziali **vulnerabilità web** è molto interessante conoscere i valori massimi supportati: {% tabs %} {% tab title="Rust" %} ```rust fn main() { let mut quantity = 2147483647; let (mul_result, _) = i32::overflowing_mul(32767, quantity); let (add_result, _) = i32::overflowing_add(1, quantity); println!("{}", mul_result); println!("{}", add_result); } ``` {% endtab %} {% tab title="C" %} ## Integer Overflow Integer overflow occurs when an arithmetic operation results in a value that exceeds the maximum size that the data type can hold. This can lead to unexpected behavior in the program, such as wrapping around to a minimum value or causing a crash. Integer overflow can be exploited by attackers to manipulate the program's behavior and potentially execute malicious code. ### Example ```c #include int main() { unsigned int x = 4294967295; // Maximum value for an unsigned int x = x + 1; printf("Value of x: %u\n", x); return 0; } ``` In this example, adding 1 to the maximum value of an unsigned integer results in an integer overflow, causing `x` to wrap around to 0. To prevent integer overflow, it is important to validate input values and check the result of arithmetic operations to ensure they do not exceed the limits of the data type. ```c #include #include int main() { int a = INT_MAX; int b = 0; int c = 0; b = a * 100; c = a + 1; printf("%d\n", INT_MAX); printf("%d\n", b); printf("%d\n", c); return 0; } ``` ## Esempi ### Overflow puro Il risultato stampato sarà 0 poiché abbiamo causato un overflow del char: ```c #include int main() { unsigned char max = 255; // 8-bit unsigned integer unsigned char result = max + 1; printf("Result: %d\n", result); // Expected to overflow return 0; } ``` ### Conversione da Segnato a Non Segnato Consideriamo una situazione in cui un numero intero segnato viene letto in input dall'utente e poi utilizzato in un contesto che lo tratta come un numero intero non segnato, senza una valida convalida: ```c #include int main() { int userInput; // Signed integer printf("Enter a number: "); scanf("%d", &userInput); // Treating the signed input as unsigned without validation unsigned int processedInput = (unsigned int)userInput; // A condition that might not work as intended if userInput is negative if (processedInput > 1000) { printf("Processed Input is large: %u\n", processedInput); } else { printf("Processed Input is within range: %u\n", processedInput); } return 0; } ``` ### Altri Esempi * [https://guyinatuxedo.github.io/35-integer\_exploitation/int\_overflow\_post/index.html](https://guyinatuxedo.github.io/35-integer\_exploitation/int\_overflow\_post/index.html) * Viene utilizzato solo 1B per memorizzare la dimensione della password, quindi è possibile fare un overflow e farlo pensare che la lunghezza sia di 4 mentre in realtà è di 260 per eludere il controllo della lunghezza * [https://guyinatuxedo.github.io/35-integer\_exploitation/puzzle/index.html](https://guyinatuxedo.github.io/35-integer\_exploitation/puzzle/index.html) * Dati un paio di numeri, scoprire utilizzando z3 un nuovo numero che moltiplicato per il primo darà il secondo: ``` (((argv[1] * 0x1064deadbeef4601) & 0xffffffffffffffff) == 0xD1038D2E07B42569) ``` * [https://8ksec.io/arm64-reversing-and-exploitation-part-8-exploiting-an-integer-overflow-vulnerability/](https://8ksec.io/arm64-reversing-and-exploitation-part-8-exploiting-an-integer-overflow-vulnerability/) * Viene utilizzato solo 1B per memorizzare la dimensione della password, quindi è possibile fare un overflow e farlo pensare che la lunghezza sia di 4 mentre in realtà è di 260 per eludere il controllo della lunghezza e sovrascrivere nello stack la variabile locale successiva ed eludere entrambe le protezioni ## ARM64 Questo **non cambia in ARM64** come si può vedere in [**questo post sul blog**](https://8ksec.io/arm64-reversing-and-exploitation-part-8-exploiting-an-integer-overflow-vulnerability/).