Desbordamiento de Enteros

Reading time: 4 minutes

tip

Aprende y practica AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Apoya a HackTricks

Informaci贸n B谩sica

En el coraz贸n de un desbordamiento de enteros est谩 la limitaci贸n impuesta por el tama帽o de los tipos de datos en la programaci贸n de computadoras y la interpretaci贸n de los datos.

Por ejemplo, un entero sin signo de 8 bits puede representar valores de 0 a 255. Si intentas almacenar el valor 256 en un entero sin signo de 8 bits, se envuelve a 0 debido a la limitaci贸n de su capacidad de almacenamiento. De manera similar, para un entero sin signo de 16 bits, que puede contener valores de 0 a 65,535, agregar 1 a 65,535 har谩 que el valor vuelva a 0.

Adem谩s, un entero con signo de 8 bits puede representar valores de -128 a 127. Esto se debe a que un bit se utiliza para representar el signo (positivo o negativo), dejando 7 bits para representar la magnitud. El n煤mero m谩s negativo se representa como -128 (binario 10000000), y el n煤mero m谩s positivo es 127 (binario 01111111).

Valores m谩ximos

Para las posibles vulnerabilidades web, es muy interesante conocer los valores m谩ximos soportados:

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

Ejemplos

Desbordamiento puro

El resultado impreso ser谩 0 ya que desbordamos el char:

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

Conversi贸n de Entero Firmado a No Firmado

Considere una situaci贸n en la que un entero firmado se lee de la entrada del usuario y luego se utiliza en un contexto que lo trata como un entero no firmado, sin la validaci贸n adecuada:

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

En este ejemplo, si un usuario introduce un n煤mero negativo, se interpretar谩 como un gran entero sin signo debido a la forma en que se interpretan los valores binarios, lo que puede llevar a un comportamiento inesperado.

Otros Ejemplos

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

ARM64

Esto no cambia en ARM64 como puedes ver en este post del blog.

tip

Aprende y practica AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Apoya a HackTricks