Slide 1

Slide 1 text

様々なCPUアーキテクチャにおける ROP攻撃可能性の検証 北海道情報大学 多木 優馬※ 長崎県立大学 福光 正幸 北海道情報大学 湯村 翼 1 ※4月より、GMOサイバーセキュリティ byイエラエ株式会社に就職

Slide 2

Slide 2 text

概要 背景 ・ROP攻撃の活⽤法が増える ・組込み機器への影響は未知数 →検証が要必要 貢献 ・組込み機器を想定したやられ環境を3種類⽤意しROP攻撃を検証した ・x86, ARM32環境への攻撃は成⽴、ARM64環境への攻撃は不成⽴であった 結論 ・ 関数呼び出しの⽅法⼀つでリターンアドレス書き換えの緩和が可能 2 ROP攻撃, 各環境の詳細は後述 検証対象 アーキ テクチャ 実行 ステート OS ROP攻撃 成立可否 x86環境 x86 - CentOS6 〇 ARM32環境 Armv8-A AArch32 RaspiOS 〇 ARM64環境 Armv8-A AArch64 Nuttx ×

Slide 3

Slide 3 text

背景 ・IoTの普及により組込み機器の増加 性能不⾜でセキュリティ機能が⼗分に実装されていない機器もある ・IoT攻撃事例| マルウェア”Mirai” Miraiによって乗っ取られたIoT機器はDDoS攻撃に利⽤され、 AmazonやTwitterといったサービスをアクセス困難な状態に陥れた。 Attack! 3 Hijack!

Slide 4

Slide 4 text

ROP攻撃の危険性 悪用例 ・ROP攻撃を利用したマルウェアの作成 ・Blind ROP攻撃によるサーバの乗っ取り 4 高い攻撃力 セキュリティ機構の回避 コンピュータの乗っ取り 広い攻撃範囲 パソコン スマートフォン 組込み機器 高い汎用性 Blind ROP, kROPなど、 派⽣技術が多様

Slide 5

Slide 5 text

ROP攻撃の概要 ・スタックバッファオーバーフロー攻撃を応⽤した攻撃 ・任意の処理を⾏わせることができる ・NXbitの回避 NX bit: 指定した領域外でのコード実⾏を禁⽌するセキュリティ機構 ・攻撃対象のアセンブリ命令のかたまり(命令⽚)を繋ぎ合わせ、 ROPチェーンを構築してスタック領域に埋め込む 5

Slide 6

Slide 6 text

ROP攻撃の原理 正常なプログラムの コード領域 命令片1 命令片2 命令片3 ROPチェーン 攻撃に必要な 命令片を集める 実⾏ファイル ROPチェーン 埋め込み コード領域 データ領域 6 … … 0x10694: pop {r4, r5, r6, r7, r8, sb, sl, pc} 0x103ac: pop {r3, pc} 0x10684: mov r0, r7 0x10688: blx r3 0x1067c: mov r2, r9 0x10680: mov r1, r8 0x103ac: pop {r3, pc} 0x10684: mov r0, r7 0x10688: blx r3 0x10694: pop {r4, r5, r6, r7, r8, sb, sl, pc} レジスタに入れる値 レジスタに入れる値 0x103ac: pop {r3, pc} 0x10684: mov r0, r7 0x10688: blx r3 0x10694: pop {r4, r5, r6, r7, r8, sb, sl, pc} レジスタに入れる値 レジスタに入れる値

Slide 7

Slide 7 text

ARM32へのROP例 ・system(“/bin/sh”)を呼び出して制御を奪う例 アセンブリ命令 pop xx: spが指す値をxxレジスタに格納 blx xx: xxレジスタが格納するポインタにジャンプ 0x103ac: pop {r3, pc} : 0x10684: mov r0, r7 0x10688: blx r3 : 0x10694: pop {r4, r5, r6, r7, r8, sb, sl, pc} : コード領域 buf (0x10) fp sp fp + 4 ! ! ! スタック領域 7 saved fp リターンアドレス レジスタ r0 関数の第一引数を格納 r3 汎用レジスタ r7 汎用レジスタ pc 次に実行する 命令ポインタを格納 fp スタックフレームポインタ を格納 sp スタックトップポインタ を格納

Slide 8

Slide 8 text

・bofによるROPチェーン埋め込み時 0x103ac: pop {r3, pc} : 0x10684: mov r0, r7 0x10688: blx r3 : 0x10694: pop {r4, r5, r6, r7, r8, sb, sl, pc} : AAAAAAAAAAAAAAAA fp sp fp + 4 スタック領域 8 AAAA 0x103ac systemの実アドレス 0x10694 ‘A’ * 12 “/bin/sh”のアドレス ‘A’ * 12 0x10684 アセンブリ命令 pop xx: spが指す値をxxレジスタに格納 blx xx: xxレジスタが格納するポインタにジャンプ ARM32へのROP例 コード領域 レジスタ r0 関数の第一引数を格納 r3 汎用レジスタ r7 汎用レジスタ pc 次に実行する 命令ポインタを格納 fp スタックフレームポインタ を格納 sp スタックトップポインタ を格納

Slide 9

Slide 9 text

・関数エピローグ時 pop {fp, pc} 0x103ac: pop {r3, pc} : 0x10684: mov r0, r7 0x10688: blx r3 : 0x10694: pop {r4, r5, r6, r7, r8, sb, sl, pc} : AAAAAAAAAAAAAAAA sp スタック領域 9 AAAA 0x103ac systemの実アドレス 0x10694 ‘A’ * 12 “/bin/sh”のアドレス ‘A’ * 12 0x10684 アセンブリ命令 pop xx: spが指す値をxxレジスタに格納 blx xx: xxレジスタが格納するポインタにジャンプ ARM32へのROP例 コード領域 レジスタ r0 関数の第一引数を格納 r3 汎用レジスタ r7 汎用レジスタ pc 0x103ac fp 0x41414141 sp スタックトップポインタ を格納

Slide 10

Slide 10 text

・pop {r3, pc} 0x103ac: pop {r3, pc} : 0x10684: mov r0, r7 0x10688: blx r3 : 0x10694: pop {r4, r5, r6, r7, r8, sb, sl, pc} : AAAAAAAAAAAAAAAA sp スタック領域 10 AAAA 0x103ac systemの実アドレス 0x10694 ‘A’ * 12 “/bin/sh”のアドレス ‘A’ * 12 0x10684 アセンブリ命令 pop xx: spが指す値をxxレジスタに格納 blx xx: xxレジスタが格納するポインタにジャンプ ARM32へのROP例 コード領域 レジスタ r0 関数の第一引数を格納 r3 systemの実アドレス r7 汎用レジスタ pc 0x10694 fp 0x41414141 sp スタックトップポインタ を格納

Slide 11

Slide 11 text

・pop {r4, r5, r6, r7, r8, sb, sl, pc} 0x103ac: pop {r3, pc} : 0x10684: mov r0, r7 0x10688: blx r3 : 0x10694: pop {r4, r5, r6, r7, r8, sb, sl, pc} : AAAAAAAAAAAAAAAA sp スタック領域 11 AAAA 0x103ac systemの実アドレス 0x10694 ‘A’ * 12 “/bin/sh”のアドレス ‘A’ * 12 0x10684 アセンブリ命令 pop xx: spが指す値をxxレジスタに格納 blx xx: xxレジスタが格納するポインタにジャンプ ARM32へのROP例 コード領域 レジスタ r0 関数の第一引数を格納 r3 systemの実アドレス r7 “/bin/sh”のアドレス pc 0x10684 fp 0x41414141 sp スタックトップポインタ を格納

Slide 12

Slide 12 text

・mov r0, r7 0x103ac: pop {r3, pc} : 0x10684: mov r0, r7 0x10688: blx r3 : 0x10694: pop {r4, r5, r6, r7, r8, sb, sl, pc} : AAAAAAAAAAAAAAAA sp スタック領域 12 AAAA 0x103ac systemの実アドレス 0x10694 ‘A’ * 12 “/bin/sh”のアドレス ‘A’ * 12 0x10684 アセンブリ命令 pop xx: spが指す値をxxレジスタに格納 blx xx: xxレジスタが格納するポインタにジャンプ ARM32へのROP例 コード領域 レジスタ r0 “/bin/sh”のアドレス r3 systemの実アドレス r7 “/bin/sh”のアドレス pc 0x10688 fp 0x41414141 sp スタックトップポインタ を格納

Slide 13

Slide 13 text

・blx r3 0x103ac: pop {r3, pc} : 0x10684: mov r0, r7 0x10688: blx r3 : 0x10694: pop {r4, r5, r6, r7, r8, sb, sl, pc} : AAAAAAAAAAAAAAAA sp スタック領域 13 AAAA 0x103ac systemの実アドレス 0x10694 ‘A’ * 12 “/bin/sh”のアドレス ‘A’ * 12 0x10684 アセンブリ命令 pop xx: spが指す値をxxレジスタに格納 blx xx: xxレジスタが格納するポインタにジャンプ ARM32へのROP例 コード領域 レジスタ r0 “/bin/sh”のアドレス r3 systemの実アドレス r7 “/bin/sh”のアドレス pc systemの実アドレス fp 0x41414141 sp スタックトップポインタ を格納

Slide 14

Slide 14 text

・system(“/bin/sh”)の実行 0x103ac: pop {r3, pc} : 0x10684: mov r0, r7 0x10688: blx r3 : 0x10694: pop {r4, r5, r6, r7, r8, sb, sl, pc} : AAAAAAAAAAAAAAAA sp スタック領域 14 AAAA 0x103ac systemの実アドレス 0x10694 ‘A’ * 12 “/bin/sh”のアドレス ‘A’ * 12 0x10684 アセンブリ命令 pop xx: spが指す値をxxレジスタに格納 blx xx: xxレジスタが格納するポインタにジャンプ ARM32へのROP例 コード領域 レジスタ r0 “/bin/sh”のアドレス r3 systemの実アドレス r7 “/bin/sh”のアドレス pc systemの実アドレス+4 fp 0x41414141 sp スタックトップポインタ を格納

Slide 15

Slide 15 text

関数2 ROP攻撃対策の先行研究 ・Control-Flow Integrity (CFI) - ROP対策としてCFIというセキュリティ機構が存在する - 制御フローを監視し、ROP攻撃を防ぐ - 組込み機器で使われるArmv8-Mアーキテクチャでは CFI実装が進む[4] - 組込み機器は種類が多く、CFIが実装できていないものもある 15 CFI Arm AVR RISC-V Mips [4]河⽥ 智明ら,Arm TrustZone for Armv8-Mを利⽤したマルチタスク対応CFIの検討(2018) 関数1 関数3 関数1

Slide 16

Slide 16 text

本研究の目的 ・CFIやASLRなどのROP対策が施されておらず、脆弱な組込み機器を調査する ・様々な組込み向けCPUアーキテクチャを対象にROP攻撃検証を行うことで、 脆弱な組込み機器の調査を行うとともに、 ROP攻撃対策が施されている機器とその対策内容について調査する。 ・検証結果をもとに、低スペックなプロセッサでも実装できるような ROP攻撃対策を考案する 16

Slide 17

Slide 17 text

検証概要 ・3種類のやられ環境を用意してROP攻撃検証を行った。 ・外部に影響をもたらさないようやられ環境はQEMUを用いて構築。 ・アーキテクチャの違いに着目するため、 OSやコンパイラ側で提供されるセキュリティ機構を無効化 17 攻撃環境 やられ環境 エクスプロイトコード 脆弱性のある テストプログラム 攻撃 ホストOS ゲストOS シェルを奪いたい

Slide 18

Slide 18 text

研究倫理配慮 ・QEMUの設定により、やられ環境はホスト環境以外との通信を遮断している ・攻撃検証はテストプログラムに対して行われ、 特定の製品やサービスに影響を与えるものではない 18

Slide 19

Slide 19 text

やられ環境について 19 検証対象 プロセッサ アーキ テクチャ OS 実行 ステート (A) x86環境 i686 x86 CentOS6 - (B) ARM32環境 Arm Cortex-A53 Armv8-A RaspiOS AArch32 (C) ARM64環境 Arm Cortex-A53 Armv8-A Nuttx AArch64

Slide 20

Slide 20 text

テストプログラムについて x86, ARM32で使用したテストプログラム 坂井氏のROP検証用プログラム[12]を使用 20 ARM64で使用したテストプログラム 自作のテストプログラム [12]坂井弘亮,ROP実験⽤サンプル,http://kozos.jp/samples/rop-sample.html

Slide 21

Slide 21 text

攻撃側環境 ・攻撃者の想定 - 攻撃対象プログラムの実行ファイルを持っており様々な解析が可能 ・命令片の探索 - 解析ツール(rp++,ropper)を使用し、攻撃に使える命令片を探索 ・エクスプロイトコードの作成 - 対象のアーキテクチャに合わせてROPチェーンを作成 - Pwntoolsを用いてROPチェーンを埋め込む攻撃コードを作成 21

Slide 22

Slide 22 text

x86環境 22 検証対象 OS アーキテクチャ設計の違い ROP攻撃 成立可否 LRの有無 命令長 PCの直接 書き換え可否 (A) x86環境 CentOS6 × 可変長 × 〇

Slide 23

Slide 23 text

x86の関数呼び出し ・関数呼び出し側 (caller)の処理 call命令でリターンアドレスのpushと、 関数へのジャンプを行う。 ・呼び出された関数側 (callee)の処理 callerのスタックベースポインタを pushした後、バッファの確保を行う。 23 buffer caller EBP リターンアドレス buffer caller EBP リターンアドレス

Slide 24

Slide 24 text

エクスプロイトコードについて 24

Slide 25

Slide 25 text

操作中端末 操作中端末 シェルを 奪取したい x86環境 Attack! 25

Slide 26

Slide 26 text

ARM32環境 26 検証対象 OS アーキテクチャ設計の違い ROP攻撃 成立可否 LRの有無 命令長 PCの直接 書き換え可否 (B) ARM32 環境 Raspi OS 〇 固定長 〇 〇 実行ステート: AArch32

Slide 27

Slide 27 text

ARM32の関数呼び出し ・callerの処理 bl命令でリターンアドレスを リンクレジスタに格納して関数にジャンプ ・calleeの処理 基本的に、関数プロローグ時に push {fp, lr}命令があり、 その後にバッファを用意する。 27 buffer saved fp リターンアドレス buffer saved fp リターンアドレス

Slide 28

Slide 28 text

エクスプロイトコードについて 28

Slide 29

Slide 29 text

ARM32環境 操作中端末 操作中端末 シェルを 奪取したい Attack! 29

Slide 30

Slide 30 text

ARM64環境 30 実行ステート: AArch64 検証対象 OS アーキテクチャ設計の違い ROP攻撃 成立可否 LRの有無 命令長 PCの直接 書き換え可否 (C) ARM64 環境 Nuttx 〇 固定長 × ×

Slide 31

Slide 31 text

ARM64の関数呼び出し 31 ・callerの処理 bl命令でリターンアドレスを リンクレジスタに格納して関数にジャンプ ・calleeの処理 リンクレジスタのpushは任意のタイミングで 行われる。用意するバッファよりも上に リターンアドレスが配置されることもある buffer1 退避レジスタ リターンアドレス buffer2

Slide 32

Slide 32 text

エクスプロイトコード 32

Slide 33

Slide 33 text

解析デモ 33 バッファオーバーフローを起こす脆弱な関数roptest_mainにジャンプする直前 LRとしてpushされる

Slide 34

Slide 34 text

解析デモ 34 roptest_mainにジャンプした直後のスタック領域 バッファオーバーフロー直後のスタック領域

Slide 35

Slide 35 text

検証結果 セキュリティ機構が無効であっても関数呼び出し⽅法⼀つで BOF攻撃、ひいてはROP攻撃を緩和できることが分かった。 35 検証対象 OS アーキテクチャ設計の違い ROP攻撃 成立可否 LRの有無 命令長 PCの直接 書き換え可否 (A) x86環境 CentOS6 × 可変長 × 〇 (B) ARM32 環境 RaspiOS 〇 固定長 〇 〇 (C) ARM64 環境 Nuttx 〇 固定長 × ×

Slide 36

Slide 36 text

考察 x86/ARM32環境でのROP攻撃可能性 ・ASLR, SSPについては環境によっては回避が可能 ・適切に実装されたCFIの回避は困難 →CFIの実装が重要 36

Slide 37

Slide 37 text

考察 ARM64環境へのROP攻撃可能性 ・ARMv8.3から実装されたPointer Authentication Code (PAC) 関数ポインタの先頭16bitに認証コードを埋め込み、ROP攻撃を検出する ・ROP攻撃を困難にするアーキテクチャ設計 - 固定命令長 - PCレジスタの書き換え禁止 - リターンアドレス書き換えの緩和 37 リターンアドレスを格納できるレジスタを用意し そのレジスタの値のpushをcalleeに委ねることができる 設計にすれば他のアーキテクチャで実現可能

Slide 38

Slide 38 text

おわりに ・3種類のやられ環境に対してROP攻撃検証を行い、 x86,ARM32環境への攻撃は成立、ARM64環境への攻撃は不成立であった ・ARM64は、アーキテクチャ設計によりROP攻撃が困難。 アーキテクチャ設計での攻撃対策を行うことで、 低リソースな組込み機器でもROP攻撃対策が見込める 38 検証対象 アーキ テクチャ 実行 ステート OS ROP攻撃 成立可否 x86環境 x86 - CentOS6 〇 ARM32環境 Armv8-A AArch32 RaspiOS 〇 ARM64環境 Armv8-A AArch64 Nuttx ×

Slide 39

Slide 39 text

謝辞 国立研究開発法人情報通信研究機構主催のSecHack365にて, トレーナーの坂井弘亮氏よりご教示いただいたプログラムの動作原理と デバッグ手法の知識が本研究を実地するうえでの礎となりました. 坂井氏ならびにSecHack365関係者の皆様に感謝申し上げます. 39

Slide 40

Slide 40 text

参考文献 40 [4]河⽥ 智明ら,Arm TrustZone for Armv8-Mを利⽤したマルチタスク対応CFIの検討(2018) [12]坂井弘亮,ROP実験⽤サンプル, http://kozos.jp/samples/rop-sample.html

Slide 41

Slide 41 text

補足資料 41

Slide 42

Slide 42 text

本研究で使用した攻撃技術の詳細 42

Slide 43

Slide 43 text

バッファオーバーフロー攻撃 ・プログラムが想定されるサイズを超えるデータをバッファに⼊⼒し、 誤作動やコンピュータの乗っ取りを⾏う攻撃。 スタック領域に対するBOF攻撃をスタックバッファオーバーフロー攻撃という。 43 変数A 変数B AAAA AAAA AAAA AAAA 変数AにBOF攻撃 変数Bの値を改ざん スタックバッファオーバーフローの例

Slide 44

Slide 44 text

ROP攻撃 ・スタックバッファオーバーフロー攻撃を応⽤した攻撃。 攻撃対象のアセンブリ命令のかたまり(命令⽚)を繋ぎ合わせ、 ROPチェーンを構築してスタック領域に埋め込むことで、 任意の処理を⾏わせることができる。 ・スタック領域に存在する関数のリターンアドレスを書き換え可能にし、 そこへROPチェーンを書き込むことでプログラムの制御を奪うことができる。 44

Slide 45

Slide 45 text

攻撃検証で行った各種解析 ・objdumpによる逆アセンブル ・rp++/ropperによる命令⽚の探索 ・stringsコマンドによる、印字可能⽂字のアドレスの特定 ・GDBデバッガによる動的解析 45

Slide 46

Slide 46 text

本発表で登場したセキュリティ機構の詳細 46

Slide 47

Slide 47 text

Non eXecutable bit (NX bit) ・指定した領域外でのコード実⾏を禁⽌にするセキュリティ機構。 攻撃コードがスタック領域に埋め込まれても、実⾏を阻⽌できる。 ・メモリ管理に使⽤されるページテーブル上で各ページにNX bitがあり、 NX bitに1がセットされていたらそのページが指すコードは実⾏禁⽌となる。 ・ROP攻撃により突破が可能。ROP攻撃はROPチェーンに沿って 正常なプログラムの命令にジャンプしているだけであり、 コードを実⾏しているわけではないため。 47

Slide 48

Slide 48 text

Address Space Layout Randomization (ASLR) ・実⾏ファイルのコード領域などのメモリアドレスをランダム化し、 特定のコードやデータの不正利⽤を困難にするセキュリティ機構。 ・コード領域やデータ領域といった領域単位でランダム化を⾏う。 なお、関数単位でランダム化を⾏うFGKASLRも研究されている。 ・領域単位でのランダム化では、変数や関数のオフセットアドレスは 変化しないため、1つでもアドレスが特定できれば、 そのアドレスとオフセットアドレスを⽤いて任意のアドレスの特定が可能。 48

Slide 49

Slide 49 text

Stack Smash Protection (SSP) ・スタックバッファオーバーフロー攻撃を検知するセキュリティ機構。 ・スタック領域に乱数値(カナリア)を挿⼊し、 その値が書き換えられていたら、 スタックバッファオーバーフロー攻撃を受けたものとみなし、 プログラムを強制終了して保護する。 ・ヌル⽂字に関するバグImproper Null Terminationにより、 カナリアを特定することができる。 また、環境によってはBlind ROPによってカナリアを特定できたりなど、 カナリア特定の⽅法は多い。 49

Slide 50

Slide 50 text

Control-Flow Integrity (CFI) ・プログラム実⾏中に不正な制御フローを検知するセキュリティ機構 ・呼び出した関数の引数や戻り値が適切か、 関数呼び出しから戻った先のアドレスが適切かの検査を⾏い、 ROP攻撃時に発⽣するような不正な制御フローを検知する。 ・コンパイラでCFIの設定を⾏うが、 -fno-sanitize-trapオプションが指定時に、 検知の回避が可能であることが確認されている[3]。 50