ROP - Return Oriented Programing
Last updated
Last updated
学习与实践 AWS 黑客技术:HackTricks 培训 AWS 红队专家 (ARTE) 学习与实践 GCP 黑客技术:HackTricks 培训 GCP 红队专家 (GRTE)
返回导向编程 (ROP) 是一种高级利用技术,用于绕过 无执行 (NX) 或 数据执行防护 (DEP) 等安全措施。攻击者不再注入和执行 shellcode,而是利用二进制文件或已加载库中已经存在的代码片段,称为 “小工具”。每个小工具通常以 ret
指令结束,并执行小的操作,例如在寄存器之间移动数据或执行算术运算。通过将这些小工具串联在一起,攻击者可以构造一个有效绕过 NX/DEP 保护的有效负载,以执行任意操作。
控制流劫持:首先,攻击者需要劫持程序的控制流,通常通过利用缓冲区溢出来覆盖栈上的保存返回地址。
小工具链:攻击者然后仔细选择并链式连接小工具以执行所需的操作。这可能涉及为函数调用设置参数,调用函数(例如 system("/bin/sh")
),并处理任何必要的清理或附加操作。
有效负载执行:当易受攻击的函数返回时,而不是返回到合法位置,它开始执行小工具链。
通常,可以使用 ROPgadget、ropper 或直接从 pwntools (ROP) 查找小工具。
cdecl:调用者清理栈。函数参数以相反的顺序(从右到左)推送到栈上。参数从右到左推送到栈上。
stdcall:类似于 cdecl,但被调用者负责清理栈。
首先,假设我们已经在二进制文件或其加载的库中识别了必要的小工具。我们感兴趣的小工具包括:
pop eax; ret
:此小工具将栈顶值弹出到 EAX
寄存器中,然后返回,允许我们控制 EAX
。
pop ebx; ret
:与上述类似,但针对 EBX
寄存器,使我们能够控制 EBX
。
mov [ebx], eax; ret
:将 EAX
中的值移动到 EBX
指向的内存位置,然后返回。这通常被称为 写入-什么-在哪里小工具。
此外,我们还有 system()
函数的地址可用。
使用 pwntools,我们准备栈以执行 ROP 链,目标是执行 system('/bin/sh')
,注意链的开始:
为对齐目的的 ret
指令(可选)
system
函数的地址(假设 ASLR 被禁用且已知 libc,更多信息见 Ret2lib)
system()
返回地址的占位符
"/bin/sh"
字符串地址(系统函数的参数)
在类Unix系统上使用 System V AMD64 ABI 调用约定,其中 前六个整数或指针参数通过寄存器 RDI
、RSI
、RDX
、RCX
、R8
和 R9
传递。额外的参数通过栈传递。返回值放在 RAX
中。
Windows x64 调用约定使用 RCX
、RDX
、R8
和 R9
作为前四个整数或指针参数,额外的参数通过栈传递。返回值放在 RAX
中。
寄存器:64位寄存器包括 RAX
、RBX
、RCX
、RDX
、RSI
、RDI
、RBP
、RSP
和 R8
到 R15
。
为了我们的目的,让我们专注于可以让我们设置 RDI 寄存器(将 "/bin/sh" 字符串作为参数传递给 system())并调用 system() 函数的小工具。我们假设我们已经识别出以下小工具:
pop rdi; ret:将栈顶值弹出到 RDI 中,然后返回。对于设置 system() 的参数至关重要。
ret:一个简单的返回,在某些情况下对栈对齐很有用。
我们知道 system() 函数的地址。
下面是一个使用 pwntools 设置和执行 ROP 链的示例,旨在执行 system('/bin/sh') 在 x64 上:
在这个例子中:
我们利用 pop rdi; ret
gadget 将 RDI
设置为 "/bin/sh"
的地址。
在设置 RDI
后,我们直接跳转到 system()
,链中包含 system() 的地址。
如果目标环境需要,使用 ret_gadget
进行对齐,这在 x64 中更为常见,以确保在调用函数之前正确对齐栈。
x86-64 ABI 确保在执行 call 指令 时 栈是 16 字节对齐。LIBC 为了优化性能,使用 SSE 指令(如 movaps),这些指令需要这种对齐。如果栈没有正确对齐(意味着 RSP 不是 16 的倍数),对 system 等函数的调用将在 ROP 链 中失败。为了解决这个问题,只需在调用 system 之前在 ROP 链中添加一个 ret gadget。
由于 x64 使用寄存器处理前几个参数, 它通常需要比 x86 更少的 gadgets 来进行简单的函数调用,但由于寄存器数量增加和地址空间更大,找到和链接正确的 gadgets 可能更复杂。x64 架构中寄存器数量的增加和地址空间的扩大为漏洞开发提供了机遇和挑战,特别是在返回导向编程(ROP)的背景下。
请查看以下页面以获取此信息:
栈金丝雀: 在发生缓冲区溢出时,需要绕过存储的栈金丝雀以覆盖返回指针,从而滥用 ROP 链。
缺乏 Gadgets: 如果没有足够的 gadgets,就无法生成 ROP 链。
请注意,ROP 只是执行任意代码的一种技术。基于 ROP 开发了许多 Ret2XXX 技术:
Ret2lib: 使用 ROP 从加载的库中调用任意函数,带有任意参数(通常是类似 system('/bin/sh')
的东西)。
Ret2Syscall: 使用 ROP 准备对系统调用的调用,例如 execve
,并使其执行任意命令。
EBP2Ret 和 EBP 链接: 第一个将利用 EBP 而不是 EIP 来控制流程,第二个类似于 Ret2lib,但在这种情况下,流程主要通过 EBP 地址控制(尽管也需要控制 EIP)。
64 位,启用 Pie 和 nx,无金丝雀,用 vsyscall
地址覆盖 RIP,唯一目的是返回栈中的下一个地址,这将是对地址的部分覆盖,以获取泄漏标志的函数部分
arm64,无 ASLR,ROP gadget 使栈可执行并跳转到栈中的 shellcode
学习与实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE) 学习与实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE)