먼저 파일을 윈도우와 우분투에 받자. 그리고 IDA로 디스어셈해보자.

 

IDA

문제의 이름이 BOF인 만큼 fgets() 함수에서 입력받는 과정에서 버퍼 사이즈를 잘 못 지정해서 취약점이 발생한 것 같다.

 

fgets() 함수에 대해 알아보자.

 

fgets(char * str, int num, FILE * stream) 
 - 첫 번째 인자는 읽어들인 문자열을 저장할 char 배열을 가리키는 포인터이다.
 - 두 번재 인자는 마지막 NULL문자를 포함하여 읽어들일 최대 문자 수이다.
 - 세 번재 인자는 문자열을 읽어들일 스트림의 FILE 객체를 가리키는 포인터이다.
 - 리턴값은 성공했을 경우 char 배열을 리턴하고 아무런 문자가 없거나 오류가 발생했을 때는 NULL이 리턴된다.

 

 

shell()

shell() 함수가 존재한다. gdb로 좀 더 살펴보자.

 

빨간 네모박스를 잘 보자.

 

ebp-0xc 위치에 0x80484b4 가 들어간다. 그 다음 eax에 ebp-0xc 위치의 값이 들어간 뒤 call 된다.

 

그렇다면 ebp-0xc 위치에 shell 함수의 주소를 입력하면 call 에서 shell 함수가 호출될 것이다. 

 

해보자.

 

 

먼저, fgets로 입력된 값이 어느 위치에 들어가는지 알아보자.

 

fgets가 호출된 다음 부분에 bp를 걸고 실행해보자.

 

0xffffd0cc에 입력을 받는 것을 알았다.

 

두 번째로 ebp-0xc의 주소를 알아내보자.

 

$ebp address

$ebp의 주소에서 0xc를 빼주면 ebp-0xc의 주소인 0xffffd14c이 나온다.

 

세 번째로 0xffffd14c 주소에 넣을 shell 함수의 주소를 알아내 보자.

 

shell address

마지막으로 입력되는 주소에서 ebp-0xc의 거리를 계산해보자.

 

위의 네모박스는 입력받는 곳이고, 밑은 ebp-0xc의 자리이다.

 

0xffffd14c - 0xffffd0cc = 0x80

 

거리가 나왔다.

 

이젠 필요한 재료(?)들이 다 모였다. 익스를 짜보자.

 

exploit.py

입력받는 곳으로부터 A로 128byte를 채우면 ebp-0xc의 자리에 위치한다. 이 곳에 shell 함수의 주소를 넣는다.

 

128byte + 4byte = 132byte 이다. 위의 fgets 함수의 버퍼 사이즈를 넘지 않는다.

 

133byte

실행해보자.

 

flag

터졌다.

 

플래그는 HackCTF{h3y_dud3_600d_f0r_y0u} 이다.

+ Recent posts