现代缓解措施下,一个漏洞还需要什么才能变成 exploit

十年前一个栈溢出基本就是 shellcode 直接跳。现在要过的关多了不少,列一下每一层和对应的破法:

DEP/NX — 数据页不可执行。
破法:ROP。不注入代码,复用已有的代码片段。

ASLR — 地址随机化。
破法:信息泄露。需要先有一个 leak 原语把某个模块基址读出来。这通常是整条链里最难的一环,很多漏洞卡在这里。

Stack canary — 栈上的哨兵值。
破法:泄露 canary,或者绕过(比如覆盖不经过 canary 的指针)。

CFI / CET — 控制流完整性。
破法:数据流攻击(DOP),不劫持控制流,只改数据。或者找 CFI 覆盖不到的间接调用。

堆隔离(如 iOS 的 kalloc_type) — 不同类型对象不混用堆块。
破法:难。要么找同类型的 UAF,要么攻击隔离机制本身。

实战里的感受是:现在的难点已经不是"怎么执行代码",而是"怎么拿到第一个地址"。一个好的 leak 比一个好的写原语值钱得多。

你们最近一条链里最难的是哪一环?