Grinder搭建小記與Nduja(這次不待續了)
Grinder是比較有名的瀏覽器FUZZ框架,採用ruby語言編寫,主要是作為測試框架來使用,在《白帽子講瀏覽器安全》一書中作者使用了Nduja生成測試樣本來配合Grinder使用。根據網上的資料,nduja、fileja的自動化部署預設都以Grinder作為支撐環境。
我個人覺得Grinder存在的意義在於能夠快速部署我們想要的Fuzz樣例而無需操心異常捕獲、程式管理這些細節。
Grinder分為
Node:負責實際的FUZZ工作
Server:負責收集結果,主要是為了管理多臺Fuzz機器
我這裡只搭建了Node
- 安裝ruby2.0環境,在Windows下我使用了RubyInstaller進行一鍵整合化的安裝。
- 把.\grinder\node\data\x86\grinder_logger.dll放到c:\windows\system32\目錄下
- 建立一個符號路徑
- 修改config.rb把上面建立的符號路徑和瀏覽器路徑填進去
- 在FUZZ目錄下制定測試的例子
- 執行ruby grinder.rb --browser=BROWSER
Grinder是動態生成樣本的。對於其它的fuzz來說是先生成待測試的樣本,再由瀏覽器開啟。但是Grinder會直接開啟規則模版,動態生成樣本。這樣一來就需要對每次導致crash的值進行記錄,Grinder透過向瀏覽器注入grinder_logger.dll,hook住Javascript中的parseFloat函式。在呼叫logger.log時,grinder_logger.dll設定的hook回撥函式就可以記錄下來其內容,並儲存為log檔案。因為要Hook javascript函式,也就是說要解析jscript9.dll,所以需要這個模組的符號。這就是我們第3布操作的作用。當成功進行Hook之後,會給出提示。
[+D+] Hooked JavaScript parseFloat() to grinder_logger.dll via proxy @ 0x99B0000
此外記錄下來的log檔案不是直接的樣本,需要使用testcase.py進行解析。
.\grinder\node>ruby testcase.rb [--config=c:\path\to\CONFIG.RB] --log=c:\path\to\XXXXXXXX.XXXXXXXX.log --save=c:\path\to\XXXXXXXX.XXXXXXXX.html
About Nduja
根據上面的內容,我們可以看出Grinder其實只是提供了一些用於變異樣本的語法,關鍵的內容還是要依靠自己來進行編寫從而生成。
在這個基礎上Rosario valotta開發了一套實際的fuzz策略稱為Nduja Fuzzer
根據作者的介紹,得知Nduja的開發背景是在市面上已有DOM level1的fuzzer的情況下,去試圖fuzz DOM level2和level3以獲取更多的成果。
作者原話如下,我標註了一些重點出來:
The usual approach in browser fuzzing leverages on DOM Level 1 interfaces for performing DOM mutations:
- a big quantity of random HTML elements are created and randomly added to the HTML document tree
- the DOM tree is crawled and element references are collected for later reuse
- elements attributes and function calls are tweaked
- random DOM nodes are deleted
- garbage collection is forced
- collected references are crawled and tweaked again
This approach is effective but suffers from some design limitations:
- every DOM mutation (e.g. element tweaking, deletion, etc) is performed on a single HTML element, no mass mutations are managed
- the execution workflow can only be altered by the cardinality and the type of randomly generated DOM nodes (e.g different tag names, attributes, etc).
The entropy of a browser fuzzer can be taken to a further level introducing some new functionalities defined in DOM Level 2 and Level 3 specifications.
即透過對DOM2和DOM3中的新特性進行Fuzz來增墒。 為此作者舉了幾個例子作以說明。
Working with aggregations of nodes (DOM Level 2)
DOM Level 2 specifications introduces several new interfaces that allow to perform mutations on collections of DOM elements.
For instance interfaces like DocumentFragment, Range, TextRange, SelectionRange allow to create logical nodes aggregations and execute CRUD mutations on them using a rich set of APIS.
A quick list of these methods: createRange, deleteContents, extractContents, cloneContents, cloneRange, removeRange, createTextRange, pasteHTML, etc
The expectation is that each of the methods provided for the insertion, deletion and copying of contents can be directly mapped to a series of Node editing operations enabled by DOM Core.
In this sense these operations can be viewed as convenience methods that also enable a browser implementation to optimize common editing patterns.
It turns out that implementation bugs in this methods can lead to serious memory corruption errors when not correctly mapped to atomic-safe node operations.
Using document traversal data structures (DOM Level 2)
In the classic fuzzer approach, crawling the DOM tree is performed walking the physical tree from the top level node (DOCTYPE or HTML) to the leaves using DOM Level 1 methods (.children, .parentNode, .nextSiebling, etc).
In DOM Level 2 several data structures are available to create logical view of a Document subtree (eg. NodeList, TreeWalker, NodeIterator); we refer to these as the logical views to distinguish them from the physical view, which corresponds to the document subtree per se.
These logical views are dynamic, in the sense that they modify their structure to reflect changes made to the underlying document.
That's why some memory corruption scenarios arise when DOM mutations performed on the physical tree are not correctly managed on the logical counterpart.
Introducing events (DOM Level 3)
In order to add more entropy to the fuzzer workflow, events firing and propagation can be used. DOM Level 3 specification defines a standard way to create events, fire them and manage event listeners for every DOM node. On top of that, specification defines a standard for event propagation model.
From the spec page (http://www.w3.org/TR/DOM-Level-3-Events/#dom-event-architecture):
"Event objects are dispatched to an event target. At the beginning of the dispatch, implementations must first determine the event object's propagation path."
The propagation path of an event include 3 steps:
- capture phase: the event propagates through the target's ancestors from the document root to the target's parent. Event listeners registered for this phase handle the event before it reaches its target.
- target phase: the event arrives at the final target element. Event listeners registered for this phase handle the event once it has reached its target.
- bubble phase: the event propagates through the target's ancestors in reverse order, starting with the target's parent and ending with the document root element. Event listeners registered for this phase must handle the event after it has reached its target.
From the spec page: "The propagation path must be an ordered list of current event targets through which the event object must pass. For DOM implementations, the propagation path must reflect the hierarchical tree structure of the document. The last item in the list must be the event target; the preceding items in the list are referred to as the target's ancestors, and the immediately preceding item as the target's parent. Once determined, the propagation path must not be changed; for DOM implementations, this applies even if an element in the propagation path is moved within the DOM. or removed from the DOM. Additionally, exceptions inside event listeners must not stop the propagation of the event or affect the propagation path."
So the idea here is to let an event fire and alter the DOM tree structure after the propagation path has already been defined. This can be easily obtained attaching random eventListeners to every DOM element, setting the "capturable" flag to true. Whenever an event targeting a node is intercepted by a node's anchestor, some random operations on DOM tree are performed, removing o inserting whole sets of elements. Then the propagation of the event goes on.
Note: this technique proved to be dramatically effective in crashing IE9/10, probably because IE9 is the first IE version to support standard W3C event model and is not still "bullet-proof".
The listeners map of a node can be altered during dispatch, but is immutable once the dispatch reached that node .
Once determined, the propagation path must not be changed, even if an element in the propagation path is moved/removed within the DOM
作者給出了Nduja的操作流程概述
- Initialization
- create a given number of random HTML elements
- for each element tweak random attributes/functions/styles
- for each element add a given number of event listeners
- append the elements in a random position in the document tree
- create logical views of a random DOM subtree (nodeIterator, treeWalker)
- Crawling
- Crawl DOM tree
- Create random Range (or similar DOM Level 2 structure) and apply random mutatios on it (delete, insert,surround, etc)
- Crawl DOM logical views
- Event management: events are managed accordingly to the dispatching phase
- if the event is in the capture/bubble phase:
- remove some random event listeners from the current target
- create random Range (or similar DOM Level 2 structure) and apply random mutatios on it (delete, insert,surround, etc)
- crawl physical tree and logical views
- if the event is in the target phase
- add some other event listeners to the event target node
參考資料:
node -browser chrome.rb firefox.rb internetexplorer.rb safari.rb -core debug debugger.rb debuggerexception.rb heaphook.rb hookedprocess.rb logger.rb processsymbols.rb configuration.rb crypt.rb debugger.rb logging.rb server.rb webstats.rb xmlcrashlog.rb -crashes -data -fuzzer *.html -lib metasm -source --部分dll的原始碼 config.rb crypto.rb grinder.rb reduction.rb testcase.rb server --主要用於分散式節點的漏洞結果彙總,這裡不再詳述
http://www.freebuf.com/sectool/93130.html
http://blog.nsfocus.net/web-browser-fuzzing/
相關文章
- 放置遊戲大成之作 — Realm Grinder2019-05-13遊戲
- 記一次 MySQL 主從搭建2020-03-06MySql
- 7天搭建一款小程式+管理後臺,這屆鵝廠 HR 有福了!2021-09-29
- 小夥伴問我:如何搭建Maven私服?我連夜肝了這篇實戰文章!!2020-10-05Maven
- Ghost 搭建部落格小記2017-10-21
- gitlab 服務搭建小記2024-07-27Gitlab
- 小程式學習筆記(未完待續)2021-01-01筆記
- 一次sql優化小記2008-01-17SQL優化
- 小程式分享,看這篇就夠了2018-07-10
- Executors:為什麼阿里不待見我?2021-11-11阿里
- 這一次,終於系統的學習了 JVM 記憶體結構2019-11-05JVM記憶體
- 你的年目標實現了嗎,記一次開發微信小程式2018-12-29微信小程式
- jenkins 搭建安裝小記(上)2019-01-27Jenkins
- Vue 開發經驗小記(持續更新)2019-03-05Vue
- 記一次mysql小版本升級2020-06-21MySql
- 小程式入門看這篇就夠了2019-11-06
- 面試一次次問的效能優化,這次終於答上來了2021-01-03面試優化
- 黑客又對數字貨幣下手了 這次瞄準了礦場2019-01-15黑客
- iOS開發常用小技巧記錄(持續更新)2018-07-31iOS
- 中國網際網路市值老三這次盈利了2019-08-27
- 又被node的eventloop坑了,這次是node的鍋2019-01-16OOP
- Mybatis動態對映,這次終於搞明白了2020-12-11MyBatis
- .NET,你忘記了麼?(三續)——重新理解List2009-04-06
- 記一次三個小時面試的收穫,這些問題你能回答嗎?2018-11-06面試
- 網易雲音樂故障 2 小時,這次到底誰背鍋?(今天記得領補償)2024-08-20
- SQL 如何查詢連續上漲 N 次的記錄2020-06-18SQL
- 高通驍龍筆記本:22小時續航+4G持續線上!2018-06-22筆記
- Ubuntu搭建Pytorch,就這一篇就夠了2022-07-18UbuntuPyTorch
- 亞馬遜AWS當機十小時,這次是人為原因2019-10-24亞馬遜
- 數數滑鼠墊3.0來了!這次是《遊戲出海攻略》2022-06-08遊戲
- 記一次mpvue開發完整小程式相關筆記2019-02-27Vue筆記
- 記一次小坑–關於window.open()2019-03-04
- 記一次小坑--關於window.open()2018-05-11
- 記一次小團隊Git實踐(上)2015-09-20Git
- 記一次小團隊Git實踐(中)2015-09-21Git
- 記一次小團隊Git實踐(下)2015-09-21Git
- 記錄自己第一次搭建本地fabric框架2021-03-07框架
- 【日記】這個人居然一個小時就學會了腳踏車……(2627 字)2024-08-05