7.2 KiB
정수 오버플로우
htARTE (HackTricks AWS Red Team Expert)를 통해 **제로**부터 **히어로**가 되어 **AWS 해킹을 배우세요**!
HackTricks를 지원하는 다른 방법:
- 회사가 HackTricks에 광고되길 원하거나 PDF로 HackTricks 다운로드하려면 구독 요금제를 확인하세요!
- 공식 PEASS & HackTricks 스왜그를 구매하세요
- The PEASS Family를 발견하세요, 저희의 독점 NFTs 컬렉션
- **💬 디스코드 그룹**에 가입하거나 텔레그램 그룹에 가입하거나 트위터 🐦 @hacktricks_live를 팔로우하세요.
- 해킹 트릭을 공유하려면 PR을 HackTricks 및 HackTricks Cloud 깃허브 저장소에 제출하세요.
기본 정보
정수 오버플로우의 핵심은 컴퓨터 프로그래밍의 데이터 유형의 크기에 의해 부과된 제한과 데이터의 해석에 있습니다.
예를 들어, 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;
}
예시
순수 오버플로우
출력된 결과는 char를 오버플로우했기 때문에 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에서도 변경되지 않습니다. 이 블로그 게시물에서 확인할 수 있습니다.
htARTE (HackTricks AWS Red Team Expert)로부터 AWS 해킹을 제로부터 전문가까지 배우세요 htARTE (HackTricks AWS Red Team Expert)!
HackTricks를 지원하는 다른 방법:
- 회사를 HackTricks에서 광고하거나 HackTricks를 PDF로 다운로드하려면 구독 요금제를 확인하세요!
- 공식 PEASS & HackTricks 스왜그를 구매하세요
- The PEASS Family를 발견하세요, 당사의 독점 NFTs 컬렉션
- 💬 디스코드 그룹 또는 텔레그램 그룹에 가입하거나 트위터** 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud github 저장소에 PR을 제출하여 해킹 트릭을 공유하세요.