Stack Overflow

htARTE (HackTricks AWS Red Team Expert)를 통해 제로부터 영웅이 될 때까지 AWS 해킹을 배우세요 htARTE (HackTricks AWS Red Team Expert)!

HackTricks를 지원하는 다른 방법:

스택 오버플로우란

스택 오버플로우는 프로그램이 할당된 스택에 저장할 수 있는 데이터보다 더 많은 데이터를 쓸 때 발생하는 취약점입니다. 이러한 초과 데이터는 인접한 메모리 공간을 덮어쓰게 하여 유효한 데이터의 손상, 제어 흐름의 중단 및 악의적 코드의 실행으로 이어질 수 있습니다. 이 문제는 종종 입력에 대한 경계 검사를 수행하지 않는 안전하지 않은 함수의 사용으로 인해 발생합니다.

이 덮어쓰기의 주요 문제는 저장된 명령 포인터 (EIP/RIP) 및 **저장된 베이스 포인터 (EBP/RBP)**가 스택에 저장되어 있다는 것입니다. 따라서 공격자는 이를 덮어쓰고 프로그램의 실행 흐름을 제어할 수 있습니다.

이 취약점은 일반적으로 함수가 할당된 양보다 더 많은 바이트를 스택에 복사하기 때문에 발생합니다. 따라서 스택의 다른 부분을 덮어쓸 수 있습니다.

이에 취약한 일부 일반 함수는 strcpy, strcat, sprintf, gets 등입니다. 또한 길이 인수를 사용하는 fgets, **readmemcpy**와 같은 함수는 지정된 길이가 할당된 길이보다 큰 경우 취약할 수 있습니다.

예를 들어, 다음 함수들이 취약할 수 있습니다:

void vulnerable() {
char buffer[128];
printf("Enter some text: ");
gets(buffer); // This is where the vulnerability lies
printf("You entered: %s\n", buffer);
}

스택 오버플로우 오프셋 찾기

스택 오버플로우를 찾는 가장 일반적인 방법은 매우 큰 A 입력을 제공하고 (python3 -c 'print("A"*1000)'와 같이) 주소 0x41414141에 액세스를 시도했다는 Segmentation Fault가 발생하는지 확인하는 것입니다.

또한, 스택 오버플로우 취약점을 발견한 후에는 리턴 주소를 덮어쓸 수 있는 오프셋을 찾아야 합니다. 이를 위해 일반적으로 De Bruijn sequence가 사용됩니다. 이는 크기가 _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가 비활성화된 경우가 일반적) 따라서 취약한 함수가 반환될 때 숨겨진 함수가 호출됩니다:

pageRet2win

스택 쉘코드

이 시나리오에서 공격자는 스택에 쉘코드를 배치하고 제어 가능한 EIP/RIP를 악용하여 쉘코드로 이동하고 임의의 코드를 실행할 수 있습니다:

pageStack Shellcode

ROP 및 Ret2... 기술

이 기술은 이전 기술의 주요 보호 기능인 **실행 불가능한 스택 (NX)**를 우회하는 기본 프레임워크이며, 바이너리 내의 기존 명령을 악용하여 임의의 명령을 실행하는 여러 기술 (ret2lib, ret2syscall 등)을 수행할 수 있습니다:

pageROP - Return Oriented Programing

힙 오버플로우

오버플로우가 항상 스택에 발생하는 것은 아니며, 예를 들어 에서도 발생할 수 있습니다:

pageHeap Overflow

보호 유형

취약점 악용을 방지하려는 여러 보호 기능이 있습니다. 이를 확인하려면 다음을 참조하십시오:

pageCommon Binary Exploitation Protections & Bypasses

Last updated