[ pwn 学习 ] CTFshow-pwn21 Partial RELRO
2026-07-23 22:53:41 # CTF # Pwn

1. 基础信息

和 pwn20 唯一区别:RELRONo RELRO 变成 Partial RELRO

2. 回顾:RELRO 三等级

等级 .got 能写? .got.plt 能写?
No RELRO
Partial RELRO
Full RELRO

Partial RELRO 的取舍:

  • .got 里的数据初始化后不会再变 → 锁掉
  • .got.plt 因为延迟绑定还要填函数地址 → 留着能写

3. 找两张表地址

段表 -S 说的都能写,别信。程序头 -lGNU_RELRO 圈起来那块,运行时会被锁成只读。

3.1 readelf -S 先看段表

段表里两张表都标 WA(可写),但段表是静态声明,运行时由程序头决定。

段名 地址 说明
.got 0x600ff0 杂项数据
.got.plt 0x601000 外部函数地址表

3.2 readelf -l 再看程序头(真正权限)

readelf -l pwn21

字段 含义
VirtAddr 0x600e10 保护区起始
MemSiz 0x1f0 保护区大小 = 496 字节
Flags R 只读

保护区范围 = [0x600e10, 0x601000)

对照段地址:

1
2
3
4
5
6
7
8
保护区范围:[0x600e10 —————————— 0x601000)
↑ ↑
.init_array 边界线
.fini_array │
.dynamic │
.got (0x600ff0) ────────────┘ ← 在保护区内 → 只读 ❌

.got.plt (0x601000) ─────────────── ← 刚好在边界外 → 可写 ✅

Section to Segment 映射也验证了 .got.plt 不在 GNU_RELRO 内:

4. 解题

  • Partial RELRO.got 不可写(0)、.got.plt 可写(1)
  • .got 地址 → 0x600ff0
  • .got.plt 地址 → 0x601000
1
ctfshow{0_1_0x600ff0_0x601000}