ref:https://www.sigpwn.io/blog/2018/5/13/adding-afl-bloom-filter-to-domato-for-fun

Adding AFL Bloom Filter to Domato for Fun

So I have been playing with Domato for few weeks now and wrote a blog about it's internals along the way. Unfortunately there is no feedback mechanism in the open-sourced version of Domato, although according to the blog post by Ivan Fratic (@ifsecure) of google project zero they are experimenting with coverage guided fuzzing using modified version of WinAFL's DynamoRIO client. I had a chat with Richard Johnson (@richinseattle) of Cisco Talos Vulndev Team while staying in Dubai for OPCDE 2018 and he gave me an idea of adding some kind of feedback mechanism in the syntax level instead of binary level feedback. First thing that came up to my mind was AFL's bloom filter. Since it is known to be so effective, why not try adding this to Domato as well?

Adding unique IDs to grammar rules

If you read my previous post, you will have understanding of how grammar rules are parsed and stored in data structures. In AFL, unique ids are assigned to each basic block(对于基本块制定一个唯一的id). In our case, assigning unique ids to each grammar rules seems appropriate since order of selecting certain grammar rules for expanding symbols is similar to visiting basic blocks in the control flow graph. (以选择不同的语法组合成为代码覆盖率计算的替代。)

So in the grammar.py file of Domato, I made following changes:

def _parse_code_line(self, line, helper_lines=False):
"""Parses a rule for generating code."""
rule = {
'type': 'code',
'parts': [],
'creates': [],
'uid' : self._get_new_uid() # add this field
} def _parse_grammar_line(self, line):
"""Parses a grammar rule."""
# Check if the line matches grammar rule pattern (<tagname> = ...).
match = re.match(r'^<([^>]*)>\s*=\s*(.*)$', line)
if not match:
raise GrammarError('Error parsing rule ' + line) # Parse the line to create a grammar rule.
rule = {
'type': 'grammar',
'creates': self._parse_tag_and_attributes(match.group(1)),
'parts': [],
'uid': self._get_new_uid() # add this field
}

Now each rule contains a field named 'uid' that stores unique integer value.

Selecting less chosen rule for expanding symbols

To record which rules were chosen in the previous generated case, I added a Python dictionary for this purpose.

# coverage map
self._cov = {}

Now when choosing the rule for expanding current symbol, we need to reference the coverage map. Note that algorithm used in AFL is like following.

cur_location = <COMPILE_TIME_RANDOM>;//选择的rule
shared_mem[cur_location ^ prev_location]++;
prev_location = cur_location >> 1;//prev_location代表之前选择的rule,以rule覆盖率来替代目标运行代码覆盖率

So in our case,  cur_location is the unique id of a rule we are considering to select. prev_location is previously chosen rule. Following code checks whether if there is an never selected order of grammar rules (thus bitmap_idx is not in the coverage map,代码选择顺序是否出现过) and selects first encountered rule of this case.

If every combination of previously selected grammar rule and current rule candidates have been selected before (so every possible bitmap_idx is already present as a key in coverage map), code saves how many times certain combination has been chosen.

def _select_creator(self, symbol, recursion_depth, force_nonrecursive):
...
# select creator based on coverage map
# select creator that has been selected less
hits = []
for c in creators:
bitmap_idx = c['uid'] ^ self._prev_id
if bitmap_idx not in self._cov:
self._cov[bitmap_idx] = 1
self._prev_id = c['uid'] >> 1
return c
else:
hits.append(self._cov[bitmap_idx])

Among the grammar rules chosen, code saves a list (less_visited_creators[]) of relatively least selected rules. If cdf is not available for rules for some symbol, it randomly chooses from less_visited_creators[] and records coverage info accordingly.

idx = random.randint(0, len(less_visited_creators) - 1)
curr_id = less_visited_creators[idx]['uid']
self._cov[(self._prev_id ^ curr_id) % MAP_SIZE] = self._cov[self._prev_id ^ curr_id] + 1
self._prev_id = curr_id >> 1
return less_visited_creators[idx]

Similarly, if cdf is available for some symbol, it uses cdf instead randomly choosing a grammar rule and records coverage information.

idx = bisect.bisect_left(less_visited_creators_cdf, random.random(), 0, len(less_visited_creators_cdf)-1)
curr_id = less_visited_creators[idx]['uid']
self._cov[(self._prev_id ^ curr_id) % MAP_SIZE] = self._cov[(self._prev_id ^ curr_id) % MAP_SIZE] + 1
self._prev_id = curr_id >> 1
return less_visited_creators[idx]

Results

Because I lack resources to be used for fuzzing, testing was somewhat limited. Also I believe Google fuzzed modern browsers with Domato (or customized internal versions) long enough so there is a very low chance of myself finding exploitable crashes with my limited resources. However, my version of Domato was able to find more unique crashes than the original open-sourced version after fuzzing IE11 on Windows 10.(发现更多不同的崩溃)

I generated 10,000 html files with both original Domato and my customized version and used them to fuzz IE11 to see which gets more unique crashes. The result if the following.

  • Original : 16 unique crashes
  • Customized : 20 unique crashes

I will soon release the code for those who are interested (it there is someone :P), although I guess by reading this blog you have enough information to go try out by yourself.

Any feedbacks or reporting of errors, please reach out !

ref:Adding AFL Bloom Filter to Domato for Fun的更多相关文章

  1. Skip List & Bloom Filter

    Skip List | Set 1 (Introduction)   Can we search in a sorted linked list in better than O(n) time?Th ...

  2. Bloom Filter:海量数据的HashSet

    Bloom Filter一般用于数据的去重计算,近似于HashSet的功能:但是不同于Bitmap(用于精确计算),其为一种估算的数据结构,存在误判(false positive)的情况. 1. 基本 ...

  3. 探索C#之布隆过滤器(Bloom filter)

    阅读目录: 背景介绍 算法原理 误判率 BF改进 总结 背景介绍 Bloom filter(后面简称BF)是Bloom在1970年提出的二进制向量数据结构.通俗来说就是在大数据集合下高效判断某个成员是 ...

  4. Bloom Filter 布隆过滤器

    Bloom Filter 是由伯顿.布隆(Burton Bloom)在1970年提出的一种多hash函数映射的快速查找算法.它实际上是一个很长的二进制向量和一些列随机映射函数.应用在数据量很大的情况下 ...

  5. Bloom Filter学习

    参考文献: Bloom Filters - the math    http://pages.cs.wisc.edu/~cao/papers/summary-cache/node8.html    B ...

  6. 【转】探索C#之布隆过滤器(Bloom filter)

    原文:蘑菇先生,http://www.cnblogs.com/mushroom/p/4556801.html 背景介绍 Bloom filter(后面简称BF)是Bloom在1970年提出的二进制向量 ...

  7. bloom filter

    Bloom filter 是由 Howard Bloom 在 1970 年提出的二进制向量数据结构,它具有很好的空间和时间效率,被用来检测一个元素是不是集合中的一个成员. 结    构 二进制 召回率 ...

  8. Bloom Filter 概念和原理

    Bloom filter 是由 Howard Bloom 在 1970 年提出的二进制向量数据结构,它具有很好的空间和时间效率,被用来检测一个元素是不是集合中的一个成员.如果检测结果为是,该元素不一定 ...

  9. 【转】Bloom Filter布隆过滤器的概念和原理

    转自:http://blog.csdn.net/jiaomeng/article/details/1495500 之前看数学之美丽,里面有提到布隆过滤器的过滤垃圾邮件,感觉到何其的牛,竟然有这么高效的 ...

随机推荐

  1. jquery ajax thinkphp异步局部刷新完整流程

    环境:ThinkPHP3.2.3,jQuery3.2   前言: 在一般的网站中,都需要用到jquery或者其他框架(比如angular)来处理前后端数据交互,thinkphp在后台也内置了一些函数用 ...

  2. php实现多继承-trait语法

    自 PHP 5.4.0 起,PHP 实现了一种代码复用的方法,称为 trait. Trait 是为类似 PHP 的单继承语言而准备的一种代码复用机制.Trait 为了减少单继承语言的限制,使开发人员能 ...

  3. Java设计模式の代理模式

    目录  代理模式 1.1.静态代理   1.2.动态代理 1.3.Cglib代理 代理模式 代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象.这样做的好处是 ...

  4. 如何在WIndows电脑上安装 SVN Server 实现代码版本控制

    One 下载-安装 SVN SVNServer  先去官网下载服务器版本的svn server,下载地址 :https://www.visualsvn.com/server/download/   选 ...

  5. Linux更改文件及目录权限问题

    1. 快速实例学习: 修改某个目录下的所有文件的权限,包括子目录中的文件,例子如下: # /home/user 注:仅把/home/user目录的权限设置为rwxrwxrwx # /home/user ...

  6. bash高级

      重定向 管道:  ps  -ef | grep bash  管道作为命令衔接的 两个都写 ,一个到文件,一个到屏幕   tee  null

  7. [php]手动搭建php开发环境(排错)

    前提:针对自己的系统下载相应的php.apache.mysql,安装完毕后按照以下去配置httpd.conf和php.ini 本人用的是php5.6.4和apache2.4.4 一.Apache : ...

  8. 【专题】数位DP

    [资料] ★记忆化搜索:数位dp总结 之 从入门到模板 by wust_wenhao 论文:浅谈数位类统计问题 数位计数问题解法研究 [记忆化搜索] 数位:数字从低位到高位依次为0~len-1. 高位 ...

  9. jquery 中$符号六大作用

    jquery 中$符号六大作用 2012-12-16 86市场网 javascript a.$用作选择器, var e = $("h1 a"); var f = $("t ...

  10. 爬行百度标题&URL案例

    思路: 先将需要获取的匹配出,然后可以用"永真"(即while True:)来遍历使得URL可以一直自增变化(百度点击下一页URL的pn参数就增加10)每增加10就爬行一遍URL然 ...