前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >通过编译器转换(llvm pass)规避模糊测试的一些障碍

通过编译器转换(llvm pass)规避模糊测试的一些障碍

作者头像
用户1423082
发布2024-12-31 20:12:11
发布2024-12-31 20:12:11
7300
代码可运行
举报
文章被收录于专栏:giantbranch's bloggiantbranch's blog
运行总次数:0
代码可运行

这个是看一个文章的记录,算是简译吧

总的来说是通过llvm pass去优化代码的生成去提高AFL的代码覆盖率

AFL通过插桩获取的代码覆盖率,假如变异的样本触发的新的路径,就会加入到接下来的变异队列中

但是有一些情况,会给afl造成极大的障碍

代码语言:javascript
代码运行次数:0
复制
if (input == 0xabad1dea) {
  /* terribly buggy code */
} else {
  /* secure code */
}

afl是随机变异的,去变异生成一个完全一样的4字节的数,真是难于上青天

那怎么解决这个问题呢?

假如把上面的代码换成下面那样

代码语言:javascript
代码运行次数:0
复制
if (input >> 24 == 0xab){
  if ((input & 0xff0000) >> 16 == 0xad) {
    if ((input & 0xff00) >> 8 == 0x1d) {
      if ((input & 0xff) == 0xea) {
        /* terrible code */
        goto end;
      }
    }
  }
}

/* good code */

end:

现在一次比较一个字节,大大提升了中奖概率,从1/2^32降低到了1/2^9,即1/512

原文作者根据这个原理,把可能出现这个问题两种情况也写了pass:switch的选项,还有比较函数(memcmp,strcmp …)

LLVM Passes

作者共实现了3个pass

比较指令的:split-compares-pass strcmp和memcmp的: compare-transform-pass switch的:split-switches-pass

The split-compares-pass

其实除了有==,还有!=,>,<,>=,<=

首先把>=,<=这种拆分为两个,比如>=,一个是==,另一个是>

再将有符号的比较拆分为,符号位比较和无符号的比较

到这就只剩这四种比较了:<, >, ==, != ,而且都是无符号的,所以再将字符拆分成单字节就好了

The compare-transform-pass

原始

代码语言:javascript
代码运行次数:0
复制
if(!strcmp(directive, "crash")) {
  programbug()
}

改成一个一个比较

代码语言:javascript
代码运行次数:0
复制
if(directive[0] == 'c') {
  if(directive[1] == 'r') {
    if(directive[2] == 'a') {
      if(directive[3] == 's') {
        if(directive[4] == 'h') {
          if(directive[5] == 0) {
            programbug()
}

局限性:就是这个比较是文字字符串并且因此字符串本身及其长度在编译时已知

The split-switches-pass

代码语言:javascript
代码运行次数:0
复制
int x = userinput();
switch(x) {
  case 0x11ff:
    /* handle case 0x11ff */
    break;
  case 0x22ff:
    /* handle case 0x22ff */
    break;
  default:
    /* handle default */
}

思想是想转化为if else,之后在通过split-compares-pass来处理,但这可能不是生成最优代码

代码语言:javascript
代码运行次数:0
复制
if (x >> 24 == 0x00){
  if ((x & 0xff0000) >> 16 == 0x00) {
    if ((x & 0xff00) >> 8 == 0x11) {
      if ((x & 0xff) == 0xff) {
        /* case 0x11ff */
        goto after_switch;
      }
      goto default_case;
    }
    goto default_case;
  }
  goto default_case;
}
else if (x >> 24 == 0x00){
  if ((x & 0xff0000) >> 16 == 0x00) {
    if ((x & 0xff00) >> 8 == 0x22) {
      if ((x & 0xff) == 0xff) {
        /* case 0x22ff */
        goto after_switch;
      }
      goto default_case;
    }
    goto default_case;
  }
  goto default_case;
}

default_case:
  /* default case */

after_switch:

评价

作者还用libpng和harfbuzz对着几个pass进行了测试

Driller的test case

代码语言:javascript
代码运行次数:0
复制
 1 int main(void) {
 2   config_t* config = readconfig();
 3   if(config == NULL){
 4     puts("Configuration syntax error");
 5     return 1;
 6   }
 7   if (config->magic != MAGICNUMBER) {
 8     puts("Bad magic number");
 9     return 2;
10   }
11   initialize(config);
12
13   char* directive = config->directives[0];
14   if(!strcmp(directive, "crashstring")) {
15     programbug();
16   }
17   else if(!strcmp(directive, "setoption")) {
18     setoption(config->directives[1]);
19   }
20   else{
21     _default();
22   }
23 
24   return 0;
25 }

有了pass,1分钟就通过了第7行的检查,60分钟生成了crashstring,但是最后没出来setoption

没有pass,可能在合理的时间都过不了第7行的检查

libpng

作者将afl分为两组

组A:1个master,3个slave,都是正常插桩 组B:1个master,1个slave,都是正常插桩,还有另外的,1个master,1个slave,都是加了pass的

A组发现了1459条路径B找到了2318条路径。

在代码覆盖率方面(使用lcov进行度量的),A组命中了libpng的2186行,而B组命中了2707行

通过看图,可以看到加了pass,比较随便过

harfbuzz

harfbuzz的测试设置与libpng的设置相同,但是测试仅运行了24小时。在测试结束时,A组发现2070条路径,而B组发现2150条路径。在代码覆盖率方面,A组达到3358行,而B组达到3474行,增长了3.5%。

效果还是比较明显的

参考原文

https://lafintel.wordpress.com/2016/08/15/circumventing-fuzzing-roadblocks-with-compiler-transformations/

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-09-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • LLVM Passes
    • The split-compares-pass
    • The compare-transform-pass
    • The split-switches-pass
  • 评价
    • Driller的test case
    • libpng
    • harfbuzz
  • 参考原文
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档