Noleak(xctf)

本文详细介绍了如何利用程序中的Use-After-Free(UAF)和堆溢出漏洞,通过Unsorted Bin Attack和Fast Bin Attack来修改内存中的malloc_hook,进而执行shellcode实现getshell。在过程中,讨论了如何绕过got表不可写和无输出函数的限制,以及如何通过特定的内存布局和地址计算来精确控制执行流程。
摘要由CSDN通过智能技术生成

0x0 程序保护和流程

保护:

protect

流程:

main()

main

create()

create

delete()

delete

free之后没有将指针置空,存在UAF。

edit()

update

没有对输入数据的大小作出限制,存在堆溢出。

0x1 利用过程

1.题目中的got表不可写,又没有输出函数,无法泄露地址,但是堆栈上可以执行代码,所以需要一个可执行的指针变量指向shellcode的地址,才能够执行shellcode。

2.可以使用Unsorted bin attack改写buf中指向chunk的地址为main_arena的地址,之后通过update将buf中的存储的数据改成malloc_hook的地址,之后向malloc_hook中写入shellcode的起始地址,之后再次执行malloc函数就可以完成getshell了。

3.因为要将修改malloc_hook中的数据,所以需要malloc_hook的地址。而malloc_hook的地址可以在libc中找到。

malloc_hook

这时再看向malloc_trim函数

反汇编

malloc_trim_ida

源码

malloc_trim_source

可以知道在main_arena-0x10就是malloc_hook的地址,而Unsorted bin在free之后的fd和bk都会指向main_arena附近的地址。并且当Unsorted bin取出的时候,会将bck->fd的位置写入Unsorted bin的链表头部的地址。

/* remove from unsorted list */
if (__glibc_unlikely (bck->fd != victim))
malloc_printerr ("malloc(): corrupted unsorted chunks 3");
unsorted_chunks (av)->bk = bck;
bck->fd = unsorted_chunks (av);

只要能够在Unsorted bin释放之后修改其bk字段,就能在下一次申请大小合适的堆块时,将*bk+0x10处的值改为Unsorted bin的链表头部的地址。又因为程序加载进内存是按页加载,页表大小为4096=212=24*24*24 (getconf PAGE_SIZE可以查看页表大小),所以低三位是不会改变的,因此只需要向*bk+0x10的位置写入’\x10’,就可以使得*bk+0x10指向malloc_hook了。

3.通过以上分析,最后只需要一个可以控制的指针即可完成整个过程,所以可以通过Unlink或者Fast bin Attack将buf中的值修改为&buf再配合程序给出的update函数就可以getshell了。

Fast bin Attack:

先介绍Fastbin中最关键的检测机制,_int_malloc 会对欲分配位置的 size 域进行验证,如果其 size 与当前 fast bin 链表应有 size 不符就会抛出异常。

if (__builtin_expect (fastbin_index (chunksize (victim)) != idx, 0))
    {
   
      errstr = "malloc(): memory corruption (fast)";
    errout:
      malloc_printerr (check_action, errstr, chunk2mem (victim));
      return NULL;
}

所以对于Fast bin的利用必须要注意size位的判断。所以在这种利用方式下需要找到一个固定的值,并且这个值的大小在需要在Fast bin中并且与索引对应的大小要一致。

要想将fast bin分配到bss段,需要一个比较固定的值,而一般libc的高位是0x7f其大小符合Fast bin,所以先利用Unsorted bin Attack给出一个高地址。

# Unsorted bin
create(0x100,'index0')
# Fastbin bin,size=0x70即可
create(0x60,'index1')
# 防止被top chunk合并
create(0x10,'index2')
delete(0)
payload=p64(0)+p64(0x601058)
update(0,payload)
create(0x100,'index3')

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值