[ pwn 学习 ] CTFshow-pwn22
2026-08-22 20:36:38
pwn22
1.基础信息

Full RELRO``.got``.got.plt都不可写
思路是直接放弃延迟绑定,启动时一次性查完所有函数地址填好,然后把整本电话簿焊死
2.Full RELRO的两个标志
2.1BLIND_NOW——立刻绑定
1 | readelf -d pwn22 | grep -i "bind\|flags" |

BLIND_NOW告诉动态连接器:程序启动时就把所有函数地址全部查完,不要等第一次调用再查。这是Full RELRO的硬性标志。
pwn20 和 pwn21 没有这一项
2.2 .got.plt 消失了
1 | readelf -S pwn22 | grep -A 1 "\.got" |

只有一张 .got 表,没有 .got.plt。
既然不搞延迟绑定了,那张留给链接器”后门填地址”的 .got.plt 表也就没存在的必要了——所有函数指针直接合进 .got 里,一次性填完就锁。
3. GNU_RELRO——把 .got 也锁死
1 | readelf -l pwn22 |

保护区范围:[0x600dc0, 0x600dc0 + 0x240)** = ****[0x600dc0, 0x601000)**
对照段地址:
1 | 保护区:[0x600dc0 ───────────── 0x601000) |
Section to Segment 映射确认:

GNU_RELRO 把 .got 也罩住了。
启动后 mprotect 一把锁死,谁来写谁段错误。
对比 pwn21(Partial RELRO):pwn21 的保护区到 0x601000,.got.plt 刚好在边界外逃过一劫。pwn22 没有 .got.plt,.got 被牢牢圈住。
4. 解题
Full RELRO+ 无.got.plt→.got不可写(0)、.got.plt不存在/不可写(0).got地址 →0x600fc0
1 | ctfshow{0_0_0x600fc0} |
5. 三题对比速查
| pwn20 No RELRO | pwn21 Partial | pwn22 Full | |
|---|---|---|---|
| GNU_RELRO | ❌ | ✅ | ✅ |
| BIND_NOW | ❌ | ❌ | ✅ |
| .got.plt 存在? | ✅ | ✅ | ❌ |
| .got 可写 | ✅ 1 | ❌ 0 | ❌ 0 |
| .got.plt 可写 | ✅ 1 | ✅ 1 | ❌ 0 |
| GOT 劫持 | 随便搞 | 只能搞 .got.plt | 💀 彻底没门 |
| Flag | {1_1_0x..._0x...} |
{0_1_0x..._0x...} |
{0_0_0x...} |
相关笔记
RELRO 三部曲:
进阶:
- pwn25 ret2libc 栈溢出利用 (NX 绕过) — Full RELRO 下 GOT 覆写不可行,但泄露仍可用
- pwn1 —
checksec查看保护等级