ref:Adding AFL Bloom Filter to Domato for Fun
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的更多相关文章
- Skip List & Bloom Filter
Skip List | Set 1 (Introduction) Can we search in a sorted linked list in better than O(n) time?Th ...
- Bloom Filter:海量数据的HashSet
Bloom Filter一般用于数据的去重计算,近似于HashSet的功能:但是不同于Bitmap(用于精确计算),其为一种估算的数据结构,存在误判(false positive)的情况. 1. 基本 ...
- 探索C#之布隆过滤器(Bloom filter)
阅读目录: 背景介绍 算法原理 误判率 BF改进 总结 背景介绍 Bloom filter(后面简称BF)是Bloom在1970年提出的二进制向量数据结构.通俗来说就是在大数据集合下高效判断某个成员是 ...
- Bloom Filter 布隆过滤器
Bloom Filter 是由伯顿.布隆(Burton Bloom)在1970年提出的一种多hash函数映射的快速查找算法.它实际上是一个很长的二进制向量和一些列随机映射函数.应用在数据量很大的情况下 ...
- Bloom Filter学习
参考文献: Bloom Filters - the math http://pages.cs.wisc.edu/~cao/papers/summary-cache/node8.html B ...
- 【转】探索C#之布隆过滤器(Bloom filter)
原文:蘑菇先生,http://www.cnblogs.com/mushroom/p/4556801.html 背景介绍 Bloom filter(后面简称BF)是Bloom在1970年提出的二进制向量 ...
- bloom filter
Bloom filter 是由 Howard Bloom 在 1970 年提出的二进制向量数据结构,它具有很好的空间和时间效率,被用来检测一个元素是不是集合中的一个成员. 结 构 二进制 召回率 ...
- Bloom Filter 概念和原理
Bloom filter 是由 Howard Bloom 在 1970 年提出的二进制向量数据结构,它具有很好的空间和时间效率,被用来检测一个元素是不是集合中的一个成员.如果检测结果为是,该元素不一定 ...
- 【转】Bloom Filter布隆过滤器的概念和原理
转自:http://blog.csdn.net/jiaomeng/article/details/1495500 之前看数学之美丽,里面有提到布隆过滤器的过滤垃圾邮件,感觉到何其的牛,竟然有这么高效的 ...
随机推荐
- vue 和react
React 和 Vue 有许多相似之处,它们都有: 使用 Virtual DOM 提供了响应式 (Reactive) 和组件化 (Composable) 的视图组件. 将注意力集中保持在核心库,而将其 ...
- Python学习笔记(三十五)—内置模块(4)struct
摘抄自:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001431955007 ...
- linux中操作数据库的使用命令记录
1,mysql 查看数据库表编码格式: show create table widget; 修改数据库表编码格式: alter table widget default character set u ...
- 51nod 1161 Partial Sums
给出一个数组A,经过一次处理,生成一个数组S,数组S中的每个值相当于数组A的累加,比如:A = {1 3 5 6} => S = {1 4 9 15}.如果对生成的数组S再进行一次累加操作,{1 ...
- mysql数据库 批量替换 某字段中的数据
当数据库出现这种情况: 表名:area id name 1 太仓 2 太仓市 3 太仓市 ... ... 我需要把 name字段中 的太仓市 的“市“去掉 可以使用: update `area` ...
- jQuery.Event的一些用法
直接写用法 //创建一个事件 var event = $.Event("事件类型",["定义的事件参数最终将出现在e1中"]); //绑定一个处理器 $(obj ...
- 可怕的npm蠕虫
https://hackernoon.com/im-harvesting-credit-card-numbers-and-passwords-from-your-site-here-s-how-9a8 ...
- javascript复习笔记
/* Javascript:用来在页面中编写特效,和HTML.CSS一样都是有浏览器解析 Javascript语言: 一.JS如何运行(javascript,jscript,vbscript,appl ...
- mysql 提权总结
1.MOF提权 简单的说mof就是系统内部的一个程序,每隔一定时间系统就会以root权限去执行,我们将其替换然后执行我们的而已攻击代码.此举称之为mof提权. 以下便是脚本: #pragma name ...
- spring mvc 自定义编辑器
起始知识: Java标准的PropertyEditor的核心功能是将一个字符串转换为一个Java对象,以便根据界面的输入或配置文件中的配置字符串构造出一个JVM内部的java对象. 如何注册自定义的属 ...