Add files via upload
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
### NX 是怎么绕过的
|
||||
|
||||
**绕过 NX 的基本思路**
|
||||
|
||||
NX 阻止了攻击者在数据段上执行**自己的代码**。那么,绕过 NX 的基本思路就是:**不注入代码,而是利用程序本身已有的、具有执行权限的代码**
|
||||
|
||||
这个思路催生了多种绕过技术,其中最主要、最著名、最通用的就是 **ROP**
|
||||
|
||||
**ROP**
|
||||
|
||||
ROP 是目前最主流的 NX 绕过技术。它的原理是利用程序中已有的、以 `ret` 指令结尾的短小代码片段,这些片段被称为 **“gadgets”**
|
||||
|
||||
**ROP 的工作原理**
|
||||
|
||||
1. **寻找 Gadgets:** 攻击者首先在目标程序或其依赖的共享库(如 `libc`)中寻找一系列以 `ret` 指令结尾的“gadgets”。一个 gadget 可能是一条或几条汇编指令,例如:`pop edi; ret;` 或 `mov eax, [ebx]; ret;`
|
||||
2. **构建 ROP 链:** 攻击者利用漏洞(如缓冲区溢出),用一系列精心挑选的 gadget 地址来覆盖栈上的返回地址这些地址按顺序排列,形成一个 **“ROP 链”**
|
||||
3. **劫持控制流:** 当函数返回时,它不再返回到正常调用的地方,而是返回到 ROP 链中的第一个 gadget
|
||||
4. **链式执行:**
|
||||
- 第一个 gadget 执行完后,其末尾的 `ret` 指令会从栈上弹出下一个地址,也就是 ROP 链中的第二个 gadget
|
||||
- 这样,一个 gadget 接一个 gadget 地执行,每个 `ret` 指令都将控制流转移到下一个 gadget
|
||||
- 通过这种方式,攻击者可以利用程序中已有的代码,间接地执行任意恶意逻辑
|
||||
|
||||
**ROP 攻击的最终目标**
|
||||
|
||||
一个典型的 ROP 攻击,其最终目标通常是调用某个函数,比如 `system()`,并将一个指向 Shell 命令字符串(例如 `"/bin/sh"`)的指针作为参数传递给它
|
||||
|
||||
一个完整的 ROP 链通常包含:
|
||||
|
||||
- **`pop` gadget:** 用于将栈上的参数值弹出到寄存器中,为函数调用做准备
|
||||
- **`system()` 的地址:** ROP 链的末尾,用于最终调用 `system()`
|
||||
- **字符串 `/bin/sh` 的地址:** 作为 `system()` 的参数
|
||||
|
||||
**绕过 NX 的其他方法**
|
||||
|
||||
除了 ROP,还有其他一些不那么常见,但同样能绕过 NX 的技术:
|
||||
|
||||
**1. JIT Spraying(JIT 喷射)**
|
||||
|
||||
这种方法主要用于绕过浏览器中的 NX 保护
|
||||
|
||||
- **原理:** JIT(Just-In-Time)编译器会动态地生成可执行代码。攻击者可以利用 JavaScript 等语言的 JIT 特性,构造大量的 `nop` 指令(无操作指令),然后在其末尾附上 Shellcode
|
||||
- **工作方式:** JIT 引擎会将这些指令编译成原生机器码并存放在一个**可执行的**内存区域。攻击者只需找到这个可执行区域的地址,并跳转过去即可
|
||||
|
||||
**2. Return-to-libc(返回到 libc)**
|
||||
|
||||
Return-to-libc 是 ROP 的前身和简化版。它不需要复杂的 gadget 链,而是直接劫持程序流,跳转到已加载的 `libc` 库中的一个函数
|
||||
|
||||
- **原理:** 攻击者利用漏洞,用 `libc` 中 `system()` 函数的地址覆盖栈上的返回地址
|
||||
- **工作方式:** 当函数返回时,程序流会直接跳转到 `system()` 函数。攻击者在栈上预先放置好 `system()` 函数所需的参数(如 `"/bin/sh"` 的地址),即可实现代码执行
|
||||
- **局限性:** 这种方法非常简单,但它只能调用 `libc` 中已有的函数,而不能像 ROP 那样组合出更复杂的逻辑
|
||||
Reference in New Issue
Block a user