
Windows x86 PoC: 스택 기반 버퍼 오버플로우와 맞춤형 셸코드를 사용한 레거시 32비트 Windows 환경에서의 증명
이것은 32비트 Windows용 스택 기반 버퍼 오버플로우 익스플로잇에 대한 간단하고 독립적인 튜토리얼입니다. 외부 가이드가 필요하지 않습니다—필요한 모든 것이 여기에 있습니다.
vulnerable.c: 안전하지 않은 gets() 함수를 사용하는 간단한 프로그램.messageBox.asm: 오버플로우 후 실행될 작은 어셈블리 페이로드.exploit.c: 오버플로우가 어떻게 트리거될 수 있는지 보여주는 예제.이 프로젝트는 한 가지 핵심 개념을 가르칩니다: 안전하지 않은 입력 읽기는 공격자가 반환 주소를 덮어쓰고 실행 흐름을 리디렉션할 수 있게 합니다.
gets()에는 크기 제한이 없습니다vulnerable.c에서 프로그램은 이렇게 동작합니다:
char buffer[32];
gets(buffer);
프로그램은 buffer에 32바이트를 할당한 다음 gets()를 호출하여 입력을 읽습니다.
문제: gets()는 버퍼 크기를 확인하지 않습니다.
새 줄 문자를 만날 때까지 계속 문자를 읽습니다.
사용자가 40자 또는 50자를 입력하면 추가 문자가 32바이트 버퍼를 넘쳐흐릅니다.
C 함수가 실행될 때, 스택(메모리 영역)은 다음을 저장합니다:
buffer 등)EBP (호출 함수의 베이스 포인터)다음과 같이 그려볼 수 있습니다:
낮은 주소 (그림상 스택의 위쪽)
[ buffer (32바이트) ]
[ 저장된 EBP (4바이트) ]
[ 반환 주소 (4바이트) ]
높은 주소 (아래쪽)
gets()가 너무 많은 입력으로 buffer를 오버플로우하면, 추가 바이트가 저장된 EBP와 반환 주소를 덮어씁니다.
오버플로우를 신중하게 구성하여 반환 주소 필드에 특정 주소를 넣으면, 함수가 반환을 시도할 때 CPU가 해당 주소로 점프합니다.
buffer[32]를 할당합니다.gets(buffer)를 호출하여 사용자 입력 한 줄을 읽습니다.gets()는 크기 검사를 하지 않으므로 모든 50바이트를 버퍼에 씁니다.buffer를 넘쳐 저장된 EBP와 반환 주소를 덮어씁니다.이것이 버퍼 오버플로우를 통한 코드 실행의 가장 단순한 형태입니다.
messageBox.asm은 오버플로우 후 실행되도록 설계된 작은 코드 조각입니다.
다음과 같은 작업을 수행합니다:
LoadLibraryA를 문자열 "USER32.DLL"과 함께 호출하여 라이브러리가 메모리에 있는지 확인합니다.ExitProcess를 호출하여 프로그램을 안전하게 종료합니다.핵심 포인트: 이것은 오버플로우가 실행을 리디렉션한 후 실행되는 실행 가능한 코드입니다. 화면에 메시지 상자가 나타나면, 세 가지를 증명합니다:
실제 공격에서는 이 페이로드가 데이터 탈취, 사용자 생성, 멀웨어 다운로드 등 무엇이든 할 수 있습니다. 메시지 상자는 임의 코드 실행이 발생했음을 보여주는 가시적이고 안전한 방법일 뿐입니다.
이 특정 페이로드는 MessageBoxA (0x751D8830) 및 ExitProcess (0x7437ADB0)에 대해 하드코딩된 메모리 주소를 사용합니다.
이 주소는 한 시스템에만 해당됩니다. 다른 Windows 버전이나 시스템에 맞게 페이로드를 조정해야 합니다.

최신 Windows에는 이 익스플로잇을 방지하는 여러 보안 기능이 있습니다:
이 학습 연습을 위해 모두 비활성화합니다.
MSVC (Microsoft Visual C++)를 특정 플래그와 함께 사용:
cl /c /GS- /W3 /Zl vulnerable.c
link /SUBSYSTEM:CONSOLE /DYNAMICBASE:NO /NXCOMPAT:NO vulnerable.obj /OUT:vulnerable.exe
플래그 의미:
/GS-는 스택 버퍼 오버런 보호를 비활성화합니다./DYNAMICBASE:NO는 주소 공간 레이아웃 무작위화(ASLR)를 비활성화합니다./NXCOMPAT:NO는 DEP를 비활성화하여 스택에서 코드 실행을 허용합니다.실행 파일이 이미 있다면 editbin으로 보호 기능을 비활성화할 수 있습니다:
editbin /NXCOMPAT:NO /DYNAMICBASE:NO vulnerable.exe
vulnerable.exe를 시작합니다.이 README는 다음을 설명합니다:
gets()가 무엇이며 왜 안전하지 않은지 (크기 제한 없음).이제 버퍼 오버플로우 익스플로잇의 전체 흐름을 이해했습니다. 코드 파일을 읽고 이 설명과 비교하여 이해를 확고히 하세요.
이 예제는 학습 목적으로만 제공됩니다. 소유하지 않았거나 명시적 테스트 허가를 받지 않은 시스템에 이 기술을 사용하지 마십시오. 컴퓨터 시스템에 대한 무단 접근은 불법입니다.