【注意】このサイトに記載されていることを他人に試すことは「不正アクセス禁止法」に該当する場合があります。詳しくはこちらから

ハッカーの裏ワザ Return-Oriented Programming(ROP)とは 防御をすり抜ける仕組みと対策

ペネトレーションテスト&バグバウンティ

ROP(リターン・オリエンテッド・プログラミング)は、ちょっと頭のいいハッカーが使う裏ワザ的な攻撃方法なんです。
ふつう、パソコンは「悪いプログラム」が動かないように守られています。でも、ROPを使うと「正しいプログラムの中の一部だけ」をつなぎ合わせて、まるでレゴブロックのように別の命令を作ってしまうんです。

※イメージです。

ROPとは

コンピュータのプログラムを攻撃する手法の一つに「ROP(Return-Oriented Programming)」という技術があります。これは、「関数の返り先(Returnアドレス)」をうまく操作して、悪意ある命令を実行する方法です。
 
ROPはバッファオーバーフロー攻撃の進化版ともいえ、近年のセキュリティ機構(NXビットなど)をすり抜けるために使われます。
 

スタック・関数・リターンアドレスのおさらい

C言語のようなプログラミングでは、関数を呼び出すたびにスタックというメモリの一時領域が使われます。関数が終わると元の場所に戻るため、returnアドレス(復帰先の場所)がスタックに保存されています。
ここが攻撃の「入り口」になります。
 
 

なぜROPが使われるのか

近年のOSは「NXビット」などを使って、ヒープやスタックでコードを実行できないようにする防御をしています。
でも、.text領域(実行可能コード)の中にある命令をうまくつなぎ合わせれば、攻撃コードを置かずに悪さができるのです。
これがROPの核心です。
 
 

ROPの攻撃の流れ

1.バッファオーバーフローなどで、リターンアドレスを上書き
2.攻撃者が指定した 小さなコード片(ガジェット) に飛ぶ
3.複数のガジェットを順番に実行させて、意図した動作を実現する
 
※ガジェット = 「ret」で終わる短い命令セット(例:pop rdi; ret など)

ガジェットとは

攻撃者は「バイナリ解析ツール(例:ROPgadget、radare2、Ghidra)」を使って、実行ファイル中の「retで終わる命令」を探します。
こうした小さなコード断片を「ガジェット」と呼び、これをレゴのように組み合わせて目的の処理を作るのです。
 
たとえば、次のようなことが可能になります。
・pop rdi; ret → 引数に「/bin/sh」を渡す
・system 関数を呼び出して、シェルを起動する
つまり、自前のシェルコードを書かずに、既存の関数を使って攻撃するのがROPです。
 
難しいですね。
「pop rdi; ret」は、C言語ではありません。
これは、C言語で書かれたプログラムがコンパイルされたあとの機械語レベル(アセンブリ言語)での命令になります。
ROPでよく使われる命令「pop rdi; ret」は、関数に引数を渡すための基本的な「ガジェット(gadget)」 です。
 
「pop rdi; ret」を説明すると
1.pop rdi
意味:スタックの一番上(top)にある値を、rdiというレジスタに入れる。
レジスタとは、CPUの中にある「データの一時保存場所」。
rdiとは、x86_64 Linuxで、関数の第1引数を渡すときに使う場所。
 
2.ret
意味:スタックの次のアドレスにジャンプ。(次に実行する命令へ飛ぶ)
ROPでは、次の「ガジェット」や「関数」へ流れをつなげるために使います。
 
使い方は
たとえば、ROPで system("/bin/sh") を呼びたいときは、
rdiに /bin/sh のアドレスをセット(第1引数)
次に、retで system 関数にジャンプ
 
そのために、次のようなROPチェーンを作ります。
[pop rdi; ret] 
 ↓
[/bin/shのアドレス]
 ↓
[system関数アドレス]
 

なぜ、system関数に飛ばすのか

それは、ROPチェーンの最終的な目的が、system()関数を「実行すること」だからです。
system()関数とは、C言語の標準関数のひとつで、シェルコマンド(例: /bin/sh)を実行できる関数なのです。
要は、「攻撃者がパソコンを自由に操作できるようになる」からです。
 
こんなことができます。
system("ls");        // ファイル一覧を表示
system("whoami");    // 今のユーザー名を表示
system("/bin/sh");   // シェル(コマンド画面)を開く
 
上記を利用して、攻撃者は、悪いことをするために、
・ファイルを盗み見たり
・管理者の操作をしたり
・ウイルスを入れたり
などを行います。
 
 

防御方法

ROPを防ぐには、いくつかの方法があります。
・ASLR(アドレス空間配置のランダム化)
→ ガジェットの位置をランダムにして、攻撃を困難にする
・Stack Canaries
→ リターンアドレスの前に「番犬(カナリ)」を置いて改ざん検出
・Control Flow Integrity(CFI)
→ 正常な関数呼び出し以外は拒否する仕組み
 
 

ハッカーの裏ワザ Return-Oriented Programming(ROP)とは 防御をすり抜ける仕組みと対策のまとめ

Return-Oriented Programming(ROP)は、パソコンの防御機能(NXビットなど)をすり抜けるハッカーの巧妙な手口です。
悪意あるコードを直接実行する代わりに、既存のプログラム内の「短い命令のかたまり(ガジェット)」を組み合わせて、あたかも自分のコードのように実行させます。リターンアドレスを書き換え、スタック上にROPチェーンを並べることで攻撃を成立させます。
対策としては、ASLR(アドレスのランダム化)やスタックカナリ、制御フローの検証(CFI)などが有効です。ROPの仕組みを知ることで、防御を強化できます。
 
「防御の仕組みをくぐり抜ける方法」を知ることは、守る側にとっても重要です。
ハッカーの思考を知って、より強い防御を作りましょう。