# Integer Overflow {{#include ../banners/hacktricks-training.md}} ## Osnovne informacije U srcu **integer overflow** je ograničenje koje nameće **veličina** tipova podataka u računarstvu i **tumačenje** podataka. Na primer, **8-bitni bez znak** može predstavljati vrednosti od **0 do 255**. Ako pokušate da sačuvate vrednost 256 u 8-bitnom bez znaka, ona se vraća na 0 zbog ograničenja svoje kapaciteta skladištenja. Slično tome, za **16-bitni bez znak**, koji može da drži vrednosti od **0 do 65,535**, dodavanje 1 na 65,535 će vratiti vrednost nazad na 0. Štaviše, **8-bitni sa znakom** može predstavljati vrednosti od **-128 do 127**. To je zato što se jedan bit koristi za predstavljanje znaka (pozitivan ili negativan), ostavljajući 7 bita za predstavljanje magnitude. Najnegativniji broj se predstavlja kao **-128** (binarno `10000000`), a najpozitivniji broj je **127** (binarno `01111111`). ### Maksimalne vrednosti Za potencijalne **web ranjivosti** veoma je zanimljivo znati maksimalne podržane vrednosti: {{#tabs}} {{#tab name="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 name="C"}} ```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; } ``` {{#endtab}} {{#endtabs}} ## Primeri ### Čista preliv Ispisani rezultat će biti 0 jer smo preli u 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; } ``` ### Signed to Unsigned Conversion Razmotrite situaciju u kojoj se potpisani ceo broj čita iz korisničkog unosa i zatim se koristi u kontekstu koji ga tretira kao nepotpisani ceo broj, bez odgovarajuće validacije: ```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; } ``` U ovom primeru, ako korisnik unese negativan broj, biće interpretiran kao veliki nesigned integer zbog načina na koji se binarne vrednosti interpretiraju, što može dovesti do neočekivanog ponašanja. ### Ostali primeri - [https://guyinatuxedo.github.io/35-integer_exploitation/int_overflow_post/index.html](https://guyinatuxedo.github.io/35-integer_exploitation/int_overflow_post/index.html) - Samo 1B se koristi za čuvanje veličine lozinke, tako da je moguće prepuniti je i naterati je da misli da je dužina 4, dok je zapravo 260, kako bi se zaobišla zaštita provere dužine. - [https://guyinatuxedo.github.io/35-integer_exploitation/puzzle/index.html](https://guyinatuxedo.github.io/35-integer_exploitation/puzzle/index.html) - Dati nekoliko brojeva, pronaći koristeći z3 novi broj koji pomnožen sa prvim daje drugi: ``` (((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/) - Samo 1B se koristi za čuvanje veličine lozinke, tako da je moguće prepuniti je i naterati je da misli da je dužina 4, dok je zapravo 260, kako bi se zaobišla zaštita provere dužine i prepisala sledeća lokalna promenljiva na steku, čime se zaobilaze obe zaštite. ## ARM64 Ovo **se ne menja u ARM64** kao što možete videti u [**ovom blog postu**](https://8ksec.io/arm64-reversing-and-exploitation-part-8-exploiting-an-integer-overflow-vulnerability/). {{#include ../banners/hacktricks-training.md}}