首页
社区
课程
招聘
[原创]trx ctf 2026 house of fishing
发表于: 2026-5-6 00:47 12176

[原创]trx ctf 2026 house of fishing

2026-5-6 00:47
12176


TRX CTF 2026 house-of-fishing Writeup · rawpayload

看了一下 trxctf 2026 的堆题,这题看上去很简单,只需要一个任意地址写将 *admin 修改成目标的地址即可触发后门函数,从而getshell,但是程序没有 show() 功能,因此无法通过修改fd之类的方式污染 bins,故而我们需要别的方法劫持堆,在刚开始做的时候没想出来怎么打,后面看了一眼官方的wp,自己整理了一下

题目给了一个elf文件,一个程序源码和docker file,查看docker file可以得知采用的是 glibc 2.39-0ubuntu8.5 版本的glibc

查询程序保护如下:

可以看到是一个很典型的 heap 的保护,保护几乎开满了


可以看到非常经典的heap题,存在 增删写 的功能,但是就是没有读,这就导致了实现任意地址写的方法变得麻烦起来了,一些常规的任意地址写的手法就无法生效了。

可以看到能够申请 size 值满足 16字节对齐 且 小于 0x500 的chunk

当 *admin == 0xdeadbeefdeadcafe 时即可触发 system("/bin/sh") 从而直接拿到shell,因此这题虽然是高版本的堆题目,但是却不需要打IO,只需要实现任意地址写即可getshell

首先没有 show() 我们无法直接修改fd指针,那么我们有什么方法可以在不泄露堆地址的情况下将fake chunk放入tcache呢?这时候 tcache_stashing_unlink 就派上了用场,改攻击手法能将smallbin chunk放入tcache中,同时因为 smallbin chunk的 bk 指针没有 safe linking 保护,因此我们可以直接将其修改成 目标地址 - 0x10 然后打 tcach_stashing_unlink 即可将目标地址放入 tcache 中。
由于 malloc 源码中存在如下的代码:

他会检测你取出的chunk的bk是否为有效指针,因此如果直接打 tcache_stashing_unlink 则会因此而无法走到 tcache_put(tc_victim, tc_idx); 这一步,因此我们需要提前利用 largebin attack 将一个有效的堆地址写入 fake chunk->bk 处,从而实现对应的攻击

因为要打 tcache_stashing_unlink 我们需要在一开始就直接构建好 smallbin chunk,防止后面再构造时出现问题,同时提前构造 smallbin 也可以不让堆结构变得特别乱

此时bin的结构如图

可以看到成功将6个0xa0的 chunk 放入 smallbin 中。

此时我们需要调用largebin attack,在 *(admin + 8) 处的地址写入一个堆地址,从而防止后续 tcache_stashing_unlink 时出现错误

最终能够发现成功将一个堆地址写入了 admin + 0x08 处的地址


传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!!

最后于 2026-5-6 01:01 被B1t3编辑 ,原因:
上传的附件:
收藏
点赞 ・5
打赏
分享
最新回复 (7)
雪    币: 200
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2 楼
吓哭了
2026-5-6 14:04
0
雪    币: 648
活跃值: (464)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3 楼
mb_bcynexxj 吓哭了
学姐ddw
2026-5-6 17:50
0
雪    币: 2687
活跃值: (811)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
4 楼

我也做了一下,这个tcache_stashing_unlink确实优雅,但我在思考,这道题其实真正利用的难点是没有show,如果把这个backdoor给删除,还能实现劫持控制流的目的吗?我目前只能想到tcache_stashing_unlink的过程中是可以通过修改smallbin的bk低字节修改为_IO_2_1_stdout_附近的地址(我的想法是利用是stderr中的指针当fake_chunk->bk,这样就不需要通过largebin_attack了(因为bk_nextsize地址是指向自己而不是libc中的地址,没法修改低字节打到stdout),但是需要修改edit的逻辑,不再是读满size大小的字节,而是可以读部分字节),然后通过修改_IO_2_1_stdout_实现泄露libc地址(menu打印用的是puts),如果能做到这步,那么相当于我们有libc内任意地址读了,那就可以泄露environ来打return_address劫持控制流,不过这些都只是理论...太懒了不想动手试)不知道师傅有没有什么其他见解,或者我这个思路有什么明显不可行的部分吗)

最后于 2026-5-8 07:30 被F0xm1ao编辑 ,原因:
2026-5-8 07:16
0
雪    币: 2687
活跃值: (811)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
5 楼
2026-5-8 13:35
0
雪    币: 648
活跃值: (464)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6 楼
F0xm1ao F0xm1ao 我也做了一下,这个tcache_stashing_unlink确实优雅,但我在思考,这道题其实真正利用的难点是没有show,如果把这个back ...
师傅,我感觉你的这个思路确实非常棒,让我有了挺大的启发。
2026-5-8 21:59
0
雪    币: 2703
活跃值: (3884)
能力值: ( LV12,RANK:286 )
在线值:
发帖
回帖
粉丝
7 楼
巨佬
2026-5-10 00:28
0
雪    币: 2703
活跃值: (3884)
能力值: ( LV12,RANK:286 )
在线值:
发帖
回帖
粉丝
8 楼
pwn学得真好
2026-5-10 00:29
0
游客
登录 | 注册 方可回帖
返回