我的AFL++fuzzing入门之路(4)

我的AFL++fuzzing入门之路(4) 00 引言:跨越鸿沟 回顾前三天: Day 1:在"教科书式test.c"上跑通AFL++,理解状态界面 Day 2:深入插桩原理,发现"平墙式memcmp让AFL失明"的致命问题 Day 3:用ASAN将"隐形漏洞"转化为"显性崩溃" 提出问题: 真实项目不是afl-cc test.c这么简单。面对libpng这类真实解析器: 如何编译带依赖的开源项目? 如何应对无处不在的"平墙式"魔数检查(memcmp(header, "\x89PNG", 4))? 如何让AFL++不再"瞎猜"? 本章目标: 以libpng 1.6.54为演示目标,掌握实战前的三大核心准备: 编译真实项目(带ASAN插桩) 构建高质量种子语料库 用字典破解"平墙式"困境 01 实战目标编译:以libpng为例 1st. 为什么选libpng 理由 说明 经典攻击面 图片解析器天生处理不可信输入(用户上传) 代码规模适中 约3万行,比内核简单,比test.c真实 历史漏洞丰富 CVE-2018-14550、CVE-2019-7317等,有参考案例 格式相对简单 PNG结构清晰:文件头+Chunk(IHDR/IDAT/IEND) 官方支持完善 Google OSS-Fuzz已集成,有现成字典参考 选什么版本?看了一下,最后决定选择1.6.54,存在已知CVE,CVE-2026-25646(png_set_quantize()堆溢出),1.6.55修复 CVE-2026-25646速览:png_set_quantize()函数在处理调色板(PLTE Chunk)时存在堆缓冲区溢出,存在30年之久。这正是ASAN的检测目标,也是我们Fuzzing的"猎物"。 2nd. 下载与依赖 # 下载源码 wget https://download.sourceforge.net/libpng/libpng-1.6.54.tar.gz tar -xzf libpng-1.6.54.tar.gz && cd libpng-1.6.54 # 验证版本 head -5 README README for libpng version 1.6.54 ================================ # 安装依赖 sudo apt update sudo apt install zlib1g-dev # libpng依赖zlib 3rd. 用afl-cc + ASAN编译 命令如下: ...

March 11, 2026 · 5 min · 933 words · Chenjx12

我的AFL++fuzzing入门之路(3)

我的AFL++fuzzing入门之路(3) 00 前言回顾 在笔者的上一篇,也是 AFL++ Fuzzing 系列的第二篇中,我们从“汇编指令”深入到“策略机制”,完成了对 AFL++ 核心能力的解构: 插桩底层:通过 IDA 反编译,直观观察了 LLVM SanitizerCoverage 的内联插桩实现,解析了 __afl_area_ptr 与 guard 变量如何协作,以及 NeverZero 机制如何防止计数溢出,从指令级掌握了覆盖率追踪的底层逻辑; 反馈机制:通过“阶梯式”与“平墙式”代码的对比实验,量化了覆盖率反馈对 fuzzing 效率的决定性影响,验证了“覆盖率引导是 AFL 灵魂”这一核心思想,揭示了为何 memcmp 类检查是 fuzzing 的噩梦; 崩溃分析:借助 GDB 与 xxd 工具,我们完成了“触发崩溃→定位根因→验证输入”的完整闭环,学会了如何区分 ud2 指令触发的逻辑崩溃与内存破坏导致的异常。 虽然我们已经掌握了发现和分析崩溃的方法,但在真实漏洞挖掘中,存在一个更棘手的问题:并非所有的内存错误都会立即崩溃。大量的堆溢出、Use-After-Free 往往会“沉默”地破坏内存,直到程序运行很久后才随机崩溃,这让 AFL++ 难以捕获到有效的反馈信号。 为了解决“漏洞隐形”的问题,本文将引入 Sanitizer(消毒器) 机制。我们将重点探索 ASAN(地址消毒器)如何通过影子内存将“隐形漏洞”转化为“显性崩溃”,并结合实战演示其在 AFL++ 中的集成方法与性能权衡,进一步提升漏洞挖掘的深度与广度。 01 ASAN 深度解析(核心重点) 1st. 为什么需要ASAN 要回答这个问题,我们首先得知道 ASAN 是什么: ASAN 全名 AddressSanitizer(整合了 LeakSanitizer (LSAN)),是一个由 Google 开发的内存错误检测工具,能够精准捕捉堆溢出、栈溢出、Use-After-Free(UAF)等常见的内存安全问题。 那么,为什么我们的 Fuzzing 特别需要它? 1. 很多内存错误是“沉默”的 在上一篇文章中,我们遇到的崩溃都是“立即触发”的(如 __builtin_trap 或空指针解引用)。但在真实世界中,很多严重的漏洞并不会立即让程序崩溃: ...

March 9, 2026 · 4 min · 772 words · Chenjx12

我的AFL++fuzzing入门之路(2)

我的AFL++fuzzing入门之路(2) 00 前篇回顾 在笔者的上一篇,也是 AFL++ Fuzzing 系列的第一篇中,我们完成了以下工作: 理论基础:建立了对 AFL++ 的基础认知,包括其作为覆盖率引导模糊测试框架的定位、核心漏洞挖掘能力,以及编译时插桩的工作原理; 环境搭建:在 Ubuntu 24.04 虚拟机中完成了 AFL++ 的源码编译安装,解决了 Ubuntu Apport 与 core_pattern 的系统冲突; 实战入门:构造并测试了首个漏洞程序,在 2.7 秒内成功触发崩溃,同时掌握了 AFL++ 状态界面 8 区域的核心指标解读方法。 基于昨日的实践基础,本文将推进三个层面的深入探索: 插桩汇编表现:通过 IDA 反编译观察 AFL++ 使用 LLVM 的 SanitizerCoverage 在二进制层面插入的 inline 代码,理解 AFL++ 如何记录边覆盖率,从汇编指令级掌握覆盖率追踪的底层机制; 难度进阶:通过修改触发条件(从 “AFL++” 阶梯式扩展至平墙式),测试 AFL++ 的变异深度与效率边界,观察 havoc 策略在长模式匹配场景下的表现; 崩溃分析:引入 GDB 调试器对发现的崩溃进行根因定位,掌握调用栈回溯、寄存器状态检查等漏洞分析基础技能,完成从"发现崩溃"到"理解崩溃"的闭环。 01 汇编插桩 为了简单,咱直接素材复用,上一篇中的test.c使用afl-cc编译的,现在再用gcc编译一遍,然后放到不同的工具下比对 ❯ cat test.c #include <stdio.h> #include <string.h> int main(int argc, char *argv[]) { char buf[100]; FILE *f = fopen(argv[1], "r"); if (!f) return 1; fread(buf, 1, sizeof(buf), f); fclose(f); // 漏洞触发点:输入 "AFL++" 会崩溃 if (buf[0] == 'A' && buf[1] == 'F' && buf[2] == 'L') if (buf[3] == '+') if (buf[4] == '+') __builtin_trap(); // 触发崩溃(SIGTRAP) return 0; } afl-cc -o test test.c gcc -o test-gcc test.c 这里就得到了两个不同的可执行程序版本:有afl插桩的test和gcc编译的无插桩的test-gcc ...

March 9, 2026 · 5 min · 999 words · Chenjx12

我的AFL++fuzzing入门之路(1)

我的AFL++fuzzing入门之路(1) 00 前言 最近学校上的事渐渐变少,遂想着找份实习充实一下自己,学习更多先进的前沿技术。 但是真正开始写简历时便越发惶恐,觉得能写的实在太少了, 思来想去再学点东西来扩充一下自己的技术栈,翻着网页发现收藏夹里的fuzz测试介绍。 而fuzz模糊测试是我在去年就见到过的,但是当时也只是匆匆一瞥,知道fuzz是一种自动输入寻找崩溃点的技术。 现在有空了,多篇介绍AFL的文章看下来发现这个功能很强大,而且和二进制方向有一定的互补, 所以就开始尝试学习了。 由于笔者也刚在这个领域入门,所以文章可能会有写不够准确甚至谬误,欢迎各位大佬斧正。 01 AFL++Fuzzing介绍 AFL++(American Fuzzy Lop Plus Plus)是目前最流行和最先进的模糊测试(Fuzzing)框架之一,是经典AFL(American Fuzzy Lop)的社区维护增强版。 它是由Google安全工程师Michał Zalewski开发的一款开源fuzzing测试工具。 其可以高效地对二进制程序进行fuzzing,挖掘可能存在的内存安全漏洞,如_栈溢出、堆溢出、UAF、double free_等。 由于需要在相关代码处插桩,因此AFL主要用于对开源软件进行测试。 配合QEMU等工具,也可对闭源二进制代码进行fuzzing,但执行效率会受到影响。 工作原理:通过对源码进行重新编译时进行插桩(简称编译时插桩)的方式利用自动产生测试用例来探索二进制程序内部新的执行路径。AFL也支持直接对没有源码的二进制程序进行测试,但需要QEMU的支持。 02 环境搭建 这里有两种选择,可以使用docker容器,也可以直接安装到本机 先附上docker容器搭建的方法: docker pull aflplusplus/aflplusplus:latest docker run -ti -v /path/to/your/code:/src aflplusplus/aflplusplus 为了能够详细的学习(?,笔者决定直接安装到Ubuntu24.04虚拟机里。 先更新系统和软件包: sudo apt update && sudo apt upgrade -y 安装依赖(没错,就是这么多),有LLVM/Clang、Python、Rust等: sudo apt install -y build-essential python3-dev automake cmake git \ flex bison libglib2.0-dev libpixman-1-dev python3-setuptools \ cargo libgtk-3-dev lld llvm llvm-dev clang \ gcc-$(gcc --version|head -n1|sed 's/\..*//'|sed 's/.* //')-plugin-dev \ libstdc++-$(gcc --version|head -n1|sed 's/\..*//'|sed 's/.* //')-dev \ ninja-build cpio libcapstone-dev wget curl python3-pip 找个好地方,克隆源码 ...

March 8, 2026 · 6 min · 1234 words · Chenjx12