数行のコードを含む単純なプログラムで基本的な悪用テストを行っています。バッファオーバーフローの脆弱性を利用して、ROP攻撃を実行するつもりです。利用可能なガジェットを収集するには、ROPgadgetツールを使用します。 addr
のようなアドレスで非常に便利なガジェットを見つけました。このアドレスは、プログラムに対する別の正当な命令の始まりです。
このガジェットを使用することは可能ですか?使用できる場合、プロセッサはガジェットをどのように実行しますが、両方が同じアドレスで開始することを知っている正当な命令ではありませんaddr
短い答え:はい。
長い答え:
X86プロセッサの命令は、長さが1バイトから数バイトの間で異なります。 (これは、どの命令も別の命令のプレフィックスになることができないため機能します。電話番号と同じです。その背後にある理論については this guy を参照してください。)
CPUはすべてをバイトとして認識し、コンパイラの意図を知りません。そのため、実行可能メモリに命令ポインタを置いても、有効な命令にデコードする限り、CPUは気にしません。その後、なんらかのエラーが発生するまで実行を続けます。
例:
89 EB FE 40 C3
最初のバイトでジャンプすると、次のようになります。
89 EB FE 40 C3:mov EAX、0xC340FEEB
2番目のバイトでジャンプすると、次のようになります。
EB FE:jmp $、無限ループ、永久にスピンします
3バイト目でジャンプすると、次のようになります。
FE 40 C3:INC BYTE [EAX-0x30]
4バイト目でジャンプすると、次のようになります。
40:INC EAX
C3:[〜#〜] ret [〜#〜]
見て、ROPガジェット! EAXをインクリメントしてから戻ります。
プログラマーが意図した「実際の」命令はどれですか?誰も気にしない?
この全体的な概念が、x86プロセッサーでのROPを非常に簡単にするものです。例えば。命令の途中でジャンプできないMIPSは、良いガジェットを見つけるのがはるかに困難です。