.. | ||
ret2win | ||
stack-shellcode | ||
pointer-redirecting.md | ||
README.md | ||
ret2win.md | ||
stack-pivoting-ebp2ret-ebp-chaining.md | ||
stack-shellcode.md | ||
uninitialized-variables.md |
스택 오버플로우
{% 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을 제출하여 해킹 트릭을 공유하세요.
스택 오버플로우란 무엇인가
스택 오버플로우는 프로그램이 할당된 것보다 더 많은 데이터를 스택에 쓸 때 발생하는 취약점입니다. 이 초과 데이터는 인접한 메모리 공간을 덮어쓰게 되어 유효한 데이터의 손상, 제어 흐름의 중단, 그리고 잠재적으로 악성 코드의 실행을 초래할 수 있습니다. 이 문제는 종종 입력에 대한 경계 검사를 수행하지 않는 안전하지 않은 함수의 사용으로 인해 발생합니다.
이 덮어쓰기의 주요 문제는 **저장된 명령 포인터 (EIP/RIP)**와 **저장된 기본 포인터 (EBP/RBP)**가 이전 함수로 돌아가기 위해 스택에 저장된다는 것입니다. 따라서 공격자는 이를 덮어쓰고 프로그램의 실행 흐름을 제어할 수 있습니다.
취약점은 일반적으로 함수가 스택에 할당된 양보다 더 많은 바이트를 복사할 때 발생하여 스택의 다른 부분을 덮어쓸 수 있게 됩니다.
이러한 취약점이 있는 일반적인 함수는: strcpy
, strcat
, sprintf
, gets
... 또한 fgets
, **read
& memcpy
**와 같이 길이 인수를 사용하는 함수는 지정된 길이가 할당된 것보다 클 경우 취약하게 사용될 수 있습니다.
예를 들어, 다음 함수들이 취약할 수 있습니다:
void vulnerable() {
char buffer[128];
printf("Enter some text: ");
gets(buffer); // This is where the vulnerability lies
printf("You entered: %s\n", buffer);
}
스택 오버플로우 오프셋 찾기
스택 오버플로우를 찾는 가장 일반적인 방법은 매우 큰 입력의 A
s를 주는 것입니다 (예: python3 -c 'print("A"*1000)'
) 그리고 **주소 0x41414141
에 접근하려고 시도했다는 것을 나타내는 Segmentation Fault
**를 기대하는 것입니다.
게다가, 스택 오버플로우 취약점이 발견되면 리턴 주소를 덮어쓸 수 있는 오프셋을 찾아야 합니다. 이를 위해 일반적으로 De Bruijn 시퀀스가 사용됩니다. 주어진 크기 _k_의 알파벳과 길이 _n_의 부분 시퀀스에 대해, 모든 가능한 길이 _n_의 부분 시퀀스가 정확히 한 번 연속된 부분 시퀀스로 나타나는 순환 시퀀스입니다.
이렇게 하면 EIP를 제어하는 데 필요한 오프셋을 수동으로 파악할 필요 없이, 이러한 시퀀스 중 하나를 패딩으로 사용하고 덮어쓴 바이트의 오프셋을 찾을 수 있습니다.
이를 위해 pwntools를 사용할 수 있습니다:
from pwn import *
# Generate a De Bruijn sequence of length 1000 with an alphabet size of 256 (byte values)
pattern = cyclic(1000)
# This is an example value that you'd have found in the EIP/IP register upon crash
eip_value = p32(0x6161616c)
offset = cyclic_find(eip_value) # Finds the offset of the sequence in the De Bruijn pattern
print(f"The offset is: {offset}")
또는 GEF:
#Patterns
pattern create 200 #Generate length 200 pattern
pattern search "avaaawaa" #Search for the offset of that substring
pattern search $rsp #Search the offset given the content of $rsp
스택 오버플로우 악용하기
오버플로우가 발생하는 동안(오버플로우 크기가 충분히 큰 경우) 스택 내의 지역 변수 값을 덮어쓸 수 있습니다. **EBP/RBP와 EIP/RIP(또는 그 이상)**에 도달할 때까지 가능합니다.
이러한 유형의 취약점을 악용하는 가장 일반적인 방법은 반환 주소를 수정하는 것입니다. 이렇게 하면 함수가 끝날 때 제어 흐름이 사용자가 지정한 위치로 리디렉션됩니다.
그러나 다른 시나리오에서는 스택 내의 일부 변수 값을 덮어쓰는 것만으로도 악용이 충분할 수 있습니다(예: 쉬운 CTF 챌린지에서).
Ret2win
이러한 유형의 CTF 챌린지에서는 결코 호출되지 않는 함수가 바이너리 내에 존재하며, 이를 호출해야 승리할 수 있습니다. 이러한 챌린지에서는 반환 주소를 덮어쓸 오프셋을 찾고 호출할 함수의 주소를 찾기만 하면 됩니다(보통 ASLR이 비활성화되어 있음) 그래서 취약한 함수가 반환될 때 숨겨진 함수가 호출됩니다:
{% content-ref url="ret2win/" %} ret2win {% endcontent-ref %}
스택 셸코드
이 시나리오에서 공격자는 스택에 셸코드를 배치하고 제어된 EIP/RIP를 악용하여 셸코드로 점프하고 임의의 코드를 실행할 수 있습니다:
{% content-ref url="stack-shellcode/" %} stack-shellcode {% endcontent-ref %}
ROP 및 Ret2... 기술
이 기술은 이전 기술의 주요 보호 장치를 우회하기 위한 기본 프레임워크입니다: 실행 불가능한 스택(NX). 그리고 이는 기존의 바이너리 명령어를 악용하여 임의의 명령을 실행하는 여러 다른 기술(ret2lib, ret2syscall...)을 수행할 수 있게 해줍니다:
{% content-ref url="../rop-return-oriented-programing/" %} rop-return-oriented-programing {% endcontent-ref %}
힙 오버플로우
오버플로우는 항상 스택에서 발생하는 것은 아니며, 예를 들어 힙에서도 발생할 수 있습니다:
{% content-ref url="../libc-heap/heap-overflow.md" %} heap-overflow.md {% endcontent-ref %}
보호 유형
취약점 악용을 방지하기 위한 여러 가지 보호 장치가 있습니다. 자세한 내용은 다음을 확인하세요:
{% content-ref url="../common-binary-protections-and-bypasses/" %} common-binary-protections-and-bypasses {% endcontent-ref %}
{% hint style="success" %}
AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE)
HackTricks 지원하기
- 구독 계획 확인하기!
- **💬 Discord 그룹 또는 텔레그램 그룹에 참여하거나, Twitter 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 팁을 공유하세요.