System Hacking/Dreamhack 풀이

Return Address Overwrite(Stack Buffer Overflow)

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

문제 정보

Exploit Tech: Return Address Overwrite에서 실습하는 문제입니다.

풀이

먼저 문제 파일을 VMWare의 Ubuntu 18.04에 다운받아 확인해 본 결과 소스 코드 안에 쉘을 실행하는 코드가 있다.

 

해당 rao.c 파일에서 취약점을 분석해본 결과 scanf 함수에서 입력 문자의 길이를 지정하고 있지 않기 때문에 버퍼오버플로우 취약점이 있다고 유추할 수 있다. 스택 버퍼 오버플로우 문제이기 때문에 main 함수의 반환 주소를 get_shell() 함수의 반환 주소로 오버플로우를 통해서 변경한 후 드림핵에서 제공한 접속 정보로 익스플로잇을 해볼 것이다.

 

 

rao 파일과 rao.c 파일을 받았고 rao파일은 실행하면 Input 화면이 나오고 return 0이 되어서 종료가 되는 프로그램인데 다음처럼 A를 64번 입력한 결과 세그멘테이션 오류가 나오고 core 파일이 생성된 것을 볼 수 있다.

 

core 파일을 분석해보기 위해서 pwndbg를 이용해 gdb -c core 명령어를 입력했다. core 파일을 분석해보기 위해서는 gdb 명령에서 -c 명령어를 지원한다.

 

pwndbg로 core 파일을 분석한 결과 A를 64번 입력했는데 8번만 입력된 것을 확인했다.

 

scanf 함수에서 스택 프레임의 크기가 0x30 만큼 할당하는 것을 알 수 있다. 즉, scanf 함수의 입력이 rbp-0x30 부터 입력을 받는 것을 알 수 있다. 또한 scanf() 함수의 메모리 주소가 0x40071e라는 것도 알아냈다. 여기서 주의해야 할 점은 반환 주소는 0x8 만큼 더한 값에 저장되기 때문에 0x38이다.

 

이제 get_shell()의 주소를 알아내야 하므로 print get_shell 명령으로 메모리 주소를 알아냈다.

 

0x4006aa의 get_shell() 주소를 리틀 엔디언 방식을 이용해 바이트 문자열로 변환해준다.

"\\xaa\\x06\\x40\\x00\\x00\\x00\\x00\\x00"

이제 pwntools를 이용해 익스플로잇을 작성해야 한다. 처음으로 pwntools을 import 해준 후 익스플로잇 할 서버를 설정해주었다. 그 후에 payload를 작성해야 하는데 0x38이 넘어야 반환 주소를 설정할 수 있기 때문에 38까지 쓰레기 값인 A와 B를 넣어주었고 그 뒤에 get_shell() 함수를 리틀 엔디언 방식으로 넣어주었다. 다음으로 서버에 payload를 전송하고 쉘을 실행하기 위해 interactive() 함수를 쓰면 된다.

from pwn import *

r = retmote("host3.dreamhack.games", 8866)

payload = b'A'*0x30 + b'B'*0x8 + b'\\xaa\\x06\\x40\\x00\\x00\\x00\\x00\\x00'

r.send(payload)

r.interactive()

다음과 같이 vi 편집기를 열어 rao.py를 만들어준 후 위에서 작성했던 코드를 붙여넣어 주었다.

 

rao.py를 python rao.py로 실행하면 다음과 같이 Input: 이 나왔는데 무시하고 엔터 쳐주면 쉘 실행이 완료된 모습을 볼 수 있다. ls 명령어로 파일이 나열되있는지 확인한 결과 flag를 확인하였고 cat 명령어를 이용해 flag 값을 획득했다.