SROP - Sigreturn-Oriented Programming
基本情報
Sigreturn
は、主にシグナルハンドラが実行を完了した後のクリーンアップに使用される特別な シスコール です。シグナルは、オペレーティングシステムによってプログラムに送信される割り込みであり、通常は何らかの例外的な状況が発生したことを示すために送信されます。プログラムがシグナルを受信すると、現在の作業を一時停止して、シグナルを処理するための シグナルハンドラ と呼ばれる特別な関数で処理します。
シグナルハンドラが終了した後、プログラムは何も起こらなかったかのように 以前の状態に戻る必要があります。 ここで sigreturn
が登場します。これにより、プログラムは シグナルハンドラから戻り、シグナルハンドラで使用されたスタックフレーム(関数呼び出しとローカル変数を格納するメモリセクション)をクリーンアップしてプログラムの状態を復元できます。
興味深いのは、sigreturn
がプログラムの状態を復元する方法です:これは、CPUのすべてのレジスタ値をスタックに保存することで行います。 シグナルがブロックされなくなると、sigreturn
はこれらの値をスタックからポップして、効果的にCPUのレジスタをシグナルが処理される前の状態にリセットします。これには、スタックポインタレジスタ(RSP)も含まれます。これは現在のスタックのトップを指すレジスタです。
ROPチェーンから sigreturn
を呼び出し、スタックにロードしたいレジストリ値を追加することで、すべてのレジスタ値を 制御 し、そのために例えば /bin/sh
で execve
シスコールを呼び出すことが可能です。
これは、他の Ret2syscall を呼び出すためのパラメータを制御しやすくする Ret2syscall の一種 であることに注意してください:
pageRet2syscall興味がある場合は、後で値を回復するためにスタックに保存される sigcontext 構造 を見てみてください(こちらの図表から)。
より詳しい説明はこちらをチェックしてください:
例
こちらの例で、signeturnへの呼び出しがROPを介して構築されているのがわかります(rxaに値0xf
を入れる)。ただし、これはそこからの最終的なエクスプロイトです:
以下は、バイナリがすでにsigreturn
を呼び出していたため、ROPを構築する必要がない場所からのexploitはこちらをチェックしてください。
その他の例と参考文献
スタックに書き込みを許可し、その後**
sigreturn
シスコールを呼び出すアセンブリバイナリ。sigreturn構造を介してret2syscall**をスタックに書き込み、バイナリのメモリ内にあるフラグを読み取ることが可能です。スタックに書き込みを許可し、その後**
sigreturn
シスコールを呼び出すアセンブリバイナリ。sigreturn構造を介してret2syscall**をスタックに書き込むことが可能です(バイナリには文字列/bin/sh
が含まれています)。64ビット、relroなし、canaryなし、nx、pieなし。
gets
関数を悪用したシンプルなバッファオーバーフローで、ret2syscallを実行します。ROPチェーンは、再度getsを呼び出して.bss
に/bin/sh
を書き込み、alarm
関数を悪用してeaxを0xf
に設定してSROPを呼び出し、シェルを実行します。64ビットアセンブリプログラム、relroなし、canaryなし、nx、pieなし。フローはスタックに書き込み、複数のレジスタを制御し、シスコールを呼び出してから
exit
を呼び出します。選択されたシスコールはsigreturn
で、レジスタを設定し、eip
を以前のシスコール命令を呼び出してmemprotect
を実行してバイナリスペースをrwx
に設定し、ESPをバイナリスペースに設定します。フローに従うと、プログラムは再度ESPにreadを呼び出しますが、この場合ESPは次の命令を指すようになるため、シェルコードを渡すと次の命令として書き込まれ、実行されます。SROPは、シェルコードが配置された場所に実行権限(memprotect)を与えるために使用されます。
Last updated