JavaScriptを使うバイナリアンの心をくすぐる極上プレゼン
(via Ajaxian)「Heap Feng Shui (風水) in JavaScript」。
ポイントを要約すると
- Webブラウザ exploit の手法について概説
- スタックオーバフローは非常に難しい
- 一般的な heap exploitation も難しい
- ほかの可能性は?
- 配列の介在しないスタックオーバフロー (非常に稀)
- 未初期化変数
- ヒープ上のアプリケーションデータ操作
- アプリケーション固有のアロケータ
- 関数ポインタ
- オブジェクトポインタ
- 具体的事例 - WebView setSlice Exploit
- Heap spraying という手法を利用 (ひたすらヒープをシェルコードで埋める)
- 関数ポインタを書き換える方法
- オブジェクトポインタおよび仮想関数テーブルポインタを書き換える方法
- まとめると Heap spraying は exploit としては確実ではない。確実にするにはヒープをコントロールすべし。
- ヒープ風水
- アロケータの挙動は決定論的である
- 特別なアロケータ操作のシーケンスによりヒープのレイアウトを操作可能
- IE のJavaScriptにおけるヒープ風水
- IE のヒープの種類
- ヒープ上の文字列
- メモリ上でのレイアウト
- アロケーション
- ガーベジコレクション
- OLEAUT32 アロケータ
- OLEAUT32 アロケータの構造および動作フロー (確保 / 開放)
- Plunger テクニックによるアロケータの操作
- HeapLib (JavaScript で書かれたヒープ制御ライブラリ)
- IE 5-7 をサポート
- オブジェクト指向
- Windows のヒープ構造について概説
- Visual C++ のオブジェクトポインタや仮想関数テーブルのレイアウトについて概説
しかし、よくまあここまで。これは使えると思ったのは、WinDbg のブレークポイントでマクロを使ってログを出力する方法。
bc * bu 7c9106eb "j (poi(esp+4)==0x150000) '.printf \"alloc(0x%x) = 0x%x\", poi(esp+c), eax; .echo; g'; 'g';" bu ntdll!RtlFreeHeap "j ((poi(esp+4)==0x150000) & (poi(esp+c)!=0)) '.printf \" free(0x%x), size=0x%x\", poi(esp+c), wo(poi(esp+c)-8)*8-8; .echo; g'; 'g';" bd 0 1 bu jscript!JsAtan2 "j (poi(poi(esp+14)+18) == babe) '.printf \"DEBUG: %mu\", poi(poi(poi(esp+14)+8)+8); .echo; g';" bu jscript!JsAtan "j (poi(poi(esp+14)+8) == babe) '.echo DEBUG: Enabling heap breakpoints; be 0 1; g';" bu jscript!JsAsin "j (poi(poi(esp+14)+8) == babe) '.echo DEBUG: Disabling heap breakpoints; bd 0 1; g';" bu jscript!JsAcos "j (poi(poi(esp+14)+8) == babe) '.echo DEBUG: heapLib breakpoint'" g
のようにブレークポイントを設定しておいて、
heapLib.ie.prototype.debug = function(msg) { void(Math.atan2(0xbabe, msg)); }
これでメッセージを出力する、という。