5.6 KiB
정수 오버플로우
{% hint style="success" %}
AWS 해킹 학습 및 실습:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 학습 및 실습: HackTricks Training GCP Red Team Expert (GRTE)
HackTricks 지원
- 구독 요금제를 확인하세요!
- 💬 디스코드 그룹 또는 텔레그램 그룹에 참여하거나 트위터 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 저장소에 PR을 제출하여 해킹 트릭을 공유하세요.
기본 정보
정수 오버플로우의 핵심은 컴퓨터 프로그래밍에서 데이터 유형의 크기와 데이터의 해석에 의해 부과된 제한입니다.
예를 들어, 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" %}
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 %}
#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이 될 것입니다:
#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;
}
부호 있는 정수를 부호 없는 정수로 변환
사용자 입력에서 읽은 부호 있는 정수가 적절한 유효성 검사 없이 부호 없는 정수로 취급되는 상황을 고려해보십시오:
#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
- 비밀번호의 크기를 저장하는 데 1B만 사용되므로 오버플로우를 발생시켜 실제 길이가 260인데 길이 확인 보호를 우회하여 길이가 4로 인식하도록 만들 수 있습니다.
- 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/
- 비밀번호의 크기를 저장하는 데 1B만 사용되므로 오버플로우를 발생시켜 실제 길이가 260인데 길이 확인 보호를 우회하여 길이가 4로 인식하도록 만들 수 있습니다. 또한 스택에 다음 로컬 변수를 덮어쓰고 두 보호 기능을 우회할 수 있습니다.
ARM64
이 ARM64에서도 변경되지 않습니다. 이 블로그 게시물에서 확인할 수 있습니다.