
在360环境中,需先编译支持模糊测试的V8引擎(添加编译选项如-DENABLE_FUZZING=1),准备包含正常用户行为的种子文件,运行AFL通过覆盖引导生成变体,结合内存分析工具(如Chrome DevTools或Valgrind)定位内存泄漏或缓冲区溢出漏洞。
老师讲解:AFL是动态模糊测试框架,核心是通过种子文件(初始有效输入)生成变体(变异后的测试用例),运行目标程序并收集覆盖数据(如函数调用、内存访问等),高覆盖的变体被保留并进一步变异,形成“覆盖引导”循环。
(类比:种子是“初始有效输入”,变体是“变异后的测试用例”,覆盖引导像“向漏洞方向引导”,最终找到漏洞。)
| 工具 | 定义 | 特性 | 使用场景 | 注意点 |
|---|---|---|---|---|
| AFL | 动态模糊测试框架 | 支持覆盖引导、变体生成 | 检测V8等JavaScript引擎的内存泄漏、缓冲区溢出 | 需编译目标程序支持模糊测试 |
| libFuzzer | Google的模糊测试库 | 基于随机变异、快速生成变体 | 检测C/C++程序,效率高 | 依赖编译选项(如-fsanitize=address) |
假设目标为360浏览器V8引擎,步骤如下:
编译V8引擎:
使用gyp配置添加fuzzing支持,命令如:
gyp configure --enable-fuzzing && gyp build
配置中添加-DENABLE_FUZZING=1等宏,生成支持模糊测试的引擎可执行文件v8(依赖库如gyp、v8源码、编译工具链)。
准备种子文件:
创建seeds/目录,放入正常输入的JavaScript文件(包含事件处理和API调用):
// seed.js
document.addEventListener('click', function(e) {
console.log('click event', e.target);
});
fetch('https://api.example.com/data').then(res => res.json());
对应种子文件:seeds/seed.js?event=click&url=https://api.example.com/data(种子文件需包含正常用户行为,过滤无效输入,如语法错误或无效API调用)。
运行AFL:
afl-fuzz -i seeds -o corpus -m 128 -d ./v8 ./seed.js
参数说明:-i指定种子目录,-o指定变体存储目录,-m限制内存(防止内存溢出),-d调试模式(便于分析变体)。
定位漏洞:
corpus目录下的变体,若Chrome DevTools的Memory面板显示内存持续增长(如变体运行后内存占用从100MB增长到200MB且未释放),则可能存在内存泄漏;可通过Valgrind验证内存分配是否异常(如malloc后未释放)。0x123456),则可能存在缓冲区溢出;可通过GDB跟踪变体运行时的内存访问,检查是否越界写入(如写入超出数组边界)。在360环境中,配置AFL测试V8引擎首先需要编译V8时添加-DENABLE_FUZZING=1等选项,确保引擎支持模糊测试。然后准备种子文件,包含用户正常浏览的JavaScript代码,比如事件处理和API调用。运行AFL时,用afl-fuzz -i seeds -o corpus -m 128 -d ./v8 ./seed.js,其中-i指定种子目录,-o指定变体存储,-m限制内存,-d调试。AFL通过变异种子生成变体,运行引擎并收集覆盖数据,高覆盖的变体被保留。定位漏洞时,用Chrome DevTools的Memory面板检查变体运行时的内存占用,若内存持续增长则可能存在内存泄漏;或分析覆盖数据中的异常内存访问,若出现越界写入则可能存在缓冲区溢出。例如,当变体导致Memory面板显示内存异常增长,结合Valgrind验证内存分配异常,可定位内存泄漏漏洞;若变体导致覆盖数据中出现异常的内存地址写入,则可能存在缓冲区溢出。
问:如何选择种子文件?
答:种子文件应包含正常使用的浏览器输入,如用户点击事件、DOM操作、API调用等,确保覆盖正常场景,过滤无效输入(如语法错误或无效API调用)。
问:变体生成策略针对JavaScript引擎的特定操作有哪些?
答:针对函数参数类型(如字符串转数组、事件回调参数变异),或针对动态代码加载的函数参数变异,比如事件回调的参数类型转换(如字符串转对象,或数组元素类型变异)。
问:如何处理V8沙箱环境对模糊测试的影响?
答:通过编译时添加沙箱隔离的适配选项(如-DENABLE_SANDBOX=1),或使用沙箱调试工具(如V8的沙箱调试接口)调整模糊测试参数,确保变体能访问敏感内存区域。
问:内存泄漏检测时如何区分正常内存增长和异常?
答:结合代码逻辑,若内存增长与输入无关(如循环中持续分配内存),则可能为泄漏;若增长与输入相关且释放后未减少,则为异常。例如,正常API调用后内存释放,若变体导致内存未释放,则为泄漏。
问:缓冲区溢出如何通过GDB验证?
答:用GDB跟踪变体运行时的内存访问,检查是否越界写入(如写入超出数组边界),或结合AFL的覆盖数据中异常的内存地址访问,确认是否为缓冲区溢出。
-DENABLE_FUZZING=1,导致V8不支持模糊测试,AFL无法运行。