使用AFL挖掘libxml2
字数 1211 2025-08-24 16:48:16

AFL挖掘libxml2漏洞实战指南

前言

XML(可扩展标记语言)是一种用于传输和存储数据的标记语言,与HTML专注于数据显示不同,XML专注于数据内容。libxml2是一个用于处理XML格式文件的C语言库和工具包。本指南将详细介绍如何使用AFL(American Fuzzy Lop)模糊测试工具来挖掘libxml2中的漏洞。

环境准备

安装必要工具

sudo apt install autoconf
sudo apt install libtool-bin

获取AFL并编译

  1. 下载AFL并编译afl-clang-fast(需要已安装clang)
  2. 切换到AFL的llvm_mode目录执行make
  3. 返回AFL根目录执行make install

编译libxml2-2.9.2

cd libxml2根目录
./autogen.sh --prefix=/path/to/install --with-python-install-dir=/path/to/install CC=afl-clang-fast
AFL_USE_ASAN=1 make -j 4
sudo make -j 4 install

参数说明:

  • --prefix:指定安装目录
  • --with-python-install-dir:指定Python安装目录
  • AFL_USE_ASAN=1:启用ASAN(AddressSanitizer)内存错误检测器
  • -j 4:使用4个进程并行编译

编写测试程序(harness.c)

基础版本

#include "libxml/parser.h"
#include "libxml/tree.h"

int main(int argc, char **argv) {
    if (argc != 2) return 1;
    
    xmlInitParser();
    while (__AFL_LOOP(1000)) {
        xmlDocPtr doc = xmlReadFile(argv[1], NULL, 0);
        if (doc != NULL) xmlFreeDoc(doc);
    }
    xmlCleanupParser();
    return 0;
}

增强版本(提高覆盖率)

#include <stdio.h>
#include <libxml/parser.h>
#include <libxml/tree.h>

static void print_element_names(xmlNode *a_node) {
    xmlNode *cur_node = NULL;
    for (cur_node = a_node; cur_node; cur_node = cur_node->next) {
        if (cur_node->type == XML_ELEMENT_NODE) {
            printf("node name: %s\n", cur_node->name);
        }
        print_element_names(cur_node->children);
    }
}

int main(int argc, char **argv) {
    xmlDoc *doc = NULL;
    xmlNode *root_element = NULL;

    if (argc != 2) return 1;

    doc = xmlReadFile(argv[1], NULL, 0);

    if (doc == NULL) {
        printf("error: could not parse file %s\n", argv[1]);
        xmlFreeDoc(doc);
        xmlCleanupParser();
        return -1;
    }
    
    while (__AFL_LOOP(1000)) {
        root_element = xmlDocGetRootElement(doc);
        print_element_names(root_element);
    }

    xmlFreeDoc(doc);
    xmlCleanupParser();
    return 0;
}

编译测试程序

动态链接方式(适合普通测试)

AFL_USE_ASAN=1 afl-clang-fast ./harness.c -I ./build/include/libxml2/ -L ./build/lib -lxml2 -lz -lm -g -o harness

静态链接方式(适合AFL模糊测试)

AFL_USE_ASAN=1 afl-clang-fast ./harness.c -I ./build/include/libxml2/ ./build/lib/libxml2.a -lz -lm -g -o harness

参数说明:

  • -I:指定头文件目录
  • -lz:使用zlib库
  • -lm:使用math库
  • -g:包含调试信息

启动AFL模糊测试

afl-fuzz -m none -i in -o out -x ~/afl-2.52b/dictionaries/xml.dict ./harness @@

参数说明:

  • -m none:不限制内存使用(便于ASAN检测)
  • -i in:输入样本目录
  • -o out:输出目录
  • -x:指定XML字典文件
  • @@:表示输入文件参数

样本准备与优化

  1. 获取样本:从MozillaSecurity/fuzzdata获取XML样本
  2. 筛选小样本
    find ./xml/ -size -1024c > tmp.txt
    mkdir less1k
    for l in `cat ./tmp.txt`; do cp $l ./less1k/; done;
    
  3. 精简样本
    afl-cmin -i less1k/ -o cmin-out/ -m none ./harness1 @@
    
  4. 最小化样本
    mkdir tmin-out
    cd cmin-out
    for i in *; do afl-tmin -i $i -o ../tmin-out/$i -m none -- ../harness @@; done;
    

漏洞分析

常见漏洞类型

  1. 堆溢出读:在解析特定格式XML时可能导致一个字节的堆溢出读
  2. 下标越界:在xmlDictQLookup函数中,未充分检查len - (plen + 1 + 1)可能导致下标越界(CVE-2015-7497)

漏洞修复

  1. 误报修复:修改parse.c,用自定义函数替换宏定义,并添加__attribute__((no_sanitize_address))标记
  2. CVE-2015-7497修复:根据官方补丁修改dict.c,增加长度检查

改进模糊测试效果

  1. 增加测试函数:在harness中添加更多libxml2函数调用
  2. 使用更全面的字典:替换AFL自带的XML字典,使用更全面的libxml_xml_read_memory_fuzzer.dict
  3. 使用screen保持会话
    screen afl-fuzz -m none -i ./tmin-out/ -o out2 -x ./libxml_xml_read_memory_fuzzer.dict -- ./harness @@
    

参考资料

  1. AFL Training GitHub
  2. AFL使用指南
  3. XML基础教程
  4. Mozilla Fuzz Data

通过本指南,您可以系统地学习如何使用AFL挖掘libxml2中的漏洞,包括环境搭建、测试程序编写、样本优化和漏洞分析等关键步骤。

AFL挖掘libxml2漏洞实战指南 前言 XML(可扩展标记语言)是一种用于传输和存储数据的标记语言,与HTML专注于数据显示不同,XML专注于数据内容。libxml2是一个用于处理XML格式文件的C语言库和工具包。本指南将详细介绍如何使用AFL(American Fuzzy Lop)模糊测试工具来挖掘libxml2中的漏洞。 环境准备 安装必要工具 获取AFL并编译 下载AFL并编译 afl-clang-fast (需要已安装clang) 切换到AFL的 llvm_mode 目录执行 make 返回AFL根目录执行 make install 编译libxml2-2.9.2 参数说明: --prefix :指定安装目录 --with-python-install-dir :指定Python安装目录 AFL_USE_ASAN=1 :启用ASAN(AddressSanitizer)内存错误检测器 -j 4 :使用4个进程并行编译 编写测试程序(harness.c) 基础版本 增强版本(提高覆盖率) 编译测试程序 动态链接方式(适合普通测试) 静态链接方式(适合AFL模糊测试) 参数说明: -I :指定头文件目录 -lz :使用zlib库 -lm :使用math库 -g :包含调试信息 启动AFL模糊测试 参数说明: -m none :不限制内存使用(便于ASAN检测) -i in :输入样本目录 -o out :输出目录 -x :指定XML字典文件 @@ :表示输入文件参数 样本准备与优化 获取样本 :从 MozillaSecurity/fuzzdata 获取XML样本 筛选小样本 : 精简样本 : 最小化样本 : 漏洞分析 常见漏洞类型 堆溢出读 :在解析特定格式XML时可能导致一个字节的堆溢出读 下标越界 :在 xmlDictQLookup 函数中,未充分检查 len - (plen + 1 + 1) 可能导致下标越界(CVE-2015-7497) 漏洞修复 误报修复 :修改 parse.c ,用自定义函数替换宏定义,并添加 __attribute__((no_sanitize_address)) 标记 CVE-2015-7497修复 :根据官方补丁修改 dict.c ,增加长度检查 改进模糊测试效果 增加测试函数 :在harness中添加更多libxml2函数调用 使用更全面的字典 :替换AFL自带的XML字典,使用更全面的 libxml_ xml_ read_ memory_ fuzzer.dict 使用screen保持会话 : 参考资料 AFL Training GitHub AFL使用指南 XML基础教程 Mozilla Fuzz Data 通过本指南,您可以系统地学习如何使用AFL挖掘libxml2中的漏洞,包括环境搭建、测试程序编写、样本优化和漏洞分析等关键步骤。