# Estouro de Inteiro
{% hint style="success" %}
Aprenda e pratique Hacking AWS:[**Treinamento HackTricks AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)\
Aprenda e pratique Hacking GCP: [**Treinamento HackTricks GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)
Apoie o HackTricks
* Verifique os [**planos de assinatura**](https://github.com/sponsors/carlospolop)!
* **Junte-se ao** 💬 [**grupo Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo telegram**](https://t.me/peass) ou **siga-nos** no **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Compartilhe truques de hacking enviando PRs para os repositórios** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
{% endhint %}
## Informações Básicas
No cerne de um **estouro de inteiro** está a limitação imposta pelo **tamanho** dos tipos de dados na programação de computadores e a **interpretação** dos dados.
Por exemplo, um **inteiro sem sinal de 8 bits** pode representar valores de **0 a 255**. Se você tentar armazenar o valor 256 em um inteiro sem sinal de 8 bits, ele será envolvido de volta para 0 devido à limitação de sua capacidade de armazenamento. Da mesma forma, para um **inteiro sem sinal de 16 bits**, que pode conter valores de **0 a 65.535**, adicionar 1 a 65.535 fará com que o valor volte para 0.
Além disso, um **inteiro com sinal de 8 bits** pode representar valores de **-128 a 127**. Isso ocorre porque um bit é usado para representar o sinal (positivo ou negativo), deixando 7 bits para representar a magnitude. O número mais negativo é representado como **-128** (binário `10000000`), e o número mais positivo é **127** (binário `01111111`).
### Valores Máximos
Para potenciais **vulnerabilidades web**, é muito interessante saber os valores máximos suportados:
{% 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" %}
## Transbordamento de Inteiro
Transbordamento de inteiro ocorre quando uma operação matemática resulta em um valor que excede o limite máximo ou mínimo que o tipo de dado pode armazenar. Isso pode levar a comportamentos inesperados e vulnerabilidades de segurança em programas.
Um exemplo comum de transbordamento de inteiro é quando um valor positivo é adicionado a um valor muito grande, resultando em um valor negativo devido ao estouro. Isso pode ser explorado por hackers para manipular o comportamento do programa e potencialmente executar código malicioso.
Para evitar transbordamentos de inteiro, é importante validar entradas, verificar limites de valores e usar tipos de dados apropriados para as operações matemáticas realizadas no programa.
{% endtab %}
```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;
}
```
## Exemplos
### Overflow puro
O resultado impresso será 0, pois ocorreu um estouro no 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;
}
```
### Conversão de Assinado para Não Assinado
Considere uma situação em que um inteiro assinado é lido a partir da entrada do usuário e depois utilizado em um contexto que o trata como um inteiro não assinado, sem uma validação adequada:
```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;
}
```
Neste exemplo, se um usuário inserir um número negativo, ele será interpretado como um grande inteiro não assinado devido à forma como os valores binários são interpretados, potencialmente levando a comportamentos inesperados.
### Outros Exemplos
* [https://guyinatuxedo.github.io/35-integer\_exploitation/int\_overflow\_post/index.html](https://guyinatuxedo.github.io/35-integer\_exploitation/int\_overflow\_post/index.html)
* Apenas 1B é usado para armazenar o tamanho da senha, então é possível causar um estouro e fazer com que ele pense que tem um comprimento de 4, enquanto na verdade é 260 para burlar a proteção de verificação de comprimento
* [https://guyinatuxedo.github.io/35-integer\_exploitation/puzzle/index.html](https://guyinatuxedo.github.io/35-integer\_exploitation/puzzle/index.html)
* Dados alguns números, descubra usando z3 um novo número que, multiplicado pelo primeiro, resultará no segundo:
```
(((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/)
* Apenas 1B é usado para armazenar o tamanho da senha, então é possível causar um estouro e fazer com que ele pense que tem um comprimento de 4, enquanto na verdade é 260 para burlar a proteção de verificação de comprimento e sobrescrever na pilha a próxima variável local e burlar ambas as proteções
## ARM64
Isso **não muda no ARM64** como você pode ver neste [**post de blog**](https://8ksec.io/arm64-reversing-and-exploitation-part-8-exploiting-an-integer-overflow-vulnerability/).