mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-24 21:53:54 +00:00
121 lines
5.6 KiB
Markdown
121 lines
5.6 KiB
Markdown
# 정수 오버플로우
|
|
|
|
{% hint style="success" %}
|
|
AWS 해킹 학습 및 실습:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
|
|
GCP 해킹 학습 및 실습: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
|
|
|
<details>
|
|
|
|
<summary>HackTricks 지원</summary>
|
|
|
|
* [**구독 요금제**](https://github.com/sponsors/carlospolop)를 확인하세요!
|
|
* 💬 [**디스코드 그룹**](https://discord.gg/hRep4RUj7f) 또는 [**텔레그램 그룹**](https://t.me/peass)에 **참여**하거나 **트위터** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**를 팔로우**하세요.
|
|
* **HackTricks** 및 **HackTricks Cloud** 깃허브 저장소에 PR을 제출하여 해킹 트릭을 공유하세요.
|
|
|
|
</details>
|
|
{% endhint %}
|
|
|
|
## 기본 정보
|
|
|
|
**정수 오버플로우**의 핵심은 컴퓨터 프로그래밍에서 데이터 유형의 **크기**와 데이터의 **해석**에 의해 부과된 제한입니다.
|
|
|
|
예를 들어, **8비트 부호 없는 정수**는 **0부터 255까지**의 값을 나타낼 수 있습니다. 8비트 부호 없는 정수에 256 값을 저장하려고 하면 저장 용량의 제한으로 인해 0으로 감싸집니다. 마찬가지로, **16비트 부호 없는 정수**는 **0부터 65,535까지**의 값을 보유할 수 있으며, 65,535에 1을 더하면 값이 다시 0으로 돌아갑니다.
|
|
|
|
또한, **8비트 부호 있는 정수**는 **-128부터 127까지**의 값을 나타낼 수 있습니다. 이는 하나의 비트가 부호(양수 또는 음수)를 나타내는 데 사용되어 크기를 나타내는 데 7비트가 남기 때문입니다. 가장 음수인 숫자는 **-128** (이진 `10000000`으로 표시)이고, 가장 양수인 숫자는 **127** (이진 `01111111`로 표시)입니다.
|
|
|
|
### 최대 값
|
|
|
|
잠재적인 **웹 취약점**을 위해 지원되는 최대 값을 알아두는 것이 매우 흥미로울 수 있습니다:
|
|
|
|
{% 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" %}
|
|
정수 오버플로우는 산술 연산에서 발생할 수 있는 일반적인 보안 취약점 중 하나입니다. 이러한 취약점은 변수가 특정 범위를 초과하여 최대값으로 다시 돌아가거나 음수가 될 때 발생합니다. 이러한 상황은 프로그램이 예상치 못한 방식으로 동작하게 하여 공격자가 코드 실행 흐름을 조작할 수 있게 합니다.
|
|
{% endtab %}
|
|
```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;
|
|
}
|
|
```
|
|
## 예시
|
|
|
|
### 순수 오버플로우
|
|
|
|
출력된 결과는 문자를 오버플로우했기 때문에 0이 될 것입니다:
|
|
```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만 사용되므로 오버플로우를 발생시켜 실제 길이가 260인데 길이 확인 보호를 우회하여 길이가 4로 인식하도록 만들 수 있습니다.
|
|
* [https://guyinatuxedo.github.io/35-integer\_exploitation/puzzle/index.html](https://guyinatuxedo.github.io/35-integer\_exploitation/puzzle/index.html)
|
|
* 몇 가지 숫자를 주어진 경우 z3를 사용하여 첫 번째 숫자와 곱해지는 새로운 숫자를 찾아보세요: 
|
|
|
|
```
|
|
(((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만 사용되므로 오버플로우를 발생시켜 실제 길이가 260인데 길이 확인 보호를 우회하여 길이가 4로 인식하도록 만들 수 있습니다. 또한 스택에 다음 로컬 변수를 덮어쓰고 두 보호 기능을 우회할 수 있습니다.
|
|
|
|
## ARM64
|
|
|
|
이 **ARM64에서도 변경되지 않습니다**. [**이 블로그 게시물**](https://8ksec.io/arm64-reversing-and-exploitation-part-8-exploiting-an-integer-overflow-vulnerability/)에서 확인할 수 있습니다.
|