System Hacking/Dreamhack 풀이

basic_exploitation_001(Stack Buffer Overflow)

박연준 2023. 7. 2. 00:25

문제 정보

이 문제는 서버에서 작동하고 있는 서비스(basic_exploitation_001)의 바이너리와 소스 코드가 주어집니다.

프로그램의 취약점을 찾고 익스플로잇해 “flag” 파일을 읽으세요.

“flag” 파일의 내용을 워게임 사이트에 인증하면 점수를 획득할 수 있습니다.

플래그의 형식은 DH{…} 입니다.

Environment

Ubuntu 16.04
Arch:     i386-32-little
RELRO:    No RELRO
Stack:    No canary found
NX:       NX enabled
PIE:      No PIE (0x8048000)

풀이

먼저 Environment 부분을 확인해보면 리눅스 32비트 아키텍처에 리틀 엔디언 방식인 것을 확인할 수 있고 따로 보호기법도 적용되지 않은 것을 알 수 있다.

 

문제 파일을 다운 받아서 소스 코드를 확인해본 결과 000 문제와 비슷하지만 read_flag()라는 함수가 새로 만들어져 있다. 익스플로잇 과정은 gets()함수 반환 주소에 read_flag() 함수의 주소가 되면 성공할 것 같다.

 

파일을 실행 시킨 후 d를 쭉 입력해보면 세그멘테이션 오류가 나오고 core 파일이 생기는 것을 확인할 수 있다.

 

gdb로 core 파일을 분석한 결과 context 부분의 stack 부분이 d가 반쯤 짤려서 나온 걸 확인할 수 있다.

 

gdb로 실행 파일을 분석해보면 0x80만큼 스택 프레임을 생성하는 것을 알 수 있다. 또한 32아키텍처 이기 때문에 4바이트만큼 더 밑에 반환 주소가 있는 것을 유추할 수 있다. 따라서 84를 10진수로 변경해보면 132가 나오고 132 값 뒤에 반환 주소를 read_flag() 주소로 넣어주면 될 것이다.

 

print read_flag 명령으로 메모리 주소가 0x80485b9 라는 것을 확인했다.

 

read_flag()의 메모리 주소를 쉘코드에 쓰기 위해 리틀 엔디언 방식을 이용해 바이트 코드로 변환해보면 다음과 같이 나온다.

\\xb9\\x85\\x04\\x08

이제 pwntools를 이용해 익스플로잇 코드를 작성해보자.

 

먼저 pwntools를 import 해주고 dreamhack 접속 정보로 설정해준다음 NOP라는 바이트 코드를 이용해 쓰레기 값으로 132바이트만큼 payload에 저장한 후 read_flag() 주소를 넣어주었다. 그리고 send() 함수를 이용해 payload를 전송했고 p가 출력하는 모든 데이터를 data에 저장해서 print를 해봤는데 안된다..

다시 한 번 더 생각해봐서 recv 부분이랑 print 부분을 지우고 interactive()로 변경해보았다.

flag 값이 잘 나오는 것을 확인할 수 있었다.