$30 off During Our Annual Pro Sale. View Details »

脆弱性を自動発見してみたい

anko
March 27, 2022
100

 脆弱性を自動発見してみたい

anko

March 27, 2022
Tweet

Transcript

  1. 脆弱性を 自動発見 してみたい traP LT 2022/3/27 あんこ(21B)

  2. 自己紹介  名前 あんこ  学年 1年生  所属 CTF班など

     Twitter @Anko_9801  Github anko9801  大学に入って好きになったもの  ラーメン、イラストを描くこと  変わらず好きなもの  アニメ、Vtuber  低レイヤー、CTF(分野: Pwn, Crypto) 1
  3. はじめに  世の中にはたくさんの脆弱性がある  毎日脆弱性が報告されている  脆弱性があるとハッカーが攻撃して、サービスが停止させられてしまったり、 情報が盗まれてしまう  有名なソフトはよく脆弱性を募ってる

     BugBounty制度:特定のアプリの脆弱性を報告したらお金が貰える  より多くの人間が脆弱性を発見して より多くの人間が修正すれば安全だよね 2
  4. 実際の脆弱性ってどんなもの?  世の中には様々な種類の脆弱性がありますが、例えば脆弱性の1つである無限ループが 起きると無駄にCPUコアのリソースを使い果たし、フリーズしたり処理を妨害させら れてしまいます。 3

  5. 実際の脆弱性ってどんなもの?  世の中には様々な種類の脆弱性がありますが、例えば脆弱性の1つである無限ループが 起きると無駄にCPUコアのリソースを使い果たし、フリーズしたり処理を妨害させら れてしまいます。 int exp2(int limit) { int

    index = 1; while (index < limit) { index *= 2; } return index; } 脆弱性の具体例  例えば右のプログラムはlimitより 大きい2の累乗数を返すものです。  一見シンプルで”良い”プログラムに 見えますが、実はここには脆弱性 が存在します。 4
  6. 実際の脆弱性ってどんなもの?  世の中には様々な種類の脆弱性がありますが、例えば脆弱性の1つである無限ループが 起きると無駄にCPUコアのリソースを使い果たし、フリーズしたり処理を妨害させら れてしまいます。 int exp2(int limit) { int

    index = 1; while (index < limit) { index *= 2; } return index; } 無限ループの具体例 limitに2147483647を入れると無限ループする  例えば右のプログラムはlimitより 大きい2の累乗数を返すものです。  一見シンプルで”良い”プログラムに 見えますが、実はここには脆弱性 が存在します。  limitをintの最大値付近にすること でオーバーフローし、indexは最終 的に0になります。するとループは ずっと回り続け、無限ループに陥 ります。 5
  7. 脆弱性を検査する方法 攻撃してみる テスト/自動テスト (OWASP ZAP) 脆弱性情報と依存関 係からの脆弱性検知 (npm, yarn, Vuls)

    形式検証 (Coq, Isabelle) Fuzzing (AFL, AFL++) Symbolic Execution (angr, Triton) 6
  8. “自動”で”簡単”に脆弱性を見つけたい 7

  9. そんなものがあるわけ… 8

  10. シンボリック実行エンジン

  11. シンボリック実行エンジンとは あるプログラムについて、その入力値がどのように実行に影響するのかを分析して、 プログラムを解析するもの。 入力値を実際の値ではなく数学的なシンボルとしておき、プログラムを条件式に置き 換えて計算することで入力値を導き出せる。 代表的なシンボリック実行エンジン  angr (2016年 Shellphish)

     Triton (2015年 Quarkslab) 今回はシンボリック実行エンジンでプログラムを解析することで脆弱性を見つけ出し ます。 10
  12. シンボリック実行の具体例 (a, b) = (2, 3), (3, 2), (6, 1)

    ab = 6 ab != 6 & c = 0 ab = 6 & a <= 1 & c = 3 ab = 6 & a > 1 & c = 1 int test(int a, int b) { int c = 0; if (a * b == 6) { c = 1; if (a <= 1) c = 3; } assert(a * b * c == 6); } ∅ 11 [1]
  13. SMTソルバ シンボリック実行エンジンの仕組み 実行バイナリ 条件式の集合 SSA形式のIR レジスタ/フラグ 命令の シンボル化 Solved! SMT/SAT

    初期制約 終了制約 実行 12
  14. 自作シンボリック実行エンジン  Intel x86_64 の命令セットをシンボリック実行します。  必要最低限の命令しか実装しません。  言語はRust。SMTソルバライブラリはz3を用いる。 

    開発期間: 丸3日  (自己/相互参照構造体に苦しめられた…)  うまく動いたときの嬉しさは半端じゃない…!!ゴゴゴゴ…(うまく動いたときの音)  リポジトリ https://github.com/anko9801/mini_symbolic 13
  15. デモ(OpenSSLの脆弱性: CVE-2022-0778)  2022年3月16日に公表されたOpenSSLの重大な脆弱性。サーバーに悪意ある証 明書を送ることで無限ループを起こさせることが出来る。 cmp r12, 1 je 19

    mov rax, r12 imul rax, r12 cdq idiv rbx mov rax, rdx cmp rdx, 1 je 12 cmp rbp, 2 je 10 mov rcx, 2 imul rax, rax cdq idiv rbx mov rax, rdx … Initialized … Symbolic Executing … Solved! rax: 193 rbx: 185 rcx: 6 rdx: 64 rdi: 2 rsi: 128 rbp: 192 r12: 181 … [2] 14
  16. シンボリック実行エンジンの壁  パス爆発 条件分岐やループに到達する度、指数的にパスが増える。  探索空間の指数的増大 入力のシンボルを増やすとそれを解く時間は指数的に増加する。 15

  17. シンボリック実行エンジンの壁  パス爆発 条件分岐やループに到達する度、指数的にパスが増える。 -> Symbolic Backward Execution  探索空間の指数的増大

    入力のシンボルを増やすとそれを解く時間は指数的に増加する。 -> Fuzzingとの併用で探索空間を縮める 16
  18. シンボリック実行エンジンの壁  パス爆発 条件分岐やループに到達する度、指数的にパスが増える。 -> Symbolic Backward Execution  探索空間の指数的増大

    入力のシンボルを増やすとそれを解く時間は指数的に増加する。 -> Fuzzingとの併用で探索空間を縮める  量子コンピュータを使えたらSATは高速で解ける! 17
  19. 参考文献  [1] バイナリ萌えの彼女がシンボリック実行に恋着してますが、制約に挑む幼気な 表情が最高です!  https://speakerdeck.com/katc/bainarimeng-efalsebi-nu-gasinboritukushi-xing- nilian-zhao-sitemasuga-zhi-yue-nitiao-muyou-qi-nabiao-qing-gazui-gao-desu-1  [2]【CVE-2022-0778】OpenSSLの無限ループの脆弱性の原因解説!

     https://zenn.dev/kurenaif/articles/ec2eec4ec7ec52 18