何为ret2csu?
ret2csu即通过栈溢出等方法构造ROP链劫持利用__libc_csu_init
函数
这个函数长什么样
这是该函数全貌,不过我们主要利用0x40050
到0x4005a4
这两段,下文简称下面那部分为csu0
,上面那部分为csu1
代码分析
csu0
段代码主要进行的是将栈上的数据弹入到指定寄存器中(进行劫持利用时一般是直接从csu0段的第二行开始利用,即跳过``add rsp,8`)
而csu1
段则对弹入寄存器中的数据进行进一步处理
1 | rbx --> 与r12一起控制跳转地址 |
这里rbx一般赋值为0,rbp赋值1,避免进入循环.(如果需要借助csu来控制rbx的值,得注意r12与rbp的值)
适用情形
控制edi,rsi,rdx的参数
这三个寄存器在64位程序中储存的是函数调用时前三个参数
向bss段写入数据
前提得先泄露出libc的版本及基址
通过csu(0,1,read_addr,0,bss_addr,0,ret_addr)来向bss段写入数据
实战
例题:ciscn_s_3
checksec
先checkesc查看保护,除了nx啥都没开,不过这个预示着这题可能需要ROP链的构造
调试分析
调试偶遇限制读入0x400字节的read函数,试试看能否溢出
这里使用cyclic工具先生成一个100个字母的字符串cyclic 100
这里返回地址成功被修改了,看看偏移是多少
cyclic -l 0x6161616661616165
IDA分析
主程序就是系统调用了一个read
函数和write
函数
这个read
函数如上所述,可以通过栈溢出控制,而这个write
函数输出的字节为0x30,我们的的buf变量只有0x10的空间,所以可以通过write
函数来泄露栈地址
然后在函数栏发现了一个名为gadgets的可疑函数,跟进去看看
是给rax赋值的语句,而rax则与``syscall`有关
syscall
从rax寄存器读取值来进行系统调用,而3Bh对应的系统调用就是execve
逻辑推理
那么到这里我们的思路就很清晰了,我们的目的就是通过执行execve(/bin/sh,0,0)来getshell
即构造最终各寄存器储存的值是这样↓
1 | rax = 0x3b |
这里rax由gadgets这里的代码段来控制
而‘/bin/sh’可以直接往栈上写,然后通过泄露地址来将‘/bin/sh’弹入寄存器
至于rsi和rdi的值直接通过csu函数进行修改
那么到这里还有一个问题:如何泄露‘/bin/sh’地址
泄露栈地址
这里我们选取原rbp+10处的值作为基址来计算输入数据的偏移
理由: write输出的为0x30个字节,而rbp+8的位置是返回地址,在泄露地址的时候可能会通过栈溢出修改rbp的值,再往下就只有rbp+10处是储存的栈上的地址
exp
1 | from pwn import* |
小结
该题通过ret2csu来控制rsi与rdx的值使得execve函数能够成功getshell