一种基于AFL测试网络服务程序的小技巧
字数 1063 2025-08-24 10:10:13
基于AFL测试网络服务程序的小技巧
方案背景
当前对于网络服务程序的模糊测试主要有以下几种解决方案:
-
Hook libc socket调用:基于LD_PRELOAD hook libc中socket相关函数,将网络流转换为标准输入IO
- 灵感来源于preeny
- AFLplusplus开发者推荐使用
- 缺点:在复杂网络程序(如nginx)中不一定通用
-
修改AFL传递输入方式:
- 代表方案:aflnet(Monash University提出)
- 将标准输入修改为网络发包方式
- 加入网络传输功能
- 缺点:移植其他优化策略工作量大,仍需修改被测程序
-
直接修改网络程序:
- 示例:bind9专门提供了用于Fuzz的部分
- 直接获取标准输入传入核心函数测试
- 优点:效率最高
- 缺点:需要深入了解程序,需定制开发
现有方案的问题
- 网络服务程序(如nginx)启动后会持续运行并监听端口,不会主动退出
- AFL需要每次重新启动程序
- 现有方案大多需要修改网络服务程序源代码
创新解决方案
核心思路
不直接通过AFL启动被测程序,而是:
- AFL启动辅助程序
- 辅助程序检查网络程序是否启动,未启动则启动网络服务程序
__AFL_SHM_ID环境变量传递给网络服务程序- 基于AFL插桩的网络服务程序记录覆盖率信息到共享内存
工作流程
- AFL启动辅助程序
- 辅助程序:
- 检查网络程序状态
- 启动网络服务程序(如果需要)
- 读取AFL输入
- 将输入通过网络发送至目标程序
- 网络服务程序:
- 持续运行
- 通过共享内存记录覆盖率
- 实现类似persistent mode的效果
异常处理
当网络服务程序失去响应时:
- 辅助程序主动crash
- AFL记录对应的crash输入
优势
- 无需修改AFL源代码
- 无需修改网络服务程序源代码
- 网络服务程序不需要重复启动,节省时间
- 实现了类似persistent mode的效果
实现要点
- 共享内存传递:通过
__AFL_SHM_ID环境变量确保覆盖率信息正确传递 - 辅助程序功能:
- 程序状态监控
- 网络输入转发
- 异常检测和处理
- 网络服务程序:
- 需要AFL插桩
- 持续运行模式
参考实现
作者提供了一个简单的实现,可以在这里查看(原文未提供具体链接)。
适用场景
- 持续运行的网络服务程序
- 启动开销较大的服务
- 需要保持状态的网络应用
- 难以修改源代码的闭源网络服务
注意事项
- 确保
__AFL_SHM_ID正确传递给网络服务程序 - 辅助程序需要有可靠的网络服务状态检测机制
- 需要考虑网络延迟对模糊测试效率的影响
- 需要处理网络连接异常情况