5.6. Grinder¶
5.6.1. 客户端配置¶
- 32位系统
.\grinder\node\data\x86\grinder_logger.dll
复制到c:\windows\system32\
- 64位系统
.\grinder\node\data\x86\grinder_logger.dll
复制到c:\windows\syswow64\
.\grinder\node\data\x64\grinder_logger.dll
复制到c:\windows\system32\
创建保存符号文件的目录
c:\symbols\
编辑``config.rb``
ruby grinder.rb [--config=c:\path\to\alternative\config.rb] --browser=BROWSER
ps: 目前grinder只支持ruby 1.9-2.0,并不支持高于2.0的版本
5.6.2. Node¶
5.6.2.1. 主要文件说明¶
browser: hook相应浏览器的parseFloat
chrome.rb
firefox.rb
internetexplore.rb
safari.rb
core: 核心代码
debug
debugger.rb 浏览器所用到的debugger基类,继承自Metasm
logger.rb 记录日志
configuration.rb 配置需要的变量,检查运行环境
crypt.rb openssl 加解密库函数
debugger.rb
logging.rb 控制台输出
server.rb 运行web服务器,浏览器访问该服务器以获得样本
webstats.rb
xmlcrashlog.rb 用xml的格式记录crashlog
crashes:生成的crash样本存放的文件夹
data: 测试用的图片/pdf/js等文件,以及需要用到的dll
continue.exe => 运行在后台,点击因为crash生成的弹窗
logging.js
fuzzer:用户实现自己fuzzer的位置
lib: grinder用到的三方库主要是metasm,这是一个ruby的用来做二进制的库
source
continue.exe 源代码
logger.dll 源代码
config.rb 配置文件,若一台电脑运行多个节点时,需要多个配置文件
crypto.rb 生成密钥,加密生成的crash
grinder.rb 主文件
reduction.rb
testcase.rb 从日志中恢复样本文件
5.6.2.2. 运行流程¶
入口文件为grinder.rb
- 初始化过程
初始化需要fuzz的浏览器
初始化环境相关变量
检查dll加载情况
- 运行过程
检查web server状态,若停止或未启动,则启动
启动浏览器相应的debugger
debugger运行过程
初始化logger
hook heap
运行目标浏览器
5.6.3. Server¶
服务器端采用典型的PHP+MySQL的结构,设计思路是比较老的非MVC结构,总体功能比较单一,主要用来查看fuzzer节点的情况
部分文件功能说明如下
account.php 用户账户管理相关
crash.php 管理crash
crashes.php 管理crash
fuzzers.php fuzz节点状态
install.php 数据库初始化
5.6.4. metasm¶
Metasm是一个ruby实现的汇编器、反编汇器以及编译器。
5.6.5. Fuzzer编写¶
5.6.5.1. 库函数¶
grinder提供的库函数主要有下面这些
rand( x )
Pick a random number between 0 and Xrand_bool()
Pick either true or falserand_item( arr )
Pick an item from an arraytickle(obj)
触发一个obj的所有属性LOGGER( name )
Logger类的构造函数
5.6.5.2. SimpleExample¶
SimpleExample.html 是grinder给出来的示例代码,展示了Fuzzer所需要的基本元素 编写logger必须的代码如下
var logger = new LOGGER( "SimpleExample" );
logger.starting();
/* other code here */
logger.finished();
window.location.href = window.location.protocol + '//' + window.location.host + '/grinder';
上面部分代码主要用于生成/初始化logger,以及完成fuzz之后回到grinder server
fuzzer主要的代码主要还是生成随机元素的部分,继续以SimpleExample.html为例
// 定义将要fuzz的元素
var elements = [ 'div', 'input', 'textarea', 'a', 'img', 'form' ];
// 生成相关元素
var elementA = rand_item( elements );
var elementB = rand_item( elements );
// 创建元素并记录,注意因为这里的fuzzer样本是随机生成的,所以需要详细的记录每一步的动作以保证可以复现
logger.log( "id_0 = document.createElement( '" + elementA + "' );", "grind", 1 );
var id_0 = document.createElement( elementA );
logger.log( "document.body.appendChild( id_0 );", "grind", 1 );
document.body.appendChild( id_0 );
// 在随后的代码对之前的元素进行变化,主要是对其属性值进行变换、调用、对换等操作
/* ... */
5.6.5.3. 编写¶
在简单看过相关的库函数和一个简单的样本之后,编写fuzzer的基础知识就已经足够了。 其必要的逻辑是在生成/修改等操作前后都调用log记录下足够的信息以便调试crash。另外就主要是设计好fuzzer种子生成的算法以及随机元素变换的算法以获取更多的crash。
5.6.6. nduja¶
SimpleExample.html更多的只是一个简单的样本,一个高效的fuzzer编写需要更精巧的思路,所以选择nduja进一步进行分析
其简单的函数调用树如下
- step1
- buildElementsTree1
createStyleSheet
- createMultipleElement
genRandomElement
appendToRandomElement
initialize => add multiply random listener
tweakattributes1 => set attr random vaule
tweakstyle1 => set random style sheet
initialize
- boom
- createNodeIterator
- ElementChecker
- Random - case 1
createElemRange1
deleteRange1
- Random - case 2
random skip / accept
- createTreeWalker
ElementChecker
createTagAggregation1
createElemRange
createTxtRange
- alterRange => random action
deleteContents
collapse
extractContents
surroundContents
selectNode
selectNodeContents
insertNode
setStartAfter
setStartBefore
setEndAfter
setEndBefore
spray
- moveIterator
- random
nextNode
previousNode
fuzzAttributes
- moveTreeWalker
- random
nextNode
previousNode
previousSibling
nextSibling
firstChild
lastChild
parentNode
fuzzAttributes
- tagCrawler1
fuzzAttributes
可以看到,正和之前文章讲述的原因,nduja的fuzz逻辑是比较复杂的,而其fuzz的主要操作是moveIterator,moveTreeWalker。即利用节点间的联系来变换,以期找出漏洞。
5.6.7. fileja¶
在之前提到了fileja也是基于grinder编写的fuzzer,相对于nduja,在grinder的基础上做了更多的扩展,其流程更复杂
fileja除了自己编写了testcase之外,也使用了来自于W3C的testcase
fileja的在函数执行之前,定义了比较多的全局变量和常量,对比较多的html元素进行了fuzz,这样能获得的crash也会比较多,定义的主要的值有下面这些
- 全局参数
元素数量
Listener数量
是否使用svg
…
- 全局变量
websocket
xhr
…
- 全局常量
object_blacklist
interesting_vals
commands
events
mutationEvents
HTMLElements
MMLElements
SVGElements
standardAttributes
SVGCommonAttributes
SVGAttributes
…
在定义相关的值之后,进行了fuzz,这里fuzz就更多的针对xhr,websocket和html事件,在fuzzer中各种同步和异步的事件分别触发来进行尝试
- getList - get test case list from server
- buildDocumentTree
- random
buildFromFile
- go
buildDOM
- initFrame
initF => create meta, add script
initXhr => add random listener to xhr
initWs => add listener to xhr
initXhrJS => add random listener to xhr
- createSupportStructures
createNodeIterator
createTreeWalker
createRanges
- cycle
tick
- startFuzzing
crawl_properties
call_methods
mutateDOM
CollectGarbage
reload