Files
2025-09-25 04:04:35 +08:00

53 lines
4.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
### 讲讲 ASLR 怎么绕过
**ASLR 的核心思想**
首先,我们简要回顾一下 ASLR 的原理。ASLR 是一种**漏洞缓解机制**,它的核心思想是**将程序在内存中的关键区域(如可执行文件、共享库、堆和栈)加载到随机的地址**
没有 ASLR 时,每次运行程序,其内存布局都是固定的。攻击者可以精确地预测函数和变量的地址,然后利用漏洞(如缓冲区溢出)来劫持程序流,跳转到这些预先知道的地址
有了 ASLR,程序每次运行时地址都会变化,攻击者无法再依赖硬编码的地址,这大大增加了攻击的难度
**绕过 ASLR 的基本思路**
ASLR 依赖于**地址的保密性**。如果攻击者能够泄露(也就是获得)任何一个模块的真实地址,那么 ASLR 就会失效。这是因为一个模块内部的相对偏移(RVA)是固定的。一旦知道了一个函数的真实地址,攻击者就可以通过这个地址减去其 RVA,得到模块的基址,进而计算出该模块中所有其他函数和数据的位置
因此,绕过 ASLR 的核心思路就是**信息泄露**
**常见绕过 ASLR 的技术**
以下是一些最常见的绕过 ASLR 的技术,从简单到复杂
**1. 信息泄露漏洞**
这是最直接的绕过方式。如果程序本身存在一个信息泄露漏洞,攻击者就可以利用它来获得内存中的地址
- **格式化字符串漏洞(Format String Bug):** 攻击者可以利用 `%p` 格式符来打印栈上的指针。如果栈上恰好有一个指向模块基址或函数地址的指针,攻击者就可以轻松获得这些关键地址
- **堆溢出或栈溢出:** 如果攻击者能够通过溢出漏洞读取栈或堆上的数据,他们可能会读出函数返回地址、栈指针或堆块指针,这些指针都包含有地址信息
- **未初始化变量:** 如果一个变量没有初始化,它可能包含之前内存中的残余数据,而这些残余数据可能恰好是一个地址
**如何利用:**
1. 利用信息泄露漏洞获得某个函数的真实地址,比如 `puts()` 的地址
2. 通过 `puts()` 的地址,计算出 `libc` 库的基址(`puts_addr - puts_libc_offset = libc_base`
3. 有了 `libc` 的基址,就可以计算出 `system()` 函数和字符串 `"/bin/sh"` 的地址,从而构造 ROP 链来执行 Shellcode
**2. 局部 ASLR 绕过**
某些系统或老旧的程序只对部分内存区域进行了 ASLR 随机化,或者随机化范围非常小
- **弱 ASLR** 32 位系统上的 ASLR 随机化范围通常只有 16 位(64KB)。攻击者可以通过暴力破解或多次尝试来命中正确的地址,这被称为**暴力破解攻击(Brute-force Attack**
**3. 非随机化区域利用**
有些程序或系统组件没有启用 ASLR 保护,它们总会被加载到固定的地址。攻击者可以利用这些非随机化区域作为跳板
- **静态编译的程序:** 如果一个程序是静态编译的,不依赖任何共享库,那么它的所有代码和数据都在一个文件中。即使开启了 ASLR,其自身的基址是随机化的,但如果攻击者能够泄露出一个地址,就能推算出所有其他地址
- **禁用 ASLR 的模块:** 有些老旧的 DLL 可能没有启用 ASLR 编译。这些模块每次都会被加载到固定地址,攻击者可以直接利用其中的 gadgets 或函数
**4. 通过其他漏洞组合绕过**
ASLR 很少被单独绕过,通常需要与其他漏洞(如代码执行漏洞)结合使用
- **Return-to-PLT/GOT** 攻击者可以利用漏洞劫持程序流,跳转到 GOTGlobal Offset Table)中一个已解析的函数地址。因为 GOT 存放的是外部函数的真实地址,通过读取这个地址,攻击者就能获得 `libc` 等共享库的基址
- **ROP Gadget 寻找:** 在没有信息泄露漏洞的情况下,攻击者可以使用**多次尝试**或**堆喷射**等技术。在现代 64 位系统上,ASLR 随机化范围很大,暴力破解几乎不可行。所以,信息泄露是绕过 ASLR 的首选方式