0.前言
有一说一,这个rop有一些点困扰了我很久,下面予以说明。
1.总体思路
ret2csu一般是应对程序中存在明显的栈溢出漏洞,但在程序中找不到system()函数,但可看到其存在read()、write()、和 __libc_csu_init() 函数的情况。
利用程序中的一些gadget来实现获取shell。
rop链的构造一般为:pop n ret+n个寄存器的值+mov call。(这边的call要注意,待会讲)
2.例子
该例子用到的ELF文件:点击下载
用IDA分析(也可用ropper或ROPgadget),找到一些gadget如下图:
所以我们构建的rop可以如下:
1 | gadget1_addr |
先控制程序到gadget1的地址(0x4013aa),再分别把值赋给六个寄存器,再到gadget2的地址(0x401390),经过mov后让我们要用的寄存器赋上我们期望的值,最后再call execv。
注意,这里的call的地址必须是execv在got中的地址!
这里各寄存器的值传递如下:
rbx <- 0
rbp <- 1
rdi <- r12 <- buf_addr(buf中的值是“/bin/sh”)
rsi<- r13 <- 0
rdx <- r14 <- 0
r15 <- execv_addr(execv函数在got中的地址)
构建的脚本文件如下:
1 | from pwn import * |
运行以上脚本即可获取shell。