정수 오버플로우
Reading time: 4 minutes
tip
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
)로 표현됩니다.
최대 값
잠재적인 웹 취약점에 대해 최대 지원 값을 아는 것은 매우 흥미롭습니다:
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); }
예시
순수 오버플로우
출력된 결과는 0이 될 것입니다. 왜냐하면 우리는 char를 오버플로우했기 때문입니다:
#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;
}
Signed to Unsigned Conversion
사용자 입력에서 읽은 signed integer가 적절한 검증 없이 unsigned integer로 처리되는 상황을 고려해 보십시오:
#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에서는 변경되지 않습니다. 이 블로그 게시물에서 볼 수 있습니다.
tip
AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE)
HackTricks 지원하기
- 구독 계획 확인하기!
- **💬 디스코드 그룹 또는 텔레그램 그룹에 참여하거나 트위터 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.