Skip to main content

HGAME Elden Ring Ⅲ wp

这道题是仅允许申请large chunk,large chunk有它专属的攻击方法,请自行去运行这个代码来理解large bin attack:how2heap/glibc_2.32/large_bin_attack.c at master · shellphish/how2heap (github.com)

我在这里再说下原理吧,防止我自己忘记

首先得知道操作largebin的地方只有malloc,并且只有malloc中 1.分类时插入largebin 2.分配largebin,并且fd_nextsize指向递减方向,bk_nextsize指向递增方向,fd指向递减(或相等)方向,bk指向递增(或相等)方向,最小的fd_指向最大的chunk,最大的bk_指向最小的chunk,形成类似ringbuf的循环结构

首先看相关源码(分类时插入largebin)

原理是首先free一个chunk进入largebin,通过UAF或者其他方式改变其bk_nextsize位为你想要任意写的目标地址,关键来了,之后再尝试free一个chunk到largebin,但是要保证这个第二个chunk大小要小于第一个chunk(必须是其中最小的chunk),为的是绕过上图那个7.7.2.3.3的else,从而绕过检查。

在free第二个chunk时,存在一个关键语句:victim->bk_nextsize->fd_nextsize = victim(victim的bk_nextsize在上一句被设置为我更改的目标地址)从而在目标地址-0x20处写入了victim的地址。

综上所述,large bin attack的结果是向任意地址写入一个chunk的地址

但是我到这里就卡住了,我不知道该向什么地址写入(我在此之前已经泄露了libc地址以及heap地址),按照当时我的知识储备,我只能想到写入 一,libc(1.hook 2.global_max_fast)二,heap的某个地址

如果是第二个的话我觉得会特别麻烦,因为可能要涉及overlapping,并且即便overlapping也没有用,失败

第一个我先尝试了hook,尝试写shellcode,但是堆不可执行加上头数据无法更改,失败

我之后尝试了将global_max_fast覆写,使之变成很大的值,用fastbin attack,后发现fastbin的检查太多了,失败

我之后google了很久,还知道了libc中对于io_file中的一些指针的写入,从而控制程序流程(参考house of pig和house of banana),但是我不太会,放弃

之后实在找不到其他的资料了,问了l0tus学姐,要关注mp_结构体,我之前通读了源码但是竟然我对这个印象不深,我之后查阅了资料(指问gpt和看源码),了解到这是一些malloc相关的参数,宏观上控制malloc的行为,比如说tcache的bin有多少个啊,申请大于多少用mmap啊之类的

之后思路就简单了,覆盖tcache_bins为很大的值,这个是用来指定tcache有多少个bin的,默认64个,这个和覆盖global_max_fast有异曲同工之妙,都是在只能申请largebin的情况下使用小chunk进行攻击,因为小chunk利用方式丰富,但是fastbin检查太多,反观tcache,为了加速,除了一个double free检测,其他几乎没有,这就导致可以在tcache entries数组越界的情况下使用tcache。

之后思路就很简单了,就是tcache poisoning申请包含hook的地址,然后system(“/bin/sh\x00”),这里有个小插曲,我一开始不知道libc2.32有safe linking的机制,这是一个对于tcache的保护机制,源码如下

两个宏做的事情都是一样的,因为这个操作是可逆的,两个宏分别用于tcache_put,tcache_get,和fastbin分配和释放时,分别是对next指针或者fd指针进行加密和解密操作,不管是加密和解密,他都是将需要加密的指针的地址右移12位并与指针值进行异或操作得到的揭秘或者加密的指针值。所以要绕过它必须泄露出指针所在的地址才能实现正确加密,实现篡改fd或者next指针为自己想要的值。

整体思路

  • 1,泄露libc和heap地址
  • 2,largebin attack写mp_上覆写tcache_bins
  • 3,绕过safe linking
  • 4,tcache poisoning

exp如下