上个月末无聊的划水时间段内,在推上看到有人发了一篇关于如何结合去年新发布的符号执行Symcc与模糊测试引擎AFL,以提升Fuzz效率的视频贴。打开这个链接后才发现是个卖课的,emmm.... , 看价格£1499果断打扰了,果然没钱的都不配学安全吗23333;原技术文章看来是看不到了,只能靠公开的一段视频还原操作。

背景介绍

虽然有很多大佬肯定已经十分熟悉模糊测试和符号执行了,还是简单介绍一下背景知识,这样更有连贯性。

模糊测试 AFL

模糊测试(fuzz testing, fuzzing)是一种软件测试技术。 其核心思想是將自动或半自动生成的随机数据输入到一个程序中,并监视程序异常,如崩溃,断言(assertion)失败,以发现可能的程序错误,比如内存泄漏。 模糊测试常常用于检测软件或计算机系统的安全漏洞。

模糊测试诞生于1988年秋季的一个黑暗暴风雨之夜 [Takanen et al, 2008.]。巴顿·米勒教授坐在麦迪逊威斯康星州的公寓里,通过一条1200波特的电话线连接到他所属大学的计算机。阵阵的雷暴在线路上造成噪音,这些噪音又导致两端的UNIX命令获得错误的输入,并导致崩溃。频繁的崩溃使他感到惊讶—我们编写的程序不是应该十分强大吗?作为一名科学家,他想探究该问题的严重程度及其原因。因此,他为威斯康星大学麦迪逊分校的学生编写了一个编程练习,而该练习将使他的学生创建第一个模糊测试器。

这项作业的原文描述是这样的:

The goal of this project is to evaluate the robustness of various UNIX utility programs, given an unpredictable input stream. [...] First, you will build a fuzz generator. This is a program that will output a random character stream. Second, you will take the fuzz generator and use it to attack as many UNIX utilities as possible, with the goal of trying to break them.

该项目的目标是在给定不可预测的输入流的情况下评估各种UNIX实用程序的健壮性。[...]首先,您将构建一个模糊发生器。这是一个将输出随机字符流的程序。其次,您将使用模糊发生器,并使用它来攻击尽可能多的UNIX实用程序,以试图破坏它们。

这个作业在不经意间抓住了模糊测试的本质:创建随机的输入,并持续性观察它是否会破坏目标应用程序,理论上只要运行足够长的时间,我们就会看到错误的发生。

AFL(american fuzzy lop)最初由Michał Zalewski开发,和libFuzzer等一样是基于覆盖引导(Coverage-guided)的模糊测试工具,它通过记录输入样本的代码覆盖率,从而调整输入样本以提高覆盖率,增加发现漏洞的概率。其工作流程大致如下:

从源码编译程序时进行插桩,以记录代码覆盖率(Code Coverage)

选择一些输入文件,作为初始测试集加入输入队列(queue)

将队列中的文件按一定的策略进行“突变”

如果经过变异文件更新了覆盖范围,则将其保留添加到队列中

上述过程会一直循环进行,期间触发了crash的文件会被记录下来

符号执行 Symcc

符号执行简单来说是在目标程序的执行过程中跟踪中间值是如何计算的,每一个中间值都可以表示为程序输入的一个公式。在任何点,系统都会使用这个公式查看这个点是否可达,这个指针是否为空等。如果答案是确定的,那么符号执行引擎将会提供测试用例,一个新的输入例子来触发对应的行为。所以符号执行可以被方便的用来探测程序路径以及触发bug。

新的符号执行Symcc发表于去年顶会USENIX’20,论文名称为Symbolic execution with SYMCC: Don’t interpret, compile!

那么Symcc和它的前辈们又有什么不同呢?论文作者Aurélien Francillon认为传统符号执行主要分为两类:IR-based和IR-less。

IR-based是指无论测试对象如何,先把目标的二进制程序给转换到IR层(中间表达形式)再进行抽象解释,其缺点是特别容易路径爆炸。常见用此方法的符号执行有angr、KLEE和Mayhem,主要过程如下图所示:

IR-less是指符号执行引擎通过动态插桩技术(利用PIN插桩框架等)先对二进制程序插桩,执行部分指令后再构造符号表达式。其优点是快,缺点是插入的代码函数可能无法生成正确的符号表达式,且较依赖于指令集。常见用此方法的符号执行有Triton、QSYM、SAGE和Driller,主要过程如下图所示:

作者提出的SymCC不同点在于,直接在编译期就开始在生成的IR上植入符号执行相关代码,进一步提升性能;其流程大致如下:

开始结合

整体的结合流程没什么新花样,基本是按照 安装各种包环境—> 编译简单的后端/功能更强的qsym后端 —> 用symcc编译llvm的libcxx —> 开始尝试fuzz 的过程循序渐进。

安装各种环境

先安装各种包和依赖:

这里的LLVM 要求是 8, 9, 10 或者11 ,C++编译器要支持 C++17。实际安装过程中有些unbuntu版本可能无法直接apt-get,使用llvm官方https://apt.llvm.org/ 的包支持。

随后安装Z3,要求版本号大于4.5

这里有点小坑,用该方式安装的z3可能在后面编译时llvm无法找到路径。如果报此类似错误的,该步可用cmake的Ninja进行编译,指路链接:https://github.com/Z3Prover/z3/blob/master/README-CMake.md

然后安装afl,没什么可说的先安原版

下载symcc的源码做好之后编译backend的准备

编译backend

symcc带了两种后端,一种是功能简单(simple)的;另一种是qsym的后端,与前者相比功能性更强,我们两种都编译一下。在配置构建时,选项都将通过“ -D”传递给CMake,常见选项如下表所示:

选项

作用

- QSYM_BACKEND=ON/OFF (default OFF)

是否编译QSYM后端,若否即为编译simple后端;每次执行时可以使用LD_LIBRARY_PATH在后端之间切换

- TARGET_32BIT=ON/OFF (default OFF)

启用64位主机对32位编译的支持

- LLVM_DIR/LLVM_32BIT_DIR (default empty)

提供编译时llvm的位置

- Z3_DIR/Z3_32BIT_DIR (default empty)

提供编译时Z3的位置

- Z3_TRUST_SYSTEM_VERSION (default OFF)

信任系统版本的Z3,不检查Z3版本的兼容性;如果Z3的安装版本太旧,则可能发生编译错误。

首先编译简单的后端,这里的LLVM_DIR指向你所用版本llvm位置

后面在ninja check时会有8个错误,不影响后面的正常执行。(参考视频的编译过程中也有错误)

下面编译qsym的后端,与前者相比区别就是把DQSYM_BACKEND改成ON

check时也会有一些错误,问题不大。

用symcc编译llvm的libcxx

对于更加复杂的C++代码,symcc提供了两种解决方法。一种是使用系统提供的C ++标准库。这是最简单的不需要额外的编译,但是它有一个重要的缺点:会影响符号执行的过程。另一种方法是自己编译一个检测的C ++标准库,这样就可以通过库跟踪数据,但这需要构建库并针对它编译所有代码。

建立C ++标准库是一项一次性的工作,建一次后可以在所有后续的C ++编译中使用,每当我们使用libc++就会自动使用我们编译的llvm标准库实现。

编译过程如下:

请自己手动把$BASE指向之前准备工作的文件位置

开始尝试Fuzz!

这里我们准备一个特殊的苛刻例子

根据这段源码,我们可以判断出当且仅当文件输入为0xdeadbeef 时,return (int)(20 / t1)会出现除零错误,而该例子单纯使用afl是难以发现错误的。

我们分别使用qsym编译出的后端symcc和afl对其进行编译,并且创建一个样例AAAAAAA

之后就开始运行吧,我们使用afl的并行模式

这里symcc_fuzzing_helper的参数中-o指向afl的out目录,-a指向要辅助的afl进程名字,如上所示这里我就是fuzz2.

symcc_fuzzing_helper其实就是在使用afl生产的testcase进行符号执行,如果它认为样例有趣就会生成新的,并将它传送到正在执行的afl队列里,afl就能够使用该新生成样例进行测试,这一流程辅助了afl能够到达一些之前无法到达的路径。

这里有个小坑,单纯执行afl时afl-fuzz命令后面的--可带也可不带,但是symcc_fuzzing_helper是通过检测afl-fuzz里--后面命令执行的,所以如果我们在afl-fuzz后习惯性不加--就可能导致symcc无有效的输出结果。

一切准备就绪,开始运行吧!

我们惊喜的发现单纯fuzz难以找到的漏洞,在symcc_fuzzing_helper的协助下,直接就找到了crash。

简单分析一下,用Hexdump看到crash真的是0xdeadbeef,symcc辅助AFL找到了使目标程序崩溃的testcase。

总结

使用符号执行Symcc与模糊测试引擎Afl的简单验证成功了,之后可以就试一试现实中的一些项目,比如论文中提的Tcpdump之类的;还可以考虑将Symcc与其他模糊测试引擎相结合,比如Afl++,在各种算法加持下的Afl++再结合符号执行可能会有更好的效果。

最后特别感谢Symcc发明人和论文的原作者 Aurélien Francillon 与 ADALogics 的安全研究员David Korczynski,它们在推特上帮助了我很多,同时感谢Discord的Fuzzing板块讨论让我有兴趣进行各种新的尝试,我仍有很多需要学习的地方。

参考资料

带你搞懂符号执行的前世今生与最近技术

https://www.anquanke.com/post/id/231413

G.O.S.S.I.P 学术论文推荐

https://wemp.app/posts/40a16228-7a86-4985-b7c2-b3507e3fc161

Symcc源码

https://github.com/eurecom-s3/symcc/

入门afl

https://i-m.dev/posts/20191001-225746.html

linux 符号执行,[原创]符号执行Symcc与模糊测试AFL结合实践相关推荐

  1. 模糊测试-AFL学习笔记之C/C++

    目录 简介 文档 QuickStartGuide README perf_tips.txt status_screen INSTALL 安装 下载 编译 检查 例子 有源码-标准输入 源代码 编译 f ...

  2. 模糊测试+符号执行等漏洞挖掘工具安装使用

    漏洞挖掘工具 符号执行 KLEE QSYM driller+AFL symcc+AFL 模糊测试 AFL AFLGO AFL++ honggfuzz 隔离了一周,解封了随便写点东西吧 符号执行 KLE ...

  3. delphi 调用浏览器内核_HFL:基于混合模糊测试的Linux内核漏洞挖掘

    Remarks Conference: NDSS 2020 Full Paper: HFL: Hybrid Fuzzing on the Linux Kernel Summary 针对的问题: Lin ...

  4. 符号测执行软件测试,基于符号执行与模糊测试的混合测试方法

    1 引言 随着信息技术的发展, 软件已经渗透到现代社会的方方面面, 而由于开发不当引入的软件漏洞也日益增多.据统计, 最近5年内软件漏洞数增加了38%, 而仅在2016年~2017年间就增加了14%[ ...

  5. 模糊测试中的动态符号执行

    文章目录 前言 整体描述 前言 来源:Concolic Fuzzing 建议阅读原文,我这里仅仅整理下思路:fuzzing仓库 建议先阅读这篇文章:SMT简介 整体描述 AFL可以通过插桩的方式,记录 ...

  6. 在Linux上使用AFL对Stagefright进行模糊测试

    前言 模糊测试是一种自动向程序传递输入数据并监控其输出的自动化测试技术.通过这种技术,安全人员可以测试程序的可靠性以及识别潜在的安全漏洞. 我们(360成都安全响应中心)将对Stagefright M ...

  7. 模糊测试技术简单整理(一)

    模糊测试技术 2022-01-09- 文章目录 模糊测试技术 预处理 1. 插桩: 2. 符号执行 3. 污点分析 基于AFL的模糊测试方法 输入构造 评估 结果分析 具体应用场景下的模糊测试 物联网 ...

  8. AI模糊测试:下一个重大网络安全威胁

    https://www.aqniu.com/news-views/46002.html 人工智能(AI)或机器学习融入传统模糊测试技术造就出查找应用程序或系统漏洞的强大工具,但研究人员和网络罪犯都能利 ...

  9. 测试页打印失败.是否参阅打印疑难解答以获得帮助_使用DeepState对API进行模糊测试(上)...

    前言 DeepState是一个框架,它为C和c++开发人员提供了一个公共接口,用于各种符号执行和模糊引擎.用户可以使用类似于Google Test的API编写一个测试工具,然后使用多个后端执行它,而不 ...

最新文章

  1. mysql源码安装都能装什么模块_源码安装后,添加其他模块
  2. 2021年最后几天,使用SSM实现网上购物商城系统
  3. 调试技巧之 找准调试点
  4. 让Exchange 2010 (2007适用)可以收发外部邮件
  5. 算法与数据结构(2)
  6. 谈一谈flex布局使用中碰到的一些问题
  7. nemesis什么车_马力2100匹《Trion Nemesis》谜样超跑诞生中?
  8. DVWA-CSRF-low级别
  9. 【Linux】Ubuntu输入法不能开机自启的解决方法
  10. 全网首发:以管理员身份运行bat,自动切换盘符、目录的正确做法
  11. 第 7 章 Neutron - 080 - 创建第一个 local network(I)
  12. 程序员数学(0)--序言
  13. 计算机输出科学计数法,C语言里要对输出的结果用科学计数法表示保留三位有效数字应该怎么写啊?...
  14. c语言中sys是什么文件夹,windows系统中C盘的pagefile.sys是什么文件
  15. 显示行数 设置ssh终端_SSH终端命令工具:zoc7 for Mac
  16. 南安普顿大学计算机排名2019,南安普顿大学2019THE世界大学排名最新排名第118
  17. ppt 另存为 html 动画,ppt2011 for mac 可以另存为html格式吗
  18. 干货!常见waf识别
  19. 关于intellij idea的
  20. *POJ3666.Making the Grade(DP+离散化)

热门文章

  1. 贺世界智能网联汽车大会-速锐得V8翻开智能驾驶汽车新篇章
  2. a到z的ascii码值是多少_c语言 ASCLL码中 A~Z和a~z是多少
  3. pcb布局设计_PCB设计布局的重要提示
  4. hdwiki的php架构,hdwiki框架结构简要说明
  5. 微信小程序使用wxparse插件,渲染文章不换行问题
  6. 首席新媒体商学院黎想:种子用户运营方法论
  7. python getch_python – 是否可以使用getch()来获取不同长度的输入?
  8. ArcMap打不开ENVI的img格式问题解决
  9. 已有一个排好序的数组,由键盘输入一个数,要求按原来的排序规律将其插入到数组中.
  10. python plc fx5u_三菱PLC FX5U定位编程时的注意事项说明