Upgrade to Pro — share decks privately, control downloads, hide ads and more …

様々なCPUアーキテクチャにおけるROP攻撃 / CSEC100

yumulab
March 06, 2023

様々なCPUアーキテクチャにおけるROP攻撃 / CSEC100

多木 優馬, 福光 正幸, 湯村 翼. 様々なCPUアーキテクチャにおけるROP攻撃可能性の検証, 情報処理学会第100回コンピュータセキュリティ(CSEC)研究会の発表資料

yumulab

March 06, 2023
Tweet

More Decks by yumulab

Other Decks in Research

Transcript

  1. 概要 背景 ・ROP攻撃の活⽤法が増える ・組込み機器への影響は未知数 →検証が要必要 貢献 ・組込み機器を想定したやられ環境を3種類⽤意しROP攻撃を検証した ・x86, ARM32環境への攻撃は成⽴、ARM64環境への攻撃は不成⽴であった 結論

    ・ 関数呼び出しの⽅法⼀つでリターンアドレス書き換えの緩和が可能 2 ROP攻撃, 各環境の詳細は後述 検証対象 アーキ テクチャ 実行 ステート OS ROP攻撃 成立可否 x86環境 x86 - CentOS6 〇 ARM32環境 Armv8-A AArch32 RaspiOS 〇 ARM64環境 Armv8-A AArch64 Nuttx ×
  2. 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} レジスタに入れる値 レジスタに入れる値
  3. 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 スタックトップポインタ を格納
  4. ・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 スタックトップポインタ を格納
  5. ・関数エピローグ時 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 スタックトップポインタ を格納
  6. ・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 スタックトップポインタ を格納
  7. ・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 スタックトップポインタ を格納
  8. ・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 スタックトップポインタ を格納
  9. ・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 スタックトップポインタ を格納
  10. ・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 スタックトップポインタ を格納
  11. 関数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
  12. やられ環境について 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
  13. ARM32環境 26 検証対象 OS アーキテクチャ設計の違い ROP攻撃 成立可否 LRの有無 命令長 PCの直接

    書き換え可否 (B) ARM32 環境 Raspi OS 〇 固定長 〇 〇 実行ステート: AArch32
  14. 検証結果 セキュリティ機構が無効であっても関数呼び出し⽅法⼀つで BOF攻撃、ひいてはROP攻撃を緩和できることが分かった。 35 検証対象 OS アーキテクチャ設計の違い ROP攻撃 成立可否 LRの有無

    命令長 PCの直接 書き換え可否 (A) x86環境 CentOS6 × 可変長 × 〇 (B) ARM32 環境 RaspiOS 〇 固定長 〇 〇 (C) ARM64 環境 Nuttx 〇 固定長 × ×
  15. 考察 ARM64環境へのROP攻撃可能性 ・ARMv8.3から実装されたPointer Authentication Code (PAC) 関数ポインタの先頭16bitに認証コードを埋め込み、ROP攻撃を検出する ・ROP攻撃を困難にするアーキテクチャ設計 - 固定命令長

    - PCレジスタの書き換え禁止 - リターンアドレス書き換えの緩和 37 リターンアドレスを格納できるレジスタを用意し そのレジスタの値のpushをcalleeに委ねることができる 設計にすれば他のアーキテクチャで実現可能
  16. Non eXecutable bit (NX bit) ・指定した領域外でのコード実⾏を禁⽌にするセキュリティ機構。 攻撃コードがスタック領域に埋め込まれても、実⾏を阻⽌できる。 ・メモリ管理に使⽤されるページテーブル上で各ページにNX bitがあり、 NX

    bitに1がセットされていたらそのページが指すコードは実⾏禁⽌となる。 ・ROP攻撃により突破が可能。ROP攻撃はROPチェーンに沿って 正常なプログラムの命令にジャンプしているだけであり、 コードを実⾏しているわけではないため。 47