hacktricks/binary-exploitation/integer-overflow.md

7.3 KiB

Integer Overflow

Impara l'hacking AWS da zero a ero con htARTE (Esperto Red Team AWS di HackTricks)!

Altri modi per supportare HackTricks:

Informazioni di Base

Al centro di un integer overflow 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" %}

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.

Example

#include <stdio.h>

int main() {
    unsigned int x = 4294967295; // Maximum value for 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 will result 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 being used.

{% endtab %}

#include <stdio.h>
#include <limits.h>

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:

#include <stdio.h>

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:

#include <stdio.h>

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;
}

In questo esempio, se un utente inserisce un numero negativo, verrà interpretato come un grande numero non firmato a causa del modo in cui i valori binari vengono interpretati, potenzialmente portando a comportamenti inaspettati.

Altri Esempi

(((argv[1] * 0x1064deadbeef4601) & 0xffffffffffffffff) == 0xD1038D2E07B42569)

ARM64

Questo non cambia in ARM64 come si può vedere in questo post sul blog.

Impara l'hacking di AWS da zero a eroe con htARTE (HackTricks AWS Red Team Expert)!

Altri modi per supportare HackTricks: