Coverage-based Greybox Fuzzing as Markov Chain

这篇具有很好参考价值的文章主要介绍了Coverage-based Greybox Fuzzing as Markov Chain。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

AFLFast: Coverage-based Greybox Fuzzing as Markov Chain

一、论文阅读

论文来自CCS2016

作者:Marcel Böhme 模糊测试领域巨佬

Abstract

基于覆盖的灰盒模糊测试 Coverage-based Greybox Fuzzing (CGF)。大多数测试用例执行少数高频路径,制定策略倾向于低频路径,使用马尔科夫链模型解释了CGF,该模型指出了执行路径 i 的种子产生覆盖路径 j 的测试用例的概率。每个种子都有能量,即从该种子产生的测试用例数量。如果每次被选择的种子的能量与固定分布的密度成反比并且单调递增

1. Introduction

  • 利用马尔科夫链模型解释了AFL的挑战以及AFLFast的卓越性。
  • 引入并评估了几种控制种子产生测试用例数量的策略,在相同时间内执行更多低频路径
  • 设计并评估了几种控制种子选择的策略
  • 实现了AFLFast并开源 https://github.com/mboehme/aflfast

2. Background

2.1 Covera-based Greybox Fuzzing
2.2 Markov Chain

https://blog.csdn.net/weixin_42437114/article/details/120935992

马尔可夫链是从从一个状态转换为另一个状态的随机过程,在任意时间,只能处于一个状态。状态集合被称为状态空间。从一个状态转移到另一个状态的概率被称为转移概率,转移概率只和前一状态有关。

3. Markov Chain Model

作者认为模糊器如果专注于马尔可夫链的低密度区域将会执行更多路径。所以作者的目标是更多访问位于平稳分布中的低密度区域的状态,更少访问位于平稳分布中的高密度区域的状态。

3.1 Coverage-based Fuzzing as Markov Chain

模糊器发现路径的序列可以由马尔可夫链描述,转移概率 p i , j p_{i,j} pi,j 为执行路径i的种子变异出执行路径j的测试用例的概率,但不是时间齐次的,即不同时间 p i , j p_{i,j} pi,j可能不同。这不能保证平稳分布存在。

时间齐次模型。给定种子集T,S+为种子发现的路径集合,S-为测试用例发现路径集合。马尔可夫链的状态空间为 S = S + ⋃ S − S=S^+ \bigcup S^- S=S+S

转移概率 p i , j p_{i,j} pi,j 定义如下:如果 i ∈ S + i \in S^+ iS+ p i , j p_{i,j} pi,j 为执行路径i的种子变异出执行路径j的测试用例的概率;如果 i ∈ S − i \in S^- iS ,则 p i , i = 1 − ∑ t j ∈ T p j , i p_{i,i}=1-\sum_{t_j\in T}p_{j,i} pi,i=1tjTpj,i ,并且对于所有的 t j ∈ T t_j\in T tjT p i , j = p j , i p_{i,j}=p_{j,i} pi,j=pj,i。即作者做了两个假设:执行路径i的种子变异出执行路径j的测试用例的概率和执行路径j的种子变异出执行路径i的测试用例的概率相同; i ∈ S − i \in S^- iS没有其它未被发现的邻居。

马尔可夫链的平稳分布 π \pi π简言之就是当步数N(应该指转移次数)趋于无限大时,停留在状态i占比。占比大于算术平均值为高密度区域,低于算术平均值为低密度区域。

能量为一个种子生成的测试用例数量,某个状态的能量由预先定义的能量调度决定。

Coverage-based Greybox Fuzzing as Markov Chain

10%的路径有1000至100000个测试用例执行,而30%的路径只有一个测试用例执行。

这样的马尔可夫链是快速收敛的,根据平稳分布,不论初始时是哪一类种子都将有更高的概率执行高频路径,

3.2 Running Example
void crashme(char* s){
    if (s[0] == ’b’)
        if (s[1] == ’a’)
            if (s[2] == ’d’)
                if (s[3] ==!)
                    abort();
}

上面的代码有五条路径,马尔可夫链如下:

Coverage-based Greybox Fuzzing as Markov Chain

每次变异一个字符,选择某个字符的概率为1/4(2-2),变异为28个字符集中的一个,变异成某个字符的概率为2-8。剩下的就很好理解了。

3.3 Challenges of Coverage-based Fuzzers

Coverage-based Greybox Fuzzing as Markov Chain

上图AFL的能量分配示例,假设从字符串“ball”开始,每个种子的能量为 29

则根据上面的状态转移概率,将会有1/4的概率执行****即27,1/4的概率执行b***,即27,1/2的概率执行ba**,即2·27。根据AFL的种子选择策略,按照添加进队列的顺序选择种子进行fuzz。接下来分别fuzz **** 和 b***,则执行各个路径的能量累加即为上图第二行和第三行。

4. Boosting Greybox Fuzzing

文中提出了单调的能量调度方案,首先为种子分配较低的能量,随后当每个种子被选择时单调递增。此外,能量分配和平稳分配的密度成反比。

为了分配更多能量给低密度区的状态,设计了种子选择策略,优先选择最少被选择的种子或是最少被测试用例执行的种子。

4.1 Power Schedules

p ( i ) p(i) p(i) fuzz执行路径i的种子t时分配给其的能量, p ( i ) p(i) p(i)是关于种子被选择次数 s ( i ) s(i) s(i)和执行路径i的测试用例数量 f ( i ) f(i) f(i)的函数。事实上 f ( i ) f(i) f(i)用作分布密度的近似值。

  • exploer模式

p ( i ) = α ( i ) β p(i)={\alpha (i) \over \beta} p(i)=βα(i)

  • coe模式,不fuzz高频路径,只fuzz低频路径,慢慢地高频路径会变为低频路径

p ( i ) = { 0 , i f   f ( i ) > μ m i n ( α ( i ) β ⋅ 2 s ( i ) , M ) , o t h e r w i s e p(i)= \begin{cases} 0, & if \ f(i)>\mu\\ min({\alpha (i) \over \beta}·2^{s(i)}, M), & otherwise \end{cases} p(i)={0,min(βα(i)2s(i),M),if f(i)>μotherwise

其中 μ \mu μ是队列中所有种子的执行路径的平均执行频率,M 为上限
μ = ∑ i ∈ S + f ( i ) ∣ S + ∣ \mu={\sum_{i \in S^+ }f(i) \over \lvert S^+\rvert} μ=S+iS+f(i)

  • fast模式,coe模式的扩展,小于 μ \mu μ 时,能量与 f ( i ) f(i) f(i) 成反比

p ( i ) = m i n ( α ( i ) β ⋅ 2 s ( i ) f ( i ) , M ) p(i)={min({\alpha (i) \over \beta}·{2^{s(i)} \over f(i)}}, M) p(i)=min(βα(i)f(i)2s(i),M)

  • linear模式,与fast模式类似,能量由指数增长变为线性增长

p ( i ) = m i n ( α ( i ) β ⋅ s ( i ) f ( i ) , M ) p(i)={min({\alpha (i) \over \beta}·{s(i) \over f(i)}}, M) p(i)=min(βα(i)f(i)s(i),M)

  • quad模式,平方

x p ( i ) = m i n ( α ( i ) β ⋅ s ( i ) 2 f ( i ) , M ) xp(i)={min({\alpha (i) \over \beta}·{s(i)^2 \over f(i)}}, M) xp(i)=min(βα(i)f(i)s(i)2,M)

4.2 Search Strategies

s(i)优先,被fuzz次数少的种子优先

f(i)优先,执行路径i的测试用例数量少的优先

4.3 Implementation of AFLFast

AFL根据种子的执行速度、覆盖以及生成时间决定分配的能量,AFLFast的五种模式中都保持了这一策略。

AFL中,第一次被fuzz的种子执行确定性变异,而AFLFast一开始分配给种子的能量较低,所以当分配的能量符合确定性变异需要的能量时才执行确定性变异。

此外,AFL首先计算出种子的能量,在本轮fuzz该种子的过程中如果发现了interesting的测试用例,会增加该种子本轮的能量,AFLFast禁用了该功能。

在标记favored时,对于每一条边,AFL选择最小最快的。AFLFast首先标记覆盖这条边并且被fuzz次数最少的种子(源码中未体现),如果存在多个,则标记执行了 被最少数量的测试用例执行的路径f(i) 的种子,如果仍然有多个,才选择最小最快的。

在种子选择时,AFL中离当前种子最近的下一个favored种子将会被选择(即按照队列中的顺序)。AFLFast中选择s(i)最小的,如果有多个,选择f(i) 最小的。(源码中未体现)

5. Evaluation

作者根据cksum判断路径是否相同,并实现了一个哈希表(cksum(i), f(i)),

分别讨论了每种能量分配模式以及每种种子选择策略的效果

总的来说,fast模式的调度策略效果最好。

二、源码分析

1. 新增参数选项

分别对应五种能量调度模式,第三个是AFL默认的能量调度

  • -p fast
  • -p coe
  • -p exploit
  • -p lin
  • -p quad
  • -p explore

2. 一些变量

fuzz_level:种子被fuzz的次数,即 s(i)

n_fuzz:该种子执行路径的执行频率(换言之,该种子执行路径被多少测试用例执行过)文章来源地址https://www.toymoban.com/news/detail-400224.html

3. calculate_score

static u32 calculate_score(struct queue_entry* q) {

  u32 avg_exec_us = total_cal_us / total_cal_cycles;
  u32 avg_bitmap_size = total_bitmap_size / total_bitmap_entries;
  u32 perf_score = 100;

  /* Adjust score based on execution speed of this path, compared to the
     global average. Multiplier ranges from 0.1x to 3x. Fast inputs are
     less expensive to fuzz, so we're giving them more air time. */

  if (q->exec_us * 0.1 > avg_exec_us) perf_score = 10;
  else if (q->exec_us * 0.25 > avg_exec_us) perf_score = 25;
  else if (q->exec_us * 0.5 > avg_exec_us) perf_score = 50;
  else if (q->exec_us * 0.75 > avg_exec_us) perf_score = 75;
  else if (q->exec_us * 4 < avg_exec_us) perf_score = 300;
  else if (q->exec_us * 3 < avg_exec_us) perf_score = 200;
  else if (q->exec_us * 2 < avg_exec_us) perf_score = 150;

  /* Adjust score based on bitmap size. The working theory is that better
     coverage translates to better targets. Multiplier from 0.25x to 3x. */

  if (q->bitmap_size * 0.3 > avg_bitmap_size) perf_score *= 3;
  else if (q->bitmap_size * 0.5 > avg_bitmap_size) perf_score *= 2;
  else if (q->bitmap_size * 0.75 > avg_bitmap_size) perf_score *= 1.5;
  else if (q->bitmap_size * 3 < avg_bitmap_size) perf_score *= 0.25;
  else if (q->bitmap_size * 2 < avg_bitmap_size) perf_score *= 0.5;
  else if (q->bitmap_size * 1.5 < avg_bitmap_size) perf_score *= 0.75;

  /* Adjust score based on handicap. Handicap is proportional to how late
     in the game we learned about this path. Latecomers are allowed to run
     for a bit longer until they catch up with the rest. */

  if (q->handicap >= 4) {

    perf_score *= 4;
    q->handicap -= 4;

  } else if (q->handicap) {

    perf_score *= 2;
    q->handicap--;

  }

  /* Final adjustment based on input depth, under the assumption that fuzzing
     deeper test cases is more likely to reveal stuff that can't be
     discovered with traditional fuzzers. */

  switch (q->depth) {

    case 0 ... 3:   break;
    case 4 ... 7:   perf_score *= 2; break;
    case 8 ... 13:  perf_score *= 3; break;
    case 14 ... 25: perf_score *= 4; break;
    default:        perf_score *= 5;

  }
    
  // 以上为AFL默认能量调度策略,即论文中的 alpha

  u64 fuzz = q->n_fuzz;	// 路径频率
  u64 fuzz_total;	

  u32 n_paths, fuzz_mu;
  u32 factor = 1;	// 公式中的右半部分

  switch (schedule) {

    case EXPLORE: 
      break;

    case EXPLOIT:
      factor = MAX_FACTOR;	// 默认策略
      break;

    case COE:
      fuzz_total = 0;
      n_paths = 0;

      struct queue_entry *queue_it = queue;	
      while (queue_it) {	// 统计所有种子的路径执行频率,这里不会重复统计,因为加入队列的种子都是执行不同路径的
        fuzz_total += queue_it->n_fuzz;
        n_paths ++;	// 种子数量
        queue_it = queue_it->next;
      }

      fuzz_mu = fuzz_total / n_paths;	// 求mu
      if (fuzz <= fuzz_mu) {	// 低频路径
        if (q->fuzz_level < 16)
          factor = ((u32) (1 << q->fuzz_level));
        else 
          factor = MAX_FACTOR;	// MAX_FACTOR 即论文中的M
      } else {	// 高频路径
        factor = 0;
      }
      break;
    
    case FAST:
      if (q->fuzz_level < 16) {
         factor = ((u32) (1 << q->fuzz_level)) / (fuzz == 0 ? 1 : fuzz); 
      } else
        factor = MAX_FACTOR / (fuzz == 0 ? 1 : next_p2 (fuzz));
      break;

    case LIN:	// 线性
      factor = q->fuzz_level / (fuzz == 0 ? 1 : fuzz); 
      break;

    case QUAD:	// 平方
      factor = q->fuzz_level * q->fuzz_level / (fuzz == 0 ? 1 : fuzz);
      break;

    default:
      PFATAL ("Unkown Power Schedule");
  }
  if (factor > MAX_FACTOR) 
    factor = MAX_FACTOR;	// MAX_FACTOR = 32

  perf_score *= factor / POWER_BETA;	// POWER_BETA = 1

  /* Make sure that we don't go over limit. */

  if (perf_score > HAVOC_MAX_MULT * 100) perf_score = HAVOC_MAX_MULT * 100;

  return perf_score;

}

4. save_if_interesting 中的更改

  // 每个测试用例执行完后都计算表示路径的校验和,然后将队列中执行相同路径的种子的路径频率+1
  /* Update path frequency. */
  u32 cksum = hash32(trace_bits, MAP_SIZE, HASH_CONST);

  struct queue_entry* q = queue;
  while (q) {
    if (q->exec_cksum == cksum)
      q->n_fuzz = q->n_fuzz + 1;

    q = q->next;

  }

5. update_bitmap_score

static void update_bitmap_score(struct queue_entry* q) {

  u32 i;
  u64 fuzz_p2      = next_p2 (q->n_fuzz);	// 求大于等于n_fuzz的第一个2的次方
  u64 fav_factor = q->exec_us * q->len;

  /* For every byte set in trace_bits[], see if there is a previous winner,
     and how it compares to us. */

  for (i = 0; i < MAP_SIZE; i++)

    if (trace_bits[i]) {	// 对于每一个覆盖到的边

       if (top_rated[i]) {	// 如果存在最优者

         u64 top_rated_fuzz_p2    = next_p2 (top_rated[i]->n_fuzz);
         u64 top_rated_fav_factor = top_rated[i]->exec_us * top_rated[i]->len;
		 // 如果执行频率大于原有最优着,则跳过
         if (fuzz_p2 > top_rated_fuzz_p2) continue;
         else if (fuzz_p2 == top_rated_fuzz_p2) {	// 如果等于

           if (fav_factor > top_rated_fav_factor) continue;	// 根据速度和大小决定去留

         }

         /* Looks like we're going to win. Decrease ref count for the
            previous winner, discard its trace_bits[] if necessary. */

         if (!--top_rated[i]->tc_ref) {
           ck_free(top_rated[i]->trace_mini);
           top_rated[i]->trace_mini = 0;
         }

       }

       /* Insert ourselves as the new winner. */

       top_rated[i] = q;
       q->tc_ref++;

       if (!q->trace_mini) {
         q->trace_mini = ck_alloc(MAP_SIZE >> 3);
         minimize_bits(q->trace_mini, trace_bits);
       }

       score_changed = 1;

     }

}

到了这里,关于Coverage-based Greybox Fuzzing as Markov Chain的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Fuzzing101:Exercise 3 - tcpdump 翻译+解题

    Fuzzing101:Exercise 3 - tcpdump 翻译+解题 题目部分翻译 题目链接:https://github.com/antonio-morales/Fuzzing101/tree/main/Exercise%203  在本练习中,我们将对 TCPdump 数据包分析器进行模糊测试。目标是在 TCPdump 4.9.2 中找到CVE-2017-13028的崩溃/PoC 。如果想要了解更多CVE-2017-13028,可以通过以下的

    2024年01月17日
    浏览(28)
  • 测试工具coverage的高阶使用

      在文章Python之单元测试使用的一点心得中,笔者介绍了自己在使用Python测试工具 coverge 的一点心得,包括: 使用coverage模块计算代码测试覆盖率 使用coverage api计算代码测试覆盖率 coverage配置文件的使用 coverage badge的生成   本文在此基础上,将会介绍coverage的高阶使用,

    2024年02月12日
    浏览(32)
  • Hopper: Interpretative Fuzzing for Libraries——论文阅读

    problem 1 :虽然目前最先进的fuzzers能够有效地生成输入,但是现有的模糊驱动程序仍然不能全面覆盖库的入口。(entries in libraries,库中的不同条目或入口点。包括调用库中的函数、使用库中的类等) problem 2 :大多数模糊驱动程序都是开发人员手工制作的,它们的质量取决于开

    2024年02月02日
    浏览(43)
  • Python库-coverage测试覆盖率

    Coverage.py 是用于测量Python程序代码覆盖率的工具。它 监视程序,注意代码的哪些部分已执行,然后 分析源以识别可以执行但未执行的代码。 覆盖率测量通常用于衡量测试的有效性。它 可以显示测试正在执行代码的哪些部分,以及哪些部分是 不。 用于运行测试套件并收集数

    2024年02月09日
    浏览(42)
  • Python:代码覆盖率工具coverage

    简介 :覆盖率测量通常用于衡量测试的有效性。它可以显示您的代码的哪些部分正在被测试执行,哪些不是。coverage是一个测量 Python 程序代码覆盖率的工具。它监视您的程序,注意代码的哪些部分已被执行,然后分析源代码以识别可能已执行但未执行的代码。 安装: 官方文

    2024年02月09日
    浏览(35)
  • Python代码覆盖率分析工具Coverage

    目录 简介 安装 命令行中使用 调用API使用 Coverage是一个Python代码覆盖率分析工具,它可以用于衡量Python测试代码的质量。通过给代码执行带来的覆盖率数据,Coverage可以帮助开发人员找出被回归测试代码中的漏洞,并且指明哪些代码没有被测试到。 Coverage可以让你知道:哪些

    2024年02月11日
    浏览(38)
  • VCS ICO - Intelligent Coverage Optimization

    ico 是vcs提供的用于优化覆盖率的feature;一般用户通过 dist solver bofore 等约束了变量的随机概率,而 ico 会在用户约束的基础上,做一些自动“修正”,以此来优化随机激励,提高随机多样性,加速覆盖率收敛,缩短 turn-around time TAT 。 主要功能包含如下几部分: Prognosis : 用于

    2024年02月14日
    浏览(34)
  • 马尔科夫链(Markov Chain)

    马尔可夫性(Markov Property)是指系统的下一个状态 仅与当前状态有关,而与以前的状态无关 (即无记忆性(memorylessness),系统不记得当前状态以前的状态,仅仅基于当前状态来决定下一个时刻转移到什么状态) 如果指标集(index set)是连续的,则称为连续时间马尔可夫链(Continuou

    2024年02月05日
    浏览(35)
  • 初识马尔科夫模型(Markov Model)

    马尔科夫模型(Markov Model)是一种概率模型,用于描述随机系统中随时间变化的概率分布。马尔科夫模型基于马尔科夫假设,即当前状态只与其前一个状态相关,与其他状态无关。 马尔科夫模型具有如下几个性质: ① 马尔科夫性 :即马尔科夫模型的下一个状态只与当前状态

    2024年02月04日
    浏览(29)
  • DARWIN Survival of the Fittest Fuzzing Mutators读论文笔记

    作者背景 达姆施塔特工业大学:成立于1877年,是德国著名理工科大学 ‡萨格勒布大学: 是克罗地亚最大的大学,也是该地区历史最悠久的大学 §拉德堡德大学:位于荷兰奈梅亨市,又称奈梅亨大学,欧洲顶尖的研究型学术院校 发表时间 [外链图片转存失败,源站可能有防盗链机

    2024年02月03日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包