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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  6. 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}
    レジスタに入れる値
    レジスタに入れる値

    View full-size slide

  7. 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 スタックトップポインタ
    を格納

    View full-size slide

  8. ・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 スタックトップポインタ
    を格納

    View full-size slide

  9. ・関数エピローグ時 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 スタックトップポインタ
    を格納

    View full-size slide

  10. ・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 スタックトップポインタ
    を格納

    View full-size slide

  11. ・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 スタックトップポインタ
    を格納

    View full-size slide

  12. ・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 スタックトップポインタ
    を格納

    View full-size slide

  13. ・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 スタックトップポインタ
    を格納

    View full-size slide

  14. ・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 スタックトップポインタ
    を格納

    View full-size slide

  15. 関数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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  19. やられ環境について
    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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  32. エクスプロイトコード
    32

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  41. 補足資料
    41

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide