GOSSIP_summerschool_2019_day3

Let’s GOSSIP软件安全暑期学校笔记

DAY 3: 7月22日

今日演讲主题:

  1. 嵌入式系统安全:从固件漏洞挖掘到远程设备验证 卢龙
  2. 模糊测试不再模糊——自动漏洞挖掘方法探秘 张超

Embedded System Security: from vulnerability discovery to remote attestation 卢龙

Software security: a quick tour

  • Memory Corruption
    • 从空间上划分:老生常谈的栈溢出、堆溢出

    • 从时间上:UAF

    • data only attack?构造恶意数据?

  • Logic flaws
  • 利用
  • 远古时期:代码注入 shellcode
  • 代码复用:ret2libc、ROP
  • Data only attack:难度更高、在内存中改变一部分数据(还是需要任意地址写?)

​ - “Golden bit” flip:

  • 防御

Embedded System: a brief intro

嵌入式系统分类
Architectures
  • Von-Neumann体系结构与Harvard体系结构

    • 冯诺伊曼体系结构内存中数据与代码不分离,在cache中分离

    • 哈佛 内存中数据与代码分离

  • CISC 与 RISC

  • 微控制器MCU

    • Intel: 8051, Quark, Intel-64

    • MIPS

    • PowerPC

    • ARM: Contex-M

  • Embedded Software Stack

    • Bootloader

    • System software: OS-based VS bare metal

​ - Linux

​ - C runtime: glibc, uClib, dietlibc

​ - Command: busybox

​ - Filesystem: inittramfs, cramfs, jffs2…

  • Peripheral drivers 外设驱动
  • Security (or insecurity)

    • Secure Booting

​ - 从TPM逐层验证,证书存在TPM里面

  • Memory Protection

​ - MPU (Optional)

​ - Regions

​ - Permission: XN 数据不执行, AP Access Permission

​ - Subregions

Attacks & Defenses on Embedded

  • Attacks
  • Defenses

    • Network level

​ - Firewall

​ - IDS/IPS

  • System/host level

​ - Event monitoring

​ - Policy enforcement

​ - Program hardening

​ - Vulnerability detection

​ - Attestation and Verification

  • 开放问题嵌入式系统中待解决的问题

Embedded Vulnerability Discovery

常用方法:fuzz、静态分析

fuzz应用在嵌入式系统中存在的问题:模拟器不好运行(需要真实设备)、路径不能达到、不好检测错误发生

启发式的Automatic Emulator Generation。(无法反调试、与厂商合作)

  • 与现在常见的Fuzz结合起来

  • 自动化识别固件

Remote Device Attestation

验证远端设备完整性

目前的检测方法只能静态检测代码、数据

解决:

检测控制流、数据流

云端控制器遇到的问题:如何信任发来的数据,未被更改

  • 两重验证:

    • Operation-scoped CFI

    • Critical value integrity

总结

嵌入式系统在未来仍有很长的前景、应用范围很广。一个问题解决后要考虑有多少的价值(多少人care这个解决方案、是否能够在现实中使用)

花了很长时间介绍前置知识,从11:25才开始介绍其研究的工作,没有深入讲解。

能够物理接触嵌入式设备,能够直接读取储存器。在软件上缓解:嵌入式系统中的输入更加多样化、可以接受模拟信号,模拟器不好模拟。(可以使用这些的特点进行缓解)


模糊测试不再模糊 张超

Fuzzing Base

发现漏洞:

  • 人工审计(10%)

  • 学术界:静态分析、动态分析、污点分析、符号执行、模型检验

  • Fuzzing(80%?)

Random Fuzz:简单、覆盖率极低

目前的两大类:

  • generation-based:根据输入的语法进行生成输入

  • Mutation-based:基于变异的,从以前的测试例,通过进化算法。需要种子输入

对比:

image-20190722140842030

Mutation-based存在的问题:覆盖率、约束

如何提高代码覆盖率

coverage-guided fuzzing

AFL Basics

image-20190722141113038

test and track中检测覆盖率,并将覆盖率作为指标,来决定是否将种子留下来。

AFL通过bitmap记录边覆盖率。

实现细节:

track code coverage

  • solution 1: 动态插桩,执行引擎插桩,比较慢,可能带来十倍的开销
  • solution 2: 让目标程序自己记录,静态插桩(AFL)

gcc_mode、llvm_mode、qemu_mode

image-20190722142523777

实现:

image-20190722142740711

AFL只记录了边,没考虑覆盖边的顺序(路径)。

共享内存,共享bitmap


Fuzz 进行决策:

virgin_bits 八个bit: 2^0,2^1…2^7

*virgin = vir & ~cur

为了循环次数,很多情况与循环有关。


Fast:fork and execve

dumb_mode: fork and execve

输入输出使用管道

image-20190722144200431

waitpid等待完成,再进行bitmap的比较

Faster: forkserver

省掉了execve的时间

image-20190722144450392

输入:通过cmd pipe,forkserver再fork


Faster: persistent mode

省去fork的时间,使用大循环,仅对少量循环程序适用。

前后数据会进行干扰。

在循环开始做快照,结束后恢复。


Faster: Parallel Mode

并行模式,多个fuzz协作,种子池共享。

image-20190722145316450


Sensitive: catch potential bugs

Securityity violations:

  • AddressSanitizer

image-20190722145715710

Our Solutions

CollAFL

控制流敏感的AFL

AFL存在的问题

  • AFL使用64KB bitmap来记录访问过的边,可能会发生碰撞。可能会造成:

    • 浪费好的种子

    • 浪费unique crashes

    • 覆盖率记录得不精确

  • 并没有利用好边覆盖率的信息

    • 仅用来选种子

    • 如何选seed使得覆盖率上升更快

路径覆盖率:存储代价很大、runtime代价很大,无法实现


CollAFL:
消除碰撞:

Naive solution: 扩大bitmap容量,性能下降很厉害(cache miss访存消耗大量时间)

替换hash算法:

image-20190722152615438

为所有基本块搜索xyz,以便避免hash碰撞。但是越往后越难搜索xyz。

优化

  • 不是所有边都需要计算hash,基本块的入度为1时,执行该基本块即可确定刚执行的边。超过一半的基本块入度为1。
  • 空间换时间,找不到xyz时,静态赋一个hash,运行时查表查hash

image-20190722153209671

优化结果 三种情况:

多前驱(找hash)、多前驱(查表)、单前驱

image-20190722153543823

结果:稍微扩大bitmap、消除碰撞。


Coverage-first seed selection

策略:

  • 一个种子没测试过的分支比较多,它可能提升代码覆盖率比较快。

  • 更多的内存访问数量


GREYONE:数据流敏感Fuzz

隐式数据传递/依赖

What types of data-flow features?

  • Taint attributes 污点数据

  • Branch value conformance 分支值的一致性

解决的问题:

image-20190722160923591


三个问题:

image-20190722155229509


RQ1-1: Taint Attributes

传统动态污点分析:

  • Libdft/DFSan…

  • Propagate taint inst by inst

  • Taint rules manually/automatically

  • Under-Taint and over-taint issues

比如xor eax, eax,应该是清除污点标记

隐式数据流依赖,认为是依赖:依赖急剧扩散;不是:漏掉

基于Fuzzing驱动的污点分析 Fuzzing-driven Taint Inference(FTI)
  • Inference rule:

    • 输入输出同时发生变化,说明输出是依赖输入的

    • 改变第i个字节,发现输出发生变化,说明依赖第i个字节。

  • Taint Inference:

    • AFL会逐字节进行变异,对变量进行监控

Comparison

  • 更快

  • 不需要手动设置规则

  • 不会出现误标记 没有over taint

  • 可能会出现真正的污点变量无标记


RQ1-2: Constraint Conformance

对分支语句做插桩,计算vlaue的一致性


RQ2: taint-guided mutation

先对字节的重要性进行排序,看其会影响多少变量

对边的权重进行计算

以权重最高的边做为目标,进行变异

image-20190722161209915

image-20190722161222751


RQ3: Conformance-guided evolution

the higher conformance, the better

将种子池进行改变,链表中节点为一组路径相同、全局一致性相同、某一分支一致性不同的种子:

image-20190722161531645

  1. 新的路径

  2. 更高的全局一致性,替换原来的

  3. 全局一致性相同,某一分支一致性不同,加入

因此能够更快的将好的种子选取出来。


具体效果:效果很好,发现了很多CVE。。。

Other Research Work

初始种子的选择

  • 通过神经网络

    • Neuzz(Oakland 19)值得一看。提高代码覆盖率,增加bitmap多样性。通过输出进行反推,送给神经网络。

    • image-20190722163011888

  • 通过符号执行辅助

    • image-20190722163952377
  • 选种子

    • AFLfast:多选冷种子、冷路径,认为每个种子贡献相近,选择多的种子已经发现得差不多了

    • image-20190722164004307

  • 编译策略
  • 通过AI帮助变异

  • image-20190722164153935

  • 更快的测试
  • image-20190722164322657
  • 安全性方面
  • image-20190722164333775

目前仍存在的一些问题:

涉及网络、复杂协议、UI界面、复杂状态机,对浏览器、kernel、driver大型目标怎么测

Q&A:

Fuzz的一些标准:CCS18的Fuzz 建议

Fuzz数据集

image-20190722164812607

总结

收获很大,对AFL有了更深入的了解。GreyOne中实现Data-flow sensitive的方式令我眼前一亮:通过fuzz来标记污点变量,可能对现在项目有所帮助。

前沿领域,越来越多使用机器学习来帮助fuzz进行seed的生成等操作,可能以后会更加常见,也值得一读通过机器学习来帮助fuzz的那篇ccs18的论文。