0x00 为什么需要万能gadget
众所周知,在 64 位程序中,函数的前 6 个参数是通过寄存器传递的,分别是rdi、rsi、rdx、rcx、r8、r9。而当我们构建ROP时,往往我们很难找到每一个寄存器对应的 gadgets。 比如,用于控制第三个参数的rdx寄存器一般情况下就是不可控的。当然,这篇文章就是为了解决这一问题而写的,将介绍如何用利用 x64 下的 __libc_csu_init 中的两个特殊 gadgets实现万能传参。
0x01 ret2csu
ret2csu是blackhat大会在2018年的一个议题,即通过__libc_csu_init 中的两个特殊 gadgets可实现万能传参。__libc_csu_init 函数是用来对 libc 进行初始化操作的,而一般的程序都会调用 libc 函数,所以可以认为这个函数一定会存在。我们IDA一下便可以看到这两个gadget
#万能gadget1:
pop rbx; pop rbp; pop r12; pop r13; pop r14; pop r15; retn
#万能gadget2:
mov rdx, r13; mov rsi, r14; mov edi, r15d; call qword ptr [r12+rbx*8]; add rbx, 1; cmp rbx, rbp; jnz short loc_400620
只要稍微稍微看得懂几条汇编指令,也能够分析出,处理后栈结构中布置的数据将要依次存入以下寄存器中: rbx, rbq, r12, rdx, rsi, edi
在这些寄存器中,我们主要关注的是r12,rdx,rsi,edi寄存器,他们分别保存着将要调用函数的指针的地址、第三个参数、第二个参数和第一个参数。而rbx和rbp必须的需要将它们的值置为0和1。因为,在gadget2中,我们call了 [r12+rbx8] ,将rbx置为0即 [r12+rbx8] == [r12],方便我们传参。而设置rbp为1是因为 add rbx, 1; cmp rbx, rbp; jnz xxxxxx 。由于我们通常使rbx=0,从而使r12+rbx*8 = r12,所以call指令结束后rbx必然会变成1。若此时rbp != 1,jnz会再次进行call,从而可能引起段错误。
0x10 题目分析
为了练习万能gadget的使用,我特意自己写了一段小程序,即通过万能传参调用vul函数输出Success!代码附上:
|
|
怎么看这都是一段人畜无害的baby_csu,但我实在没想到竟然后面还衍生出了那么多坑….
IDA分析
一波上exp:
|
|
这里对第二次填充稍作解释。
可以看到,ROP链上我们先跳转到万能gadget1用于给寄存器赋值,然后retn到万能gadget2用于给寄存器转移值,但是万能gadget2运行完后又会运行下面那块函数(也就是万能gadget1),等于这整个过程会运行两次万能gadget1,这一系列操作将会抬升8*7共56字节的栈空间,因此我们还需要提供56个字节的垃圾数据进行填充,然后才能再拼接上retn要跳转的地址。
EXP完成,py运行….没有输出???edb启动,调试开始,踏坑之路开始….
这后面这个乱七八糟一点也不像地址的东西是什么鬼!一波资料后,我发现我成功混淆了地址与指针的概念。call指令将会转移至该指针中所保存的地址的位置,而我使用*elf.symbols[“vul”]*得到的直接是vul函数的真实地址,从而导致经过指针运算符运算后出现了一个不是地址的地址。换句话说,如果我这里要调用的是一个已调用过的libc函数,那我可以直接给r12寄存器传elf.got[“xxx”],从而即可实现调用该函数。
找到问题后,就要想解决方案了,这里点名表扬傅师傅和南梦师傅给出的解决方案。一种是找到一个指针,第一次劫持流程将vul的地址存进去,然后再call调用;第二种则是绕过call,通过后面的retn跳转至vul执行。
0x20 解决方案
然后,我就挑了第二个方案解决此问题,因为这更容易实现(而且我的本意只是学习万能gadget的使用啊)。那么…怎么绕过呢?此处再次实名表扬傅师傅,他提示我可以用__init_array_start函数的指针来跳过call。__init_array_start函数是ELF程序的一个初始化函数,运行它不会对栈空间造成影响,可以说是用于跳过call指令的最佳选择。下面附上exp:
|
|
但是,这样的调用方法也会有缺点,那就是等到跳转到vul函数空间时,rdi和rsi寄存器中的值已经被改变了,也就是我们还需要找gadget重新给这两个寄存器赋值,不过最麻烦的第三个参数解决了,别的应该都不是什么问题。
0x30 参考资料
https://ctf-wiki.github.io/ctf-wiki/CTF/linux/stackoverflow/medium-rop-zh/
https://www.cnblogs.com/ichunqiu/p/9288935.html
https://www.anquanke.com/post/id/85129