# [HGAME2024] Unsotredbin 向前合并 + Off-By-Null
# 题目简述
来自 HGAME2024 - Week3
给了 add delete show 的功能,edit 在 add 的时候就进行了。
add 函数在 edit 的时候会在写入内容末尾的下一个字节写入 \x00,只可以引起 Off-By-Null。
堆块大小限制在 0xff 及以下。
delete 把 tabel 的地址清零了,因此没有 UAF,show 也无法 leak 被 free 的 chunk。
# 思路
# 1
Off-By-Null 可以缩小 chunk 的大小,也可以把 PREV_INUSE 设为 0,从而在构造好的条件下触发 chunk 的合并。
限制是 0xff 的大小,chunk 的 size 范围是 0x110 以及以内,由于小于 0x100 的 size 在 Off-By-Null 之后 size 会被设置为 0,因此我们可以把 0x110 的 chunk 缩小为 0x100
因此如果我们把一个 chunk 的 size 缩小,把被去掉的那部分伪装成 fake-chunk,那么我们就能在不触发原本 chunk 之后的 chunk 修改 prev_size 的条件下对这个 chunk 进行分割,再触发后面的 chunk 的向前合并,从而造成 Overlapping
利用 Overlapping,我们可以利用 UAF 的思想 leak libc,那么修改 hook 也就不难了
但是!
问题在于我们不易得到这样一个既能触发堆缩又能实现 Off-By-NULL 的 chunk。于是采用一种新方法。
# 2
大致思路和上面差不多。改变的是我们不利用堆缩再切割的方式得到 overlapping 的 chunk,我们直接 add 几个 chunk,直接把最后一个 chunk 的 prev_size 改成这几个 chunk 的 size 的总和,同时把 PREV_INUSE 改为 false,那么就能在不 free 中间的 chunk 的条件下得到 overlapping 的 chunk。
如果要触发一个 chunk 的向前合并,我们一方面要伪造 prev_size 和 PREN_INUSE,另一方面我们要把 addr-prev_size 地方的 chunk 的 fd,bk 伪造了,这样才能通过 Ulink 以及其他的检查。
在 EXP 中,我们把 7,8,9,10 号 chunk 合并了,其中 7,10 处于 free 状态,8,9 没有 free,于是我们通过 add 我们可以直接得到两个 chunk 之间的部分重叠,于是就能泄露 libc 基址并修改 Tcache chunk 的 fd 为 hook,从而修改 hook,GET SHELL...
# EXP
1 | #patchelf --set-interpreter /home/akyuu/glibc-all-in-one/libs/2.23-0ubuntu3_amd64/ld-2.23.so --replace-needed libc.so.6 /home/akyuu/glibc-all-in-one/libs/2.23-0ubuntu3_amd64/libc.so.6 pwn |