Return-oriented programming
Return-oriented programmingは、スタックスマッシング攻撃の発展形である。一般にこの種類の攻撃は、攻撃者がバッファオーバーフローなどのプログラムのバグを利用してコールスタックを操作することで可能になる。バッファオーバーフローは、ユーザから受け取ったデータをメモリに保存する際に境界検査(英語版)を正常に行わない関数が、正しく保存できる量よりも多くのデータを受け取ることで発生する。大きすぎるデータがスタックに書き込まれると、関数の変数に割り当てられた空間(右の図で「Locals」と表示されている部分)をオーバーフローし、returnアドレスを上書きしてしまう場合がある。このアドレスはその後関数が制御フローを呼び出し元に戻すときに参照されるが、これが上書きされた場合、制御フローは新しいreturnアドレスが指定した位置に分岐してしまう。
一般的なバッファオーバーフロー攻撃では、攻撃者は単純に攻撃用のコード(ペイロード)をスタックに書き込み、returnアドレスをこれらの書き込んだ命令の位置に上書きする。1990年代まで、当時一般的に流通していたオペレーティングシステムにはこういった攻撃に対する防御機構が一切なかった。例えば、Microsoft Windowsには、2004年までバッファオーバーフローへの防御機構が存在しなかった。
x64プロセッサの普及に伴い、バッファオーバーフロー脆弱性を利用したコールスタック操作だけでは任意の引数のライブラリ関数呼び出しを組み立てることができなくなり、関数への最初の引数をスタックではなくレジスタに渡す新しいサブルーチン呼び出し規約に対応する必要が生じてきた。また、共有ライブラリの開発元も、システムコールのラッパー関数など、攻撃者にとって特に有用なライブラリ関数を除去したり、制限したりし始めた。結果、return-into-library攻撃を成功させることは困難になった。
これに対抗して、関数全体ではなく、ライブラリ内の関数の一部を利用して、より単純な攻撃に対する防御を備えたマシン上でバッファオーバーフローの脆弱性を突く攻撃の手法が現れた。この手法は、スタックから値をpopしてレジスタに入力する命令群を含む関数を探索することで、攻撃者が適切な値を正しいレジスタに入れ、新しい呼び出し規約の下で関数呼び出しを実行することを可能にする。攻撃の残りの部分は、通常のreturn-into-library攻撃と同様である。
Return-oriented programming(ROP)は、実行保護やコード署名(英語版)などのセキュリティ防御の機構が存在するマシンで任意コードの実行を可能にするセキュリティエクスプロイトである。
この手法では、攻撃者はコールスタックを操作してプログラムの制御フローを乗っ取り、マシンのメモリ上に存在する「ガジェット」と呼ばれる命令群を実行する。各ガジェットは通常return命令で終わり、既存のプログラムまたは共有ライブラリのコードのサブルーチンに存在する。これらのガジェットを組み合わせることで、単純な攻撃を無効化する防御機構が存在するマシンで攻撃者が任意の命令を実行できるようになる。