Ret2lib
基本信息
Ret2Libc 的本质是将易受攻击的程序的执行流重定向到共享库中的一个函数(例如 system、execve、strcpy),而不是在堆栈上执行攻击者提供的 shellcode。攻击者构造一个有效载荷,修改堆栈上的返回地址,使其指向所需的库函数,同时根据调用约定正确设置任何必要的参数。
示例步骤(简化)
获取要调用的函数的地址(例如 system)和要调用的命令(例如 /bin/sh)
生成一个 ROP 链,将第一个参数传递给指向命令字符串的地址,并将执行流传递给函数
查找地址
假设使用的
libc
是当前机器上的libc
,可以通过以下方式找到它将加载到内存中的位置:
如果您想检查ASLR是否更改了libc的地址,可以执行以下操作:
知道使用的libc后,还可以通过以下方法找到
system
函数的偏移量:
知道使用的libc后,还可以通过以下方法找到字符串
/bin/sh
函数的偏移量:
使用 gdb-peda / GEF
了解使用的 libc 后,还可以使用 Peda 或 GEF 来获取 system 函数的地址,exit 函数的地址以及字符串 /bin/sh
的地址:
使用 /proc/<PID>/maps
如果进程每次与其通信时都会创建子进程(网络服务器),尝试读取该文件(可能需要使用 root 权限)。
在这里,您可以找到进程内部libc 加载的确切位置以及每个子进程将要加载的位置。
在这种情况下,它加载在0xb75dc000(这将是 libc 的基地址)
未知的 libc
可能您不知道二进制文件正在加载的 libc(因为它可能位于您无法访问的服务器上)。在这种情况下,您可以利用漏洞来泄漏一些地址并找出使用的 libc 库:
Leaking libc address with ROP您可以在以下位置找到用于此目的的 pwntools 模板:
Leaking libc - template使用 2 个偏移量了解 libc
查看页面 https://libc.blukat.me/ 并使用 libc 中几个函数的地址来找出使用的版本。
绕过 32 位 ASLR
这些暴力攻击仅适用于 32 位系统。
如果利用是本地的,您可以尝试暴力破解 libc 的基地址(适用于 32 位系统):
如果攻击远程服务器,您可以尝试暴力破解
libc
函数usleep
的地址,将10作为参数传递。如果某个时刻服务器需要额外10秒才能响应,则找到了该函数的地址。
One Gadget
执行一个shell,只需跳转到libc中的一个特定地址:
One Gadgetx86 Ret2lib 代码示例
在这个示例中,ASLR暴力破解已集成在代码中,并且易受攻击的二进制文件位于远程服务器中:
x64 Ret2lib 代码示例
查看示例:
ROP - Return Oriented ProgramingARM64 Ret2lib 示例
在ARM64的情况下,ret指令跳转到x30寄存器指向的位置,而不是栈寄存器指向的位置。因此,这会变得有点复杂。
此外,在ARM64中,一条指令执行其本身的功能(不可能在指令中间跳转并将其转换为新的指令)。
查看示例:
Ret2lib + Printf leak - arm64Ret-into-printf(或puts)
这允许通过调用printf
/puts
并将特定数据放置为参数来从进程中泄漏信息。例如,将puts
在GOT中的地址放入puts
的执行中将泄漏内存中puts
的地址。
Ret2printf
这基本上意味着滥用Ret2lib将其转换为printf
格式字符串漏洞,通过使用ret2lib
调用printf并使用要利用的值(听起来毫无意义,但是可能):
其他示例和参考资料
Ret2lib,给定libc中函数地址的泄漏,使用一个gadget
64位,启用ASLR但没有PIE,第一步是填充溢出直到canary的字节0x00,然后调用puts并泄漏它。使用canary创建ROP gadget来调用puts以从GOT中泄漏puts的地址,然后使用ROP gadget来调用
system('/bin/sh')
64位,启用ASLR,没有canary,在主函数中有来自子函数的堆栈溢出。ROP gadget调用puts以泄漏GOT中puts的地址,然后调用一个gadget。
64位,没有PIE,没有canary,没有relro,nx。使用write函数泄漏write(libc)的地址并调用一个gadget。
使用格式字符串从堆栈中泄漏canary,并使用缓冲区溢出调用system(在GOT中)并传递
/bin/sh
的地址。32位,没有relro,没有canary,nx,pie。滥用错误的索引以从堆栈中泄漏libc和堆地址。滥用缓冲区溢出以调用
system('/bin/sh')
的ret2lib(需要堆地址来绕过检查)。
Last updated