一、前言
Fuzzing是漏洞挖掘领域最有效的方法之一,可以用来发现大量的远程代码执行和提权的漏洞。然而,fuzzing优势相对肤浅和盲目的。随机变异使得我们很难实现达到测试程序特定的代码路径。这就使得测试的代码覆盖率很低。
有很多人试图去解决这个问题,Tavis
Ormandy曾经提出一种:根据代码覆盖率,从大量高质量的输入文件语料中选取一个子集,然后按照传统方法去fuzz。这种方法很有效,但前提是需要一个这样的语料。另一方面,代码覆盖率只提供了一个很简单的对程序状态的描述,当Fuzzing测试到了一定的程度,代码覆盖率就没什么作用了。
所以,大家都在探索更复杂的技术,比如:程序控制流分析,符号执行或静态分析。这些技术在实验中是很有前途的,但是在实际应用中显得效率低下、缺乏可靠性。
因此提出了以程序控制流分析为核心的AFL_FUZZ
本工程实践内容是阅读AFL源码,最后使用其对分布式数据库进行漏洞检测
二、软件设计方案:
2.1软件结构特点:
AFL本身是一个测试软件,使用给定的测试用例对目标程序进行自动化执行,期望在执行过程中造成目标程序的崩溃,以发现目标程序存在的漏洞,不存在广义的前后端与数据库,因为其是linux c编写,运行通过命令行,数据的存储就是linux中的一个个文件。
2.2接口API:
getopt:对命令行中的命令参数进行解析,以做出相应动作;
setup_signal_handlers():设置一些对应信号的处理方法,比如退出等
check_asan_opts():查看Address-Sanitizier和MSAN的运行选项,asan是linux下内存检测工具
save_cmdline(argc, argv):保存命令行
fix_up_banner(argv[optind]):设置一下banner
check_if_tty():配置终端的屏幕是否能输出,若能输出更新终端窗口大小
get_core_count():计算逻辑cpu核心数,并查看当前系统的可运行进程是否对于cpu核心而言过多
check_crash_handling():确保核心转储不会进入程序,不怎么理解
check_cpu_governor():对cpu频率进行检查和设置
setup_post():从动态链接库中获得afl_postprocess函数,并检查其能否使用
setup_shm():前一半不知道在干嘛,后一半是创建64KB的共享内存,引入共享内存并让trace_bits指向共享内存的第一个字节
init_count_class16():对count_class_lookup16(对0-65535次命中次数进行分类)进行初始化
setup_dirs_fds():重新创建out_dir里面的各种目录queue crash hangs plot_data 等
read_testcases():遍历in_dir/queue目录里的测试用例,对文件做一些判断,包括是否经过确定性变异,之后把符合的测试用例加入到队列条目中。
load_auto():加载50个自动检测生成的token
AFL有大量的API,所以这里就省略介绍其他的了。
三、软件系统概念视图
3.1分解视图:
3.2依赖视图:
3.3执行视图:
四、源代码的目录文件结构:
五、软件系统运行环境和技术选型说明:
AFL由Linux C编写,所以运行环境的是Unix类系统
技术选型说明:所选测试用例尽量小,太大会降低测试效率
六、总结:
AFL是现在工业界普遍运用的测试工具,学习如何使用以及深入了解其原理对程序员是很有意义的。