湖湘旅游日记之house of muney
写在前面
之前打线下都没有笔记,这次比赛第一次打awd plus
,给我的感觉就是线下ctf,hhhh(得亏没爆0)。
日程有点赶,长沙没怎么玩,每次出去比赛后脚都有一个比赛,刚到了长沙就点了一杯茶颜悦色,味道还是挺不错的。还面基了好多师傅,没吃到长沙的臭豆腐有点小可惜哈哈哈,不过还是挺赚的。

言归正传,还是来看看这次要学的东西。
原理分析
先附上大佬的博客:https://www.anquanke.com/post/id/254797
大佬的博客已经讲的很清楚了,我这里就简单的总结一下。首先程序要有Partial RELRO
的,和延迟绑定的道理一样。我们最终是利用sym->st_value
改为我们要执行的目的代码地址比如one_gadgets
。
1 | typedef struct |
但是原本这一块地址是不能写的,但是当我们申请极大块的chunk时,都会放在特殊的mapped区域。比较特殊的是当我们释放这类chunk时会直接回收至内核。通过这个特性,我们可以释放一些不可写的区域,然后申请再拿回对应区域,并且使得其有可写的权限,这样我们就可以对Elf64_Sym
进行修改。
然后有几个检测的地方,要满足的条件如下:
1 | bitmask[offset] --> 0xf000028c0200130e |
不同环境可能会有一些不一样,我的环境是Ubuntu 18.04(Ubuntu GLIBC 2.27-3ubuntu1.4)
,这些值可以通过调试获得。
题目分析
菜单题目,有编辑、申请、删除功能,还有一个功能就是修改堆块size。申请的堆块大小最小是0x100000
也就是mapped范围,而且只能申请两个chunk。
思路
申请两个mapped范围的,然后修改size,使其覆盖.gnu.hash
和.dynsym
,而且范围确保不会影响到.dynstr
。然后将其释放再申请出来(要申请比原来要大的chunk),这是因为M_MMAP_THRESHOLD
会随着munmap/free
操作发生增长,若分配的大小小于M_MMAP_THRESHOLD
,堆操作将回到常规堆空间进行(大佬博客里摘的)。然后通过编辑堆块修改对应的值。通过exit(将被解析成one_gadgets)来拿shell。
1 | bitmask[offset] --> 0xf000028c0200130e |
exp
1 | #coding=utf-8 |