System Hacking

[Windows] Stack Buffer Overflow

zz! 2025. 5. 26. 12:19
728x90

1) Stack Buffer Overflow

메모리 경계를 검사하지 않는 함수 사용으로 인해 스택을 덮어쓰게 되어 주로 발생한다. 아주 고전적인 취약점이지만 아직도 많이 발생하고 있으며 실제로 퍼징을 하다 보면 여전히 많이 발견된느 취약점이다.

함수는 각각의 스택 프레임을 가지고, 함수 호출 시 저장된 SFP(Saved Frame Pointer), RET(Return address)를 이용하여 호출 이전의 코드로 돌아간다.

 

실습 소스코드

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char* argv[])
{
	char readbuf[2000] = { 0, };
	char printbuf[500] = { 0, };
	printf(" # text reader #\n");
	if (argc != 2) {
		printf(" Usage : reader.exe filename\n", argv[0]);
		exit(1);
	}
	FILE* f = fopen(argv[1], "r");
	fgets(readbuf, 2000, f);
	strcpy(printbuf, readbuf);
	printf("File Contents : %s\n", printbuf);
}

위에 프로그램은 인자 값으로 준 파일을 열어서 화면에 출력하는 단순한 프로그램 소스코드입니다.

fgets 함수를 이용해서 지정된 파일에서 2000바이트를 읽어와서 readbuf에 저장한다. readbuf에 복사된 2000개의 바이트를 strcpy 함수를 사용해서 printbuf에 복사한다. 그런데 strcpy는 null byte를 만날 때까지 바이트를 계속 복사하는데, readbuf는 2000바이트 printbuf는 500바이트의 크기를 가지고 있으므로 500바이트 이상 복사하면 버퍼 오버플로우가 발생한다.

 

컴파일 시 버퍼 보안 검사 기능과 DEP 기능과 ASLR 기능을 제외를 시킵니다.

버퍼 보안 검사 옵션

ASLR & DEP 옵션

링커 -> 고급 -> 임의 기준 주소 "아니요" & DEP (데이터 실행 방지) "아니요" 로 체크하면 됩니다.

windbg

테스트를 위해서 아래와 같이 텍스트 파일을 작성을 해봅시다.

이뮤니티 디버거로 실습을 진행을 해보겠습니다.

그리고 디버거에 인자 값으로 방금 작성한 파일명을 적습니다. [Debug] 메뉴의 [Arguments]를 선택하고 적어주면 됩니다.

0x40108B 지점의 fgets 함수에 bp를 설정하고 F9를 눌러서 진행을 할 수 있습니다. F8을 눌러 한번 더 실행하면 버퍼에 파일의 내용이 들어간 것을 알 수 있습니다.

문제는 이 다음 코드인 strcpy에서 발생합니다.

strcpy 함수는 원본 문자열이 끝나는 지점을 알기 위해 한 글자를 복사할 때마다 "Test CL, CL" 명령어를 통해서 복사할 문자가 널 바이트인지 확인을 합니다.

-> 버퍼의 크기와 상관없이 널바이트가 나올 때가지 목표 주소에 문자를 계속 복사합니다.

print ("[+] Create text file...")
TEXT = "A" * 550
f = open("test.txt", "w")
f.write(TEXT)
f.close()
print ("[+] Done !!")

EIP 41414141

EIP 값도 변경이 되엇다는 것을 알 수 있다. EIP를 원하는 주소로 변경할 수 있는 취약점을 찾은 것이다.

 

728x90