19.3K Views
October 04, 24
スライド概要
GMOサイバーセキュリティ byイエラエ株式会社
登壇者 • 山崎 啓太郎 (@tyage) • 高度診断部 アプリケーションセキュリティ課 • CTF Team: TokyoWesterns, binja • 金子 孟司 (@arkark_) • 高度診断部 アプリケーションセキュリティ課 • CTF Team: ./Vespiary
テーマ: 業務で役に立ったCTFテク • 「月刊〇〇(競技)は役に立たない」はよく話題になる • 先日Flattさんからも似たような記事(*1)が • Web診断目線で「これCTFでやったところだ!」というのを紹介 • (最初はXS-Leaksの予定でしたが10分で話すには難しかった…) (*1) https://blog.flatt.tech/entry/ctf_vs_product_security
アジェンダ • 初級編 • 中級編 • 上級編
初級編 – 特定文字(列)の禁止/無害化を 回避するCTF問題
特定の文字(列)を禁止/無害化する問題 • *jail系(PHPJail, JSJail, PyJail) • 禁止された文字を使わずにコードを書く • jail問だけ集めたjailCTFなんかも 大量の禁止ワード chall.stypr.com https://github.com/stypr/chall.stypr.com/blob/master/challenges/docker/chall/chall-phpsandbox/www/index.php
特定の文字(列)を禁止/無害化する問題 • WAF系 • Cha’s Wall - CODEGATE CTF 2024 Preliminaries • WAF: Go製。PHP関連のファイルアップロードを弾く • Backend: PHP製。ファイルアップロードできる WAFが誤解するようなリクエストを作る
特定の文字(列)を禁止/無害化する問題 • 無害化系 • 特定の文字を削除/置き換え ../ を削除してパストラバーサル対策 ※注意: ….// が ../ になる! Ricerca CTF 2023 Cat Café https://github.com/RICSecLab/ricerca-ctf-2023-public/blob/main/web/catcafe/distfiles/app.py
大雑把な解き方 • 方針1: あまり知られていない文字列を使って悪さをする • あまり知られていない機能・関数を探し出したり、組み合わせたり • 方針2: 無害化処理 / WAFの不備を突く • 無害化することによって逆に危険になる文字列を作る • WAFを回避してアクセスする • 現実でも結構役に立つ
現実での応用 • 方針1: あまり知られていない文字列を使って悪さをする • 場当たり的な対策に有効。現実でもよくある • 「’」(クオート)は攻撃っぽいので弾く、on*は攻撃っぽいので弾く… • 現実のWAFもまだ知らないpayloadを使って攻撃 • AWS WAF, Cloudflare WAF, etc… マイナーなHTML属性の例 https://x.com/kinugawamasato/status/1816157074382028869
現実での応用 • 方針2: 無害化処理 / WAFの不備を突く • ../ を削除して無害化 → ….// で悪用 • 現実でもよく見かける…もしかしてどこかで広まってる? • 現実のWAFの回避手法も様々 • オリジンサーバを見つける • Request bodyが8KBを超えるとAWS WAFが機能しなくなる
現実での応用 • 現実でも結構役に立つ • 根本治療をしていないケース • AI生成コードをコピペしたり、直感で無害化処理するケース • CTFで素振りをすると、怪しさ対する嗅覚が身につくかも? • 多様な制約、状況が用意されている • 回避手法だけではなく「この文字が制限されているとかなりきつい」 といった効果的な防御方法も試行錯誤の中で分かってくる
中級編 – SQLiってまだあるんですか?
エスケープは十分なのに発生するSQLi • 現代ライブラリ/ORM使ってればSQLiからは安全だよね?とい う思い込みを利用したCTF問題 • Log Me In (Google CTF 2020) • mysql @npm • passwordless (IERAE DAYS CTF 2023) • sequel @Ruby gems
SQLインジェクション(SQLi)
• SQLi: 古来から生息する有名な脆弱性
• [SQL] SELECT name FROM items WHERE name = '<検索ワード>'
• <検索ワード> = ' OR '1' = '1
• → 全ての商品がヒットする
• <検索ワード> = ' UNION SELECT password FROM users;
• → パスワードが漏洩!
電話越しにデータベースを破壊するミーム https://xkcd.com/327/
SQLインジェクション(SQLi) • 対策 • プリペアドステートメントを利用する • 入力値をエスケープする • ' → '' (連続シングルクオートはシングルクオート1つ分とみなされる)
SQLインジェクション(SQLi) • Q. 現代的なライブラリの安全な関数使えば大丈夫だよね? • A. はい。でも気を付けて… • そのライブラリ、便利すぎませんか?
便利すぎるライブラリ1 – mysqljs/mysql • mysqljs/mysql (JS) (*1) なら自動でエスケープするから安心? ?に入る文字は自動エスケープ (*1) https://github.com/mysqljs/mysql
便利すぎるライブラリ1 – mysqljs/mysql • [便利機能] オブジェクトを `key` = value に展開 • UPDATE/INSERT文に便利! ? が展開される
便利すぎるライブラリ1 – mysqljs/mysql • SELECT文でも展開される! SELECT文でもおかまいなし name = `name` = 1 → (name = `name`) = 1 → 1 = 1 すべてのデータがヒット
パスワードリセットへの応用 リセットトークンから対象のユーザを検索
パスワードリセットに使われると…? パスワードリセットのSELECT文で展開 reset = `reset` = 1 → (reset = `reset`) = 1 → 1 = 1 全ユーザがパスワードリセット対象に!
暗黙の型変換にも注意 • mysql2 (JS) (*1) ならプリペアドステートメントなので安全? 文字列 = 0 の比較結果は…? reset (文字列) と 0 (数値)を比較 MySQLでは暗黙の型変換により ‘abcabc…’ = 0 は正 (*1) https://github.com/sidorares/node-mysql2
便利すぎるライブラリ2 – sequel • sequel (Ruby) (*1) にも同様の例が • [便利機能] 条件にハッシュを指定すると key = value に変換 展開 & 文字列 = 0 の比較のコンボ reset = ('x' = 'y') → reset = 0 → 暗黙の型変換により 'abc…' = 0 (*1) https://github.com/jeremyevans/sequel
エスケープは十分なのに発生するSQLi(*) • 「ライブラリがエスケープするから、内部でプリペアドステー トメントを利用しているから大丈夫だと思っていた…」という 事例は現実でもよく見る • 現実だと特にパスワードリセットで発生しやすい印象 • 入力値を直接比較する、比較結果が認証に直結する機能 • 入力値の型検証を忘れずに! (*実際のところこれをSQLiと呼んでいいのかは怪しい。手法としてはJSON SQL Injection, NoSQL Injection, Mass Assignmentが近いか…?)
上級編 – ブラウザの変な挙動でXSS
CTFでよくあるシチュエーション • 問題設定: 自明なHTMLインジェクション or 自由にHTMLが書ける • でもXSSができそうにない... • サニタイザ(例: DOMPurify, Sanitizer API) • Content-Security-Policy(例: CSP nonceによる制限) • Trusted Types • iframeタグのsandbox属性・csp属性 • Content-Typeに制約 • ページに表示できない(例: fetchでしかアクセスできない) • etc. • 様々な制約で出題される †安全な† HTMLインジェクション
CTFでよくあるシチュエーション • 一見XSSは不可能に見えるが実は可能 • 作問者からの「この制約でXSS達成できる???」の挑戦状 • 難しい問題は • HTML Living Standardにしか書かれていないような仕様を突いたり • ブラウザの実装に依存した挙動を悪用したり • フレームワークの深淵に触れたり • BABA IS YOUみたいなパズルを強要されたり • 参加者の感想: こんな知識・攻撃テクニック、いつ使うんや... • → 現実でも応用できる ことがあります!
ブラウザキャッシュを悪用するXSS • 「spanote」SECCON CTF 2022 Qualsで出題 • Webのボス問 - 1 solves • chrome独自のブラウザキャッシュ挙動を悪用してXSSする問題 • 現実で応用できる例として紹介します💡
spanote: 問題概要 • 一般的なノートアプリ • ノートの作成・削除・一覧 • ゴール: XSS
spanote: 問題概要 • ノート一覧ページ: 各ノートをfetchで取得 → 動的に要素として挿入 • textContentで代入 → ここでXSSはできない
spanote: 問題概要 • 少し工夫すると任意HTMLのノートを作成可能 • XSSペイロードのHTML • Content-Type: text/html • XSSできそうな雰囲気ではある...
spanote: 問題概要 • ブラウザでノートに直接アクセス • → Invalid token エラー • アクセスするにはカスタムヘッダが必要 • URLバーにURLを入れてアクセスする場合、ヘッダを自由に付与できない • → ブラウザで表示することができない → 一見するとXSSは不可能
spanote: 問題概要 • 目標: 以下の2つを両立させたい → 達成すればXSS可能 カスタムヘッダの付与 ブラウザのページに表示 • それ、ブラウザキャッシュを使うとできます!
spanote: 解法 手順1: XSSノートのページに直接アクセス • カスタムヘッダがないので 500 エラー
spanote: 解法 手順2: ノート一覧のページにアクセス • XSSノートにカスタムヘッダ付きのfetchリクエスト → 200 OK
spanote: 解法 • 手順3: ブラウザの「戻る」でXSSノートのページに再アクセス • 手順2のときのレスポンスがキャッシュされて、それが表示される!
spanote: 解法 • 手順1~3を自動化すれば罠サイト経由でXSSが可能! • 詳細: https://blog.arkark.dev/2022/11/18/seccon-ja/#web-spanote • Chromeのブラウザキャッシュ挙動を悪用してXSSする攻撃 • (私の認識では)これ以降、CTFでの典型テクニックとなった • Intigriti Monthly Challenges - Challenge-0323 • HITCON CTF 2024 - Private Browsing+ • corCTF 2024 - iframe-note • その他、非想定解テクニックとしても活躍
現実での応用 • XSSの温床:「Content-Typeの設定不備・制限の考慮不足」 • 例1: JSONなのに「Content-Type: text/html」 • 例2: ファイルアップロード時の拡張子でContent-Typeが決定 • 例3: 画像のみに制限されているが、SVG(image/svg+xml)を許容 • 参考: https://github.com/BlackFan/content-type-research/blob/master/XSS.md • アクセス時にヘッダ必須でXSSできないケースは、実際にある • ブラウザキャッシュ悪用によるXSSチャンス…!
現実での応用 ケース1: XSS対策として X-Requested-With ヘッダをチェック • 例: jQueryの$.ajaxは、ヘッダに 「X-Requested-With」を付与する • 古のXSS対策のひとつとして このヘッダを判定する方法があった • 一度定着してしまったこともあり、現代でも採用しているプロダクトは多い… • ブラウザキャッシュ悪用でbypassが可能 → XSS☠
現実での応用 ケース2: クラウドストレージにアクセス時の署名ヘッダ • サービス構成例: • ユーザが自由にファイルアップロードできる • アップロード先がクラウドストレージ(S3, Cloud Storage, …) • 拡張子でContent-Typeをある程度制御可能(例: text/html, image/svg+xml, etc.) • 関連: S3経由でXSS!?不可思議なContent-Typeの値を利用する攻撃手法の新観点 - Fla4 Security Blog • 任意のユーザがアクセスできないようにアクセス時に署名ヘッダを要求 • →(意図せずに)通常のXSSは困難 • ブラウザキャッシュ悪用がきれいにハマることがある → XSS☠
まとめ
まとめ • CTFの現実への応用をいくつか紹介した • 初級編: 特定文字(列)の禁止/無害化を回避するCTF問題 • 中級編: SQLiってまだあるんですか? • 上級編:ブラウザの変な挙動でXSS • 結論: CTFは業務の役に立ちます • CTFは業務の役に立ちます •CTFは業務の役に立ちます