【bsauce读论文】MoonShine:Optimizing OS Fuzzer Seed Selection with Trace Distillation-USENUX2018

摘要

    问题:现有OS Fuzzer的效率受到种子程序中syscall序列的质量和多样性的影响,种子程序中各个syscall之间可能存在相互依赖的关系(每个syscall的行为依赖于之前的syscall所创建的内核状态),仅仅依靠人工定义的规则来生成有效syscall序列非常耗时耗力,且代码覆盖率有限。

    目标:从真实程序中提取有效的syscall序列作为OS fuzzer的种子,同时保持较高的覆盖率。

    方法:轻型静态分析—distillation算法,有效检测不同syscall之间的依赖关系。作为Syzkaller的扩展

    结果:从3220个包含280万syscall的真实程序中,提取出3195个trace,syscall数目减少到14000个,但仍然保持了86%的原始路径覆盖率。将syzkaller的代码覆盖率提高了13%;发现17个漏洞。

    缺点:只能从已有路径中探索,不能变异生成畸形调用序列。是否能找到调用之间的参数依赖图,这样变异效率更高。

1.Introduction

总体步骤

         执行真实程序—>收集syscall序列+每个syscall覆盖信息—>选取覆盖大的syscall,静态分析识别依赖关系—>分组形成种子程序。


Fig3-MoonShine总体流程

贡献

         a.提出seed distillation(保持依赖关系,实现代码覆盖)。

         b.用轻型静态分析实现高效的seed distillation算法。

         c.实现MoonShine,帮助Syzkaller提高代码覆盖,发现17个漏洞。

2.Overview

2.1 问题描述

    人工定义调用规则:扩展性不强。

    最小化策略—afl-tmin[12]:动态移除输入的部分字节,而不影响覆盖率。但无法处理调用序列,syscall之间依赖关系很复杂。

    解决方法:从真实程序中提取trace,因为真实程序的syscall序列一般满足call之间调用依赖。新问题是真实程序的syscall序列过长,不能直接作为种子程序,要想缩短trace,动态分析的开销很大。

    依赖类型

        (1)显式依赖:参数来自其他syscall的输出。见Fig1,mmap()的第3参数来自open()的返回值。

        (2)隐式依赖:控制流影响,某些syscall内部修改了内存共享变量(共享数据结构),从而影响其他syscall的执行流。见Fig1-2,mlockall()设置的变量vma->vmflags影响了msync()的执行流。

2.2案例分析

见Fig1。

(1)识别显式依赖

         首先识别出覆盖率贡献最大的syscall,如mmap,msync,write。识别其中的显式依赖,如对mmap,遍历每个参数,搜索该参数是之前哪个syscall的返回值。

(2)识别隐式依赖

         如对msync,检查执行时是否在条件语句中用了之前syscall设置的结构变量。msync在条件语句中读取vma_struct->vma_flags,mlockall在赋值语句中写vma_struct->vma_flags。


Fig1—Distillation案例
Fig2—隐式依赖案例

3.方法

(1)Seed distillation算法

见Algorithm1。

Algorithm1—seed distillation算法 - 笔记

(2)显式依赖算法

         见Algorithm2。

定义

        依赖图:结果节点+参数节点。

        结果节点r:返回值+返回值类型+生成返回值的syscall。

        参数节点a:参数+参数类型+使用该参数的syscall。

        a->r边:参数a依赖产生r的syscall。

方法:Mooshine解析Trace来构造依赖图,通过依赖图来检测显/隐式依赖关系。

显式依赖

        对每个syscall的返回值,构造结果节点加入到结果map,用组合key(type,value)索引;对每个syscall的参数,检查结果map,若有匹配的结果节点,则添加一条边。构建好参数依赖图后,对给定call c,遍历c的参数,访问依赖图中对应的参数节点,标记c与该参数节点指向的结果节点为显式依赖。

(3)隐式依赖算法

         Read dependency:调用c在条件语句中读取全局变量v。

         Write dependency:调用c写全局变量v。

         定义隐式依赖:调用c_a的写依赖与c_b的读依赖交集不为空,则c_a是c_b的隐式依赖。

         方法:利用静态控制流分析,得到读/写依赖,对指定syscall c,记录每个条件语句的全局变量读和一元赋值语句的全局变量写。

         问题:过依赖—全局变量设置为特定值才会影响其他syscall执行流;欠依赖:别名-全局变量。


Algorithm2-显式隐式依赖算法 - 笔记

4.实现

总体:Trace Generation + Seed Selection。

(1)内核插桩

         Kcov[38]内核插桩—设置CONFIG_KOV标记。

         检测bug—gcc sanitizer:KASAN[18],UBSAN[14]。

         其他detector:死锁检测;内存泄露KMEMLEAK[5]。

(2)Tracer

         扩展Strace[13]—通用syscall tracer:检测syscall名称,参数,返回值,能跟踪到fork/exec内部。给Strace添加455行代码+3个文件,用-k选项执行。

(3)多进程Trace

         进程树:node—存call trace;edge—父子关系。

         跨进程找显式依赖,确保父进程在clone之前把值存入cache。

(4)显式依赖

         存在3种例外:syscall参数自己返回结果,如pipe;内存分配syscall如mmap,依赖返回值确定的调用空间,只要落在这个地址空间内都算显式依赖;不同种子程序之间有依赖,则整合为1个。

(5)隐式依赖

         基于Smatch[16]—针对c的静态分析框架,进行控制流分析;能够在smatch遍历程序的AST时根据相应事件触发相应的注册函数。

         方法:在判断条件处Hook,检测read依赖;在一元赋值处Hook,检测Write依赖。


5.测试

5.1 环境准备

     种子程序(获取Trace):

                    a.Linux Testing Project (LTP) [7]

                    b.Linux Kernel selftests (kselftests) [6]

                    c.Open Posix Tests [8]

                    d.Glibc Testsuite [3]

    OS Fuzzer—syzkaller。

    提取算法:MoonShine(I+E)—显式/隐式;MoonShine(E)—显式;RANDOM—不考虑依赖。

5.2 漏洞检测能力

         MoonShine(I+E)发现17个漏洞;MoonShine(E)发现7个。10/17个是竞争漏洞,都在文件/网络子系统中。见Table1。

5.3代码覆盖率

         MoonShine(I+E)发现53270个基本块;MoonShine(E)发现51920个基本块;RANDOM发现47320个基本块。帮助syzkaller把代码覆盖率提高了13%。

5.4 提取trace有效性

         3220条trace包含290万个syscall,提取过后的种子只包含16442个syscall,保留了86%覆盖率。

5.5 高效性

         80min内收集和提取了110千兆(十亿)字节的trace。

6.讨论

6.1 不足

(1)不能识别线程/进程之间的依赖:只能识别同一个线程或父进程产生的依赖关系。

(2)静态分析的误报率较高:一是错误识别为隐式依赖,使trace过长;二是指针分析不准确,若两个syscall同时读写了一个struct,MoonShine不能判断是否对应的指针引用了相同的struct,例如mlock和munmap都引用了vma struct,但vma由传入的第一个参数指针决定,若传入指针不同,则没有依赖,而MoonShine每次都判定有隐式依赖。

6.2 未来方向

(1)支持其他内核fuzzer

         例如Digtool[29],kAFL[33]。基于虚拟化的动态方法能更准确的识别隐式依赖,当然性能开销更大。

(2)fuzz设备驱动

         本文目标是linux内核,如文件系统、内存管理、网络,但设备驱动占linux源码超过40%。


参考:跟着白泽读paper丨MoonShine: Optimizing OS Fuzzer Seed... - 简书

推荐阅读更多精彩内容

  • MoonShine: Optimizing OS Fuzzer Seed Selection with Trace...
    复旦白泽战队阅读 300评论 0 0
  • 官网 中文版本 好的网站 Content-type: text/htmlBASH Section: User ...
    不排版阅读 2,373评论 0 5
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 7,254评论 1 24
  • feisky云计算、虚拟化与Linux技术笔记posts - 1014, comments - 298, trac...
    不排版阅读 2,659评论 0 5
  • 加入写作群第三周,先不提写作水平,单说“坚持”自己都没有做到,坚持了一周,错过了一周。大部分不“坚持”的人可能都会...
    0呆_呆0阅读 32评论 1 0