[ 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
2
3
4
5
6
7
8
保护区:[0x600dc0 ───────────── 0x601000)
↑ ↑
.init_array (0x600dc0) 边界线
.fini_array (0x600dc8) │
.dynamic (0x600dd0) │
.got (0x600fc0) ──────────┘ ← 圈里 → 只读

.data (0x601000) ────────────────── ← 圈外 → 可写(普通数据,不是 GOT)

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 三部曲:

  • pwn20 — No RELRO:两张表都可写
  • pwn21 — Partial RELRO:.got 锁、.got.plt 可写

进阶:

  • pwn25 ret2libc 栈溢出利用 (NX 绕过) — Full RELRO 下 GOT 覆写不可行,但泄露仍可用
  • pwn1 — checksec 查看保护等级
上一页
2026-08-22 20:36:38
下一页