0Pricing
Cyber Security Academy · レッスン

Return-Oriented Programming(ROP)

ROPガジェットを連結してNX/DEPを回避し、shellcodeを使わないexploitを構築します。

「Return-Oriented Programming(ROP)」はCoddyKit上の無料Cyber Security Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはCyber Security Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Cyber Security Academyコースには全4レッスンが含まれています。

ROPが存在する理由

NX/DEPがあると、注入したシェルコードは実行できません。リターン指向プログラミング(ROP)は、ret命令で終わる既存の小さなコード列(ガジェット)を連結することで、これを回避します。新しいコードは注入せず、スタックと既存のコードだけを使用します。

ROPガジェットとは何ですか

ガジェットとは、retで終わる短い命令列のことで、バイナリやロード済みライブラリ内に存在します。例: pop rdi; ret、pop rsi; ret、mov eax, 0; ret。ガジェットはROPチェーンを構成する基本要素です。

ガジェットの検索

バイナリ内のROPガジェットを検索するツール:

# ROPgadget:
ROPgadget --binary ./vuln --rop
# ropper:
ropper -f ./vuln --search "pop rdi"
# pwntools:
from pwn import *
elf = ELF("./vuln")
rop = ROP(elf)
rop.find_gadget(["pop rdi", "ret"])

ROPチェーンの構築

ROPチェーンとは、スタック上に並べたリターンアドレスの列です。上書きされたリターンアドレスに到達すると、ガジェット1へジャンプします。ガジェット1は有用な処理を行ってからリターンし、次のアドレスを取り出してガジェット2へジャンプします。この処理を順に繰り返します。

ret2pltとGOTの上書き

ret2pltはPLT(Procedure Linkage Table)経由で関数を呼び出します。たとえばputs()を呼び出してlibcのアドレスをリークし、そのアドレスを使ってsystem()を呼び出す場合に便利です。メインバイナリでは、PIEがなければ、ASLRが有効でもPLT/GOTの構造は予測可能です。

ROPによるASLRの突破

ROPでは、puts(GOT_entry)を呼び出すガジェットを使って、GOTからlibc関数のアドレスをリークできます。リークされたアドレスからlibcのベースアドレスが判明します。system()のオフセットを計算します: system_addr = leak - libc.symbols["puts"] + libc.symbols["system"]。

SROP: シグリターン指向プログラミング

SROPはsigreturnシステムコールを使って偽のsigcontextフレームを読み込み、1つのガジェットですべてのレジスターを攻撃者が制御する値に設定します。利用可能なガジェットが少ない場合に便利です。

JOPとCOPの派生手法

ROP以外の手法:

  • JOP(Jump-Oriented Programming) — retではなくjmpで終わるガジェットを連結します
  • COP(Call-Oriented Programming) — callで終わるガジェットを連結します

CFI(Control Flow Integrity)などの防御策は、これらすべての手法を防ぐことを目指しています。

制御フローの完全性(CFI)

CFIは、間接分岐(呼び出しやリターン)が有効なターゲットにのみジャンプするよう強制します。リターン先をシャドースタックまたは許可リストと照合することで、ROPを阻止します。Intel CET(Control-flow Enforcement Technology)は、ハードウェアレベルのCFIを実装します。

実践的なROPの例

ROPを使った64ビットret2libc:

# pwntools ROP chain example:
from pwn import *
p = process("./vuln")
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
elf = ELF("./vuln")
rop = ROP(elf)
# Leak puts GOT to get libc base
rop.puts(elf.got["puts"])
rop.main()

緩和策のまとめ

ROPに対する防御策:

  • CFI — 分岐先を検証します
  • シャドースタック(CET) — ハードウェアで保護されたリターンアドレスのコピー
  • RELRO(full) — GOTを読み取り専用にして上書きを防ぎます
  • PIE — バイナリのベースアドレスをランダム化するため、ガジェットの検索にリークが必要になります

クイックチェック: ROP

ROPガジェットとは何ですか?

レッスンのまとめ

ROPは、既存のコード列(retで終わるガジェット)を連結することでNX/DEPを回避します。シェルコードを注入する必要はありません。ガジェットの検索ツールにはROPgadgetとropperがあります。ret2pltはlibcのアドレスをリークしてASLRを突破します。防御策には、CFI、シャドースタック(Intel CET)、PIE、full RELROがあります。ROPは現代のバイナリエクスプロイトの基盤です。

よくある質問

「Return-Oriented Programming(ROP)」レッスンは無料ですか?

はい。「Return-Oriented Programming(ROP)」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Cyber Security Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Cyber Security Academyコースには全4レッスンが含まれています。

「Return-Oriented Programming(ROP)」で何を学びますか?

ROPガジェットを連結してNX/DEPを回避し、shellcodeを使わないexploitを構築します。 ブラウザで直接実行するハンズオンコードでCyber Security Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Cyber Security Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのCyber Security Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「Return-Oriented Programming(ROP)」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このCyber Security Academyレッスンでコードを書いて実行できますか?

はい。すべてのCyber Security Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. スタックバッファオーバーフロー
  2. Return-Oriented Programming(ROP)
  3. フォーマット文字列脆弱性
  4. ヒープの悪用:Use-After-Freeとヒープスプレー
← Cyber Security Academyに戻る