house_of_muney[CISCN]
house_of_muney
首先介绍一下house of muney 这个利用原理:
在了解过_dl_runtime_resolve的前提下,当程序保护开了延迟绑定的时候,程序第一次调用相关函数的时候会执行下面的命令
1 | |
这里的n对应的是这个符号在rel.plt重定位表中的下标然后第二个MoudleID则一般是本程序的link_map结构体的地址,解析来就进入到了_dl_runtime_resolve函数
我们来看看这个函数做了什么
1 | |
可以看见又继续调用_dl_lookup_symbol_x这个函数 ,它会开始在link_map寻找符号,实际上调用了do_lookup_x
1 | |
这里是roderick师傅做了注释之后的代码,上面标注了我们需要伪造的值
- bitmask_word
- bucket
- hasharr
还有两个比较重要的值就是set_name 和set_value,前半部分是通过查找该函数符号和strtab之间的偏移得到的,不同的程序得到的不同,而set_vaule是通过相应的libc环境编译而来的的对于需求函数,这里也是通过调试获得,简而言之,如果控制了set_name 就可以正确解析到相应的函数名,控制了set_vaule就可以控制调用函数解析到需求函数的地址进而调用需求函数。
在2023年的CISCN有一道题目
muney
保护策略

ida逆向分析

是一个堆题,前提是需要实验http格式发送相应选项,让web手给说个形式

比如使用
1 | |
来定义edit函数,其余的以此类推
这题的漏洞主要在edit函数,只限制不能超过申请堆块大小,但是没有限制长度为负数,也是就可以修改到低地址处的内容,比如可以修改堆块size

此外这题的malloc函数给的范围在0xFFFFF以上及申请0x100000大小的堆块以上,那么意味着申请的堆块由mmp直接分配,那么会在libc上面mmp出一块内存

给的后门是exit(/bin/sh)

如果给exit解析成system即可拿到shell
这里就需要伪造libc里面的一系列上面提到的内容
这里给出调试脚本
1 | |
这里需要源码级的调试,在事先导入源码目录

push n …… 进入 _dl_runtime_resolve

继续步入进入_dl_fixup

在这里先空走一轮while循环,因为这里看的是第二次解析的地址

这里看一下bitmask_word 的内容


继续往后走,这里看一下bucket 的内容


然后看一下hasharr的内容


因为环境是20.04环境,我这里使用20.04虚拟机来找偏移

这里0x46a40是exit的set_vuale set_name需要找一下strtab和exit字符串的偏移


这里需要尝试,找到哪一个才是真正的偏移。然后需要找一下同环境下的system的set_vuale
写一个程序验证一下
1 | |
需要开启延迟绑定,然后关闭pie保护

找到发现是0x52290
那么现在该有的都有,只需要找一下偏移即可
这里要注意,实际的偏移和输入的偏移相差0x1000,因为在起始地址时候减少了0x1000

所以这里要输入0x152b78,以此类推
EXP
1 | |
这里面有几个点需要注意,第一个是bitmask_word的内容做了一点改变,用看见的内容不行,用这个也许0xaaa101010210130e也就是后4位需要注意。
还有一个就是set_name这个后面4位是需要调试出来的,第四位和第六位程序里面里面得到
result

参考