Ret2csu

从零开始学习AWS黑客技术,成为 htARTE(HackTricks AWS红队专家)

支持HackTricks的其他方式:

ret2csu是一种黑客技术,当您试图控制程序但找不到通常用于操纵程序行为的gadgets时使用。

当程序使用某些库(如libc)时,它具有用于管理程序中不同部分如何通信的一些内置函数。在这些函数中,有一些隐藏的宝石可以充当我们缺失的gadgets,特别是一个称为__libc_csu_init的函数。

__libc_csu_init中的神奇Gadgets

在**__libc_csu_init**中,有两个要突出的指令序列(gadgets):

  1. 第一个序列允许我们在几个寄存器(rbx、rbp、r12、r13、r14、r15)中设置值。这些类似于我们可以稍后使用的数字或地址的存储槽。

pop rbx;
pop rbp;
pop r12;
pop r13;
pop r14;
pop r15;
ret;

这个工具允许我们通过从堆栈中弹出值来控制这些寄存器。

  1. 第二个序列使用我们设置的值来执行一些操作:

  • 将特定值移动到其他寄存器,使它们准备好作为函数参数使用。

  • 调用一个位置,该位置由将r15和rbx中的值相加确定,然后将rbx乘以8。

  1. 也许你不知道任何要写入的地址,而且你需要一个 ret 指令。请注意,第二个小工具也会以 ret 结尾,但是你需要满足一些条件才能到达它:

条件如下:

  • [r12 + rbx*8] 必须指向存储可调用函数的地址(如果没有思路且没有PIE,可以直接使用 _init 函数);

  • 如果 _init0x400560,使用 GEF 在内存中搜索指向它的指针,并使 [r12 + rbx*8] 成为具有指向 _init 的指针的地址:

  • rbprbx 必须具有相同的值以避免跳转

  • 你需要考虑一些省略的弹出操作

RDI 和 RSI

从 ret2csu gadget 中控制 rdirsi 的另一种方法是通过访问特定的偏移量:

查看此页面以获取更多信息:

BROP - Blind Return Oriented Programming

示例

使用调用

假设你想要进行系统调用或调用一个像 write() 这样的函数,但需要在 rdxrsi 寄存器中作为参数具有特定值。通常,你会寻找直接设置这些寄存器的 gadget,但你找不到任何。

这就是 ret2csu 发挥作用的地方:

  1. 设置寄存器:使用第一个 magic gadget 从堆栈中弹出值并将其放入 rbx、rbp、r12 (edi)、r13 (rsi)、r14 (rdx) 和 r15 中。

  2. 使用第二个 Gadget:有了这些设置的寄存器,你可以使用第二个 gadget。这使你可以将你选择的值移动到 rdxrsi 中 (分别来自 r14 和 r13),为函数调用准备参数。此外,通过控制 r15rbx,你可以使程序调用位于你计算并放入 [r15 + rbx*8] 中的地址的函数。

你可以在这里使用此技术并解释它的示例,这是它使用的最终利用:

绕过调用并到达ret

以下漏洞利用是从此页面提取的,在这个页面中使用了ret2csu,但是不是使用调用,而是绕过比较并到达ret

为什么不直接使用libc?

通常这些情况也容易受到ret2plt + ret2lib的影响,但有时您需要控制的参数比直接在libc中找到的gadget更多。例如,write()函数需要三个参数,直接找到设置所有这些参数的gadget可能是不可能的

最后更新于