作者: Flanker
原文链接:https://mp.weixin.qq.com/s/G26MJOH4VPene1Sd_zjEQw
本文拨开二进制Fuzzing的迷雾为Fuzzing战争系列的第二篇,也是Fuzzing战争:从刀剑弓斧到星球大战的续篇。
每个人都期待有全图点亮的体验,然而现实中安全研究的目标却更多是编译好的二进制binary而没有源码。迷雾之下崇山峻岭羊肠小道,但应许之地却往往也隐藏其中。本文将以目前最为主流的Android on ARM/AARCH64为例,综合笔者在 MOSEC 2020 和 RWCTF Tech Forum 2021 的演讲内容,首次系统性地阐述如何实现无源码情况下的大规模Coverage-Guided Fuzzing理论、工程和实践,和小试牛刀即发现的主流移动终端中广泛存在的真实漏洞。出于阅读体验,本篇可能会分多次发出,持续更新中。
Let's rock n' roll !
就像简陋的纸带机模型却能描述出完备的图灵机一样,一个五行的bash脚本甚至也可以成为fuzzer,当然作为一个dumb fuzzer,直到宇宙毁灭,它也不一定能发现一个漏洞。
现代Fuzzing技术以样本为驱动,论Coverage Feedback为核心,取遗传算法为理论。获取Coverage的办法主要有三种:
相比于传统的Grammar Fuzzer, CGF Fuzzer在每轮变异样本的输入运行后,会评估该样本是否触及了更多的代码块,从而决定是否保留它进而进行更深度的变异,从而自动构建输入样本的格式。以AFL为例,在x86形式下,其核心插桩代码逻辑如下所描述:
cur_location = <COMPILE_TIME_RANDOM>; shared_mem[cur_location ^ prev_location]++; prev_location = cur_location >> 1;
在有源码的情况下,基于编译器工具链的支持,我们可以很容易地在编译过程中实现以上的变更。
但更多的时候,房间里会有这么一些闭源的大象:
引入注目却大部分时间让人束手无策,也少见对这方面的研究和成功实践。公开的文献中对此类目标仍然是dumb fuzz居多,
这前朝Fuzzer的剑,就斩不了本朝的binary target了么?
为了解决这个问题,我们首先需要确定在无源码情况下应当如何收集Coverage。ELF/MachO的Static Rewrite和Dynamic Tracing是我们可能的选项,那他们分别是什么,对于实际环境下的目标又应当如何选择?是996,还是11116?
Static Rewrite基于Disassembling 和 Static Patching。目标ELF/MachO/PE首先被汇编后,根据其Control Flow提取出Basic Block。类似于孙悟空复制出六小龄童一样,我们可以在Basic Block的edge处插入希望被执行的指令,进而获得一个新的binary,也就是所谓的rewrite
。AFL-DynInst
和e9patch
是其中的典型案例,例如AFL-DynInst
的做法即是
.. inserting callbacks for each basic block and an initialization callback either at _init or at specified entry point ..
它的优点非常明显:对于实现较好的rewrite,目标binary在性能上具有巨大的优势。但同样地缺点也非常明显,魔鬼在于细节。
当然,随着ARM工作站的逐渐普及(特别是苹果M1芯片的搅局),这个状况后面可能会有所改观。但目前M1芯片的Mac产品仍不支持直接运行Android Binary (Kernel和linker不同导致),这也是笔者后续所关注和研究的方向。
相对于静态编辑技术,Dynamic Tracing着力于运行时获取coverage信息。这也通常会有两种实现方式:
QEMU通过Translated Block
的方式提供动态二进制翻译。我们知道,任何计算机科学技术中的问题都能通过添加中间层解决,QEMU定义了TCG (Tiny Code Generator)
的概念作为IR中间语言,任何前端目标语言指令都会被统一翻译为标准Ops后,再通过后端的解释器翻译为Host Machine的Target Code。
在QEMU执行目标程序时,根据指令位置查询到对应已翻译的TB会被直接执行,而未翻译的TB则会被进行实时翻译,并链入缓存序列中,如下图所示:
这种JIT的方式给了我们操作的空间,一种简单的思路是与tb挂钩,在tb_find_slow
中直接挂钩记录当前的pc值并传递给AFL,如下图所示:
但显然这个初步的方法有很大的优化空间:
tb_find_slow
中进行记录意味着必须要禁用block chain caching,也就是说每一个block都需要跳回dispatcher查询是否被翻译过。这带来了巨大的性能回退。 针对这两个问题,abiondo
等提出了如下的解决方案:
就像计算产业的速度曾经被摩尔定律所主导,但当摩尔定律主频这个柠檬的汁被榨干之后,人们转向分布式计算和专用芯片(FPGA)。在穷尽当前系统性的措施之后,我们仍可以借用专用计算的概念来优化Fuzzer,也就是说
如果我们关心的只是特定的代码片段,我们是否仍需要模拟整个完整的Runtime环境?
笔者在MOSEC 2020上介绍的基于Unicorn框架
实现的DroidCorn
即是基于这个理念编写的改进版执行框架。它的结构如下图所示:
相比于QEMU-usermode
,DroidCorn在如下方面进行了重写,并最终初步获得了约30%的性能提升。
这套框架完成了笔者在x86工作站和服务器Linux环境下运行和fuzz ARM binary的目标,在摆脱了物理移动设备的限制之后,我们可以轻松地对其进行大规模并发Fuzz,开拓前人所未到达之领地,发现前人所未发现之漏洞。
当QEMU以上的优化做到极致,我们可能就要考虑优化QEMU本身了。在预先控制流解析的支持下,JIT编译是否可以被替换为AOT编译,就像从Dalvik到ART runtime?这是一个开放性的话题,请读者自行思考。
以上介绍了binary fuzzing技术的现状和笔者的思考、探索和实践。在接下来的文章中我们将进入实战环节,针对数亿移动手机中所广泛内置默认使用的闭源图片解析库进行fuzz,并分析发现的数十个远程内存破坏漏洞,i.e. CVE-2020-12751, CVE-2020-25278, CVE-2020-12751, CVE-2021-22493。敬请期待。
本文所对应的RWCTF 2021 Tech Forum上分享的PPT可以在 https://speakerdeck.com/flankerhqd/blowing-the-cover-of-android-binary-fuzzing查阅。
https://github.com/lunixbochs/usercorn
https://github.com/AeonLucid/AndroidNativeEmu
https://github.com/AFLplusplus/AFLplusplus
https://github.com/Battelle/afl-unicorn
https://abiondo.me/2018/09/21/improving-afl-qemu-mode
https://github.com/andreafioraldi/qasan
https://gts3.org/~wen/assets/papers/xu:os-fuzz.pdf
数十年前因特网的蛮荒时代,ARPA的先贤们曾满怀信念,希望能建立一个田园牧歌的大同世界,Richard Stallman至今仍在为了看似疯癫的信念而奔走呼号。曾经我们以为这个梦想已经越来越近,但撕裂的地缘政治和残酷的资本迅速消灭了所有的幻想。
曾经的程序员(我更愿意称为计算机工程师和科学家)是极客,是创作者,是艺术家。开源社区的蓬勃发展是他们灵感的碰撞,才华的闪光,成千上万人智慧的结晶。但很不幸的是,创作的果实被贪婪地资本所攫取,they are taker not giver,开源驱动的基础架构技术发展和完善让手艺人异化成了流水工。精妙的计算科学变成了CRUD的堆需求,严谨的数学计算被7*24
人肉盯盘取代,每一个电脑配一个人,看是电脑还是人先crash。先贤图灵和冯诺依曼们若泉下有知,是否会预料到今天的局面?
愿每个人都能有时间看看天空,再次引述下天才黑客GeoHot的一句话:I want power, not power over people, but power over nature and the destiny of technology. I just want to know how the things work.
愿我们仍能记住这段话:
Computer science is the study of algorithmic processes, computational machines and computation itself. As a discipline, computer science spans a range of topics from theoretical studies of algorithms, computation and information to the practical issues of implementing computational systems in hardware and software.
本文由 Seebug Paper 发布,如需转载请注明来源。本文地址:https://paper.seebug.org/1465/