Return-oriented programming
Return-oriented programmingは、先述のborrowed code chunks手法をベースとし、これにループや条件分岐を含むチューリング完全性を付け加えたものである。つまり、Return-oriented programmingは攻撃者が危殆化したマシン上で実行できる完全な言語を提供する。Hovav Shachamが2007年にこの手法を公表し、C標準ライブラリにリンクし、悪用可能なバッファオーバーフロー脆弱性を含むアプリケーションに対してReturn-oriented programmingを用いることであらゆるプログラミングの要素が再現可能であることを示した。
Return-oriented programmingは、その有用性や防御機構に対する耐性などの点で他の種類の攻撃よりも優れている。共有ライブラリからの危険な可能性のある関数の除去を含め、前述したいずれのエクスプロイト対策もReturn-oriented programmingに対して有効ではない。
Return-oriented programmingをベースにした攻撃を防ぐため、多くの手法が提案されてきた。それらの多くは、プログラムおよびライブラリコードの位置をランダム化し、ガジェットとして利用可能な命令の位置を攻撃者が正確に予測できないようにすることで、Return-oriented programmingのチェーンを作成できないようにするものである。この手法の実装として一般的なアドレス空間配置のランダム化(ASLR)は、プログラムの読み込み時に毎回共有ライブラリをメモリ上の別の場所に読み込む。この手法は最近の主要なオペレーティングシステムの多くで実装されているが、ASLRはinformation leakage(英語版)攻撃やその他のメモリ上の既知のライブラリの関数の位置を特定する手法に対して脆弱である。もし攻撃者が既知の命令の位置を1つ見つけるのに成功すると、その他すべての命令の位置も推測でき、Return-oriented programming攻撃を組み立てることができるからである。
さらに一歩進んで、ライブラリの位置だけでなくあらゆる命令およびその他のプログラムの状態(レジスタやスタックオブジェクト)の位置を変更することもできる。ただし、ランタイムでランダム化された命令を元に戻すため、software dynamic translatorなどの高度なランタイムサポートが必要であり、ガジェットの発見および利用を難しくする一方で、大きなオーバーヘッドが伴う。
kBouncerの手法では、オペレーティングシステムを修正し、return命令が実際にcall命令の直後の位置に制御フローを戻しているかどうかを確認する。これにより、ガジェットのチェーン化は防がれるが、大きなパフォーマンス上の負担があるほか、return命令ではなくjump命令やその他の制御フローを変更する命令を書き換えるJump-oriented programmingに対しては有効ではない。