hacktricks/src/binary-exploitation/integer-overflow.md

116 lines
3.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 整数溢出
{{#include ../banners/hacktricks-training.md}}
## 基本信息
**整数溢出**的核心在于计算机编程中数据类型的**大小**所施加的限制和数据的**解释**
例如,一个**8位无符号整数**可以表示从**0到255**的值。如果你尝试在8位无符号整数中存储值256由于其存储容量的限制它会回绕到0。同样对于一个**16位无符号整数**,它可以容纳从**0到65,535**的值将1加到65,535会将值回绕到0。
此外,一个**8位有符号整数**可以表示从**-128到127**的值。这是因为一个位用于表示符号正或负剩下7个位用于表示大小。最小的负数表示为**-128**(二进制`10000000`),最大的正数是**127**(二进制`01111111`)。
### 最大值
对于潜在的**网络漏洞**,了解最大支持值是非常有趣的:
{{#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 <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;
}
```
{{#endtab}}
{{#endtabs}}
## 示例
### 纯溢出
打印的结果将是 0因为我们溢出了 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;
}
```
### 有符号到无符号转换
考虑一种情况,其中从用户输入中读取一个有符号整数,然后在一个将其视为无符号整数的上下文中使用,而没有进行适当的验证:
```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;
}
```
在这个例子中,如果用户输入一个负数,由于二进制值的解释方式,它将被解释为一个大的无符号整数,这可能导致意想不到的行为。
### 其他示例
- [https://guyinatuxedo.github.io/35-integer_exploitation/int_overflow_post/index.html](https://guyinatuxedo.github.io/35-integer_exploitation/int_overflow_post/index.html)
- 仅使用 1B 来存储密码的大小,因此可能会溢出并使其认为长度为 4而实际上是 260以绕过长度检查保护
- [https://guyinatuxedo.github.io/35-integer_exploitation/puzzle/index.html](https://guyinatuxedo.github.io/35-integer_exploitation/puzzle/index.html)
- 给定几个数字,使用 z3 找出一个新数字,使其与第一个数字相乘将得到第二个数字:&#x20;
```
(((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/)
- 仅使用 1B 来存储密码的大小,因此可能会溢出并使其认为长度为 4而实际上是 260以绕过长度检查保护并覆盖栈中的下一个局部变量从而绕过这两种保护
## ARM64
这在 ARM64 中**没有变化**,正如你在 [**这篇博客文章**](https://8ksec.io/arm64-reversing-and-exploitation-part-8-exploiting-an-integer-overflow-vulnerability/)中看到的。
{{#include ../banners/hacktricks-training.md}}