Lord of BOF_0_Gate

C언어 소스코드와 실행파일을 준다.

소스코드의 내용은 다음과 같다.

이 코드의 핵심 알고리즘은 다음과 같다.
- main함수 인자를 받는다.
argv[1]내용을 buffer에 strcpy한다.
이 코드에서는 취약한 함수인 strcpy를 사용한다. BOF를 일으켜 return address를 조작해 주면 되겠다.
정확한 스택의 모습을 알기 위해 gdb를 이용한다.

이 때, 다른 소유자의 프로그램은 gdb를 이용할 수 없으므로 /tmp 폴더에 복사해야 한다.


main 함수의 코드이다. canary 체크 루틴이 없는 것을 보아 SG는 적용되지 않았다.
스택 구조는 다음과 같다.
- push ebp로 ebp 백업
- sub esp, 0x100 코드로 스택을 0x100만큼 확보
- strcpy 함수 인자로 ebp-256 을 넣음 ( = ebp-0x100)
EBP - 0x100 strcpy 인자
...
EBP + 0x0 EBP backup
EBP + 0x4 return address따라서, 셸 코드를 입력하고, return address에 셸 코드의 주소를 넣으면 되겠다.
gdb에서 스택의 주소를 확인할 수도 있지만, 환경변수 등의 변수때문에 주소가 확실하지 않다. 따라서 core를 이용하도록 한다.

return address에 유효하지 않은 값을 넣어주면 core dump하게 된다. 버퍼 100개엔 “A”를, EBP backup자리에는 “B”를, return address 자리에는 “C”를 넣었다.

ret 전 스택 프레임을 정리하는 루틴을 실행했기 때문에, 예전 스택 프레임을 보기 위해 esp-0x108부터 0x108바이트를 뽑았다.
100바이트의 버퍼와 EBP 백업, return address를 포함하여 보게 된다. (4바이트 단위로 66개 뽑았음, 66*4 = 264 = 0x108)
버퍼의 시작 주소가 0xbffff928임을 알 수 있다.
셸 코드를 만들기 위해 코드를 썼다.


기계어를 떼어내어 셸 코드를 만든다.

얻은 스택 주소를 이용하여 파이썬 익스플로잇 코드를 썼다.

프로그램을 실행할 때 경로때문에 스택의 주소가 변경되는 것을 방지하기 위해 tmp 폴더에 링크 파일을 생성했다.

그대로 파이썬 인자를 넘겨 프로그램을 실행하면 gremlin의 권한을 가진 셸을 얻게 된다.

my-pass를 이용하여 gremlin의 비밀번호를 알 수 있다. gremlin의 비밀번호는 hello bof world 이다.
다음 문제를 풀 때는 gremlin으로 로그인하면 되겠다.
tags: writeup, pwnable, buffer overflow, stack overflow, memory corruption, elf file, linux, c lang, x86asm