リターン指向プログラミング(ROP)
リターン指向プログラミング(ROP) とは何ですか?
リターン指向プログラミング(ROP)ROP は、RET で終わる短い命令列(ガジェット)を連結して、新しいコードを注入することなく任意の計算を実現するコード再利用型のエクスプロイト手法です。
Hovav Shacham は 2007 年の論文「The Geometry of Innocent Flesh on the Bone」で ROP を提唱し、return-into-libc をチューリング完全な計算へ一般化できること、それにより DEP/W^X を無力化できることを示しました。攻撃者はスタックを破壊し、それぞれが短いガジェット(RET で終わる数命令)を指すアドレスの連鎖を書き込みます。各ガジェットの実行後、RET が次のアドレスを取り出すため、制御は既存の実行可能バイト列(libc、プログラム本体、各種ライブラリ)の中を流れ、DEP が検知できる注入コードは存在しません。
各ガジェットのアドレスは絶対値なので、ROP はコードがメモリ上のどこにあるかを知っている必要があり、それこそが ASLR がランダム化する対象です。そのため実際のエクスプロイトは情報漏洩と組み合わせられます。派生として、JOP(ジャンプ)や COP(コール)はリターンの代わりに間接ジャンプ/コールを連結し、SROP(sigreturn)はカーネルのシグナルフレーム復元を悪用して全レジスタを一度に設定します。Blind ROP(Bittau ら, 2014)はバイナリなしでもクラッシュを観測して遠隔サービスに対する連鎖を構築します。
ROP は一世代分の緩和策が生まれた主因です。防御は三つの面のいずれかを狙います。ガジェットの可用性、制御フロー整合性、あるいはソースでのメモリ安全性です。Intel CET(Tiger Lake 以降、2020 年)は改ざんされた戻りアドレスを検出するハードウェア シャドースタックと、JOP/COP に対する Indirect Branch Tracking(endbr64)を強制します。ARM は Pointer Authentication と BTI を提供します。Rust のようなメモリ安全言語は、連鎖の起点となる破壊バグそのものを排除します。
flowchart TD A["メモリ破壊バグ<br/>スタックオーバーフロー"] --> B["戻りアドレスを上書き"] B --> C["スタックに<br/>ガジェット連鎖が並ぶ"] C --> G1["ガジェット1: pop rdi, ret"] G1 --> G2["ガジェット2: pop rsi, ret"] G2 --> G3["ガジェット3: syscall, ret"] G3 --> X["execve /bin/sh"] D1["DEP: スタック実行不可"] -. 再利用で回避 .-> C D2["ASLR"] -. 情報漏洩が必要 .-> C D3["Intel CET シャドースタック"] -. 不正な RET を阻止 .-> G1
● 例
- 01
glibc の pop-rdi/syscall ガジェットを連結して execve("/bin/sh") を呼び出す。
- 02
KASLR の漏洩を利用して ROP で commit_creds(prepare_kernel_cred(0)) に到達する。
● よくある質問
リターン指向プログラミング(ROP) とは何ですか?
ROP は、RET で終わる短い命令列(ガジェット)を連結して、新しいコードを注入することなく任意の計算を実現するコード再利用型のエクスプロイト手法です。 サイバーセキュリティの アプリケーションセキュリティ カテゴリに属します。
リターン指向プログラミング(ROP) とはどういう意味ですか?
ROP は、RET で終わる短い命令列(ガジェット)を連結して、新しいコードを注入することなく任意の計算を実現するコード再利用型のエクスプロイト手法です。
リターン指向プログラミング(ROP) からどのように防御しますか?
リターン指向プログラミング(ROP) に対する防御は通常、上記の定義で述べたとおり、技術的統制と運用上の実践を組み合わせます。
リターン指向プログラミング(ROP) の別名は何ですか?
一般的な別名: ROP, コード再利用攻撃, Return-to-libc。