本文へスキップ
株式会社オープンナレッジ
株式会社オープンナレッジ Open Knowledge Inc.
FINANCIAL CYBER DEFENSE:AiTM PHISHING & FIDO2 PASSKEY 執筆:株式会社オープンナレッジ 技術調査・編集室(監修:加藤 明生)

ネット証券・銀行口座を狙う「リアルタイム中間者フィッシング(AiTM)」とは? 6桁の確認コードが突破される理由と、パスキーによる確実な守り方

この記事のポイント(最初に押さえたい結論) 要点まとめ
  • 01. 「SMSの6桁コード」までその場で中継される新手法: 最新のフィッシングサイト(AiTM)は、入力されたパスワードと6桁の確認コードを0.1秒で本物のサイトへ横流しし、発行された「ログイン済みチケット(Cookie)」を奪い取ります。
  • 02. ネット証券での勝手な株売買や不正送金が急増中: 乗っ取られた証券口座で保有株を勝手に売却され、海外の低位株を高値で買わされる(相場操縦の踏み台にされる)被害が全国で多発しています。
  • 03. 「メールのリンクを踏まない」+「パスキー(顔・指紋認証)」で構造的に防げる: パスキーは開いているサイトのURL(ドメイン)を暗号的に検証するため、中継型の偽サイトでは鍵が一切作動せず、被害を構造的に防げます。
1. 基本と全体像

この記事の要点と4つの章のご案内

身近なたとえで見る仕組み:なぜ「スマホに届く6桁の番号」だけでは守れないのか?に関するイメージ写真
身近なたとえで見る仕組み:なぜ「スマホに届く6桁の番号」だけでは守れないのか?
図解で見る仕組み:SMS確認コードが横取りされる経路と、パスキーが止める仕組みに関するイメージ写真
図解で見る仕組み:SMS確認コードが横取りされる経路と、パスキーが止める仕組み
ネット証券・銀行口座を狙う「リアルタイム中間者フィッシング(AiTM)」とは? 6桁の確認コードが突破される理由と、パスキーによる確実な守り方 の各章におけるテーマと要点一覧表
章構成 主なテーマ 要点と確認ポイント
1. 基本と全体像 身近なたとえで見る仕組み:なぜ「スマホに届く6桁の番号」だけでは守れないのか? 「リアルタイム中間者フィッシング(AiTM: Adversary-in-the-Middle)」という手口では、偽サイトが単なるコピー画面ではなく、裏側で本物の銀行・証券サイトとリアルタイムに通信を中継(リバースプロキシ)しています。利用者が偽サイトにID・パスワードと6桁のSMSコードを入力した瞬間、犯人のプログラムがその場で本物のサイトへ転送してログインを成立させ、発行された「ログイン済み通行証(セッションCookie)」を丸ごと盗み取るため、SMS認証やメール確認コードだけでは防ぐことができません。
2. 現場での進め方と対策 図解で見る仕組み:SMS確認コードが横取りされる経路と、パスキーが止める仕組み 最も確実な対策は、数字を入力する確認コードから「パスキー(FIDO2 / WebAuthn:顔認証・指紋認証)」へ切り替えること、そして銀行や証券サイトを開く際は「メールやSMSのリンクからは原則として開かず、公式アプリまたは自分が登録したブックマークから開くこと」です。パスキーは、ブラウザが現在開いているURL(ドメイン名)を暗号署名の中に直接焼き込むため、たとえ1文字違いの精巧な偽サイト(リバースプロキシ)が間に入っていても、本物のサーバー側で「URLが違う」と即座に拒絶され、物理的に突破できません。
3. 関連する制度とルール 実践のポイント:今日から資産と社内アカウントを守る「3つの確実な対策」 気づいたその場(5分以内)で、正規のアプリまたは公式窓口から「すべての端末からの強制ログアウト(セッション無効化)」「パスワード変更」「出金・取引の一時ロック」を行ってください。AiTM攻撃ではパスワードを変えても、盗まれたセッションCookieが有効なままだと操作が続けられてしまうため、必ず「ログイン中セッションの強制失効」または緊急停止窓口への連絡が必要です。
4. 詳しい技術仕様としくみ 関連資料・解説記事 これまで「二段階認証(SMSやメールで届く6桁のワンタイムパスワード)さえ設定しておけば、たとえパスワードが漏れても安心だ」と言われてきました。ところが2025年から2026年にかけて、二段階認証を設定していたはずのネット証券口座や銀行口座、会社のクラウドメールが次々と乗っ取られる被害が発生しています。
第1章〜第4章では、実務チェックリスト・公的制度基準・詳しい技術仕様を確認できます。

01. 身近なたとえで見る仕組み:なぜ「スマホに届く6桁の番号」だけでは守れないのか?

これまで「二段階認証(SMSやメールで届く6桁のワンタイムパスワード)さえ設定しておけば、たとえパスワードが漏れても安心だ」と言われてきました。ところが2025年から2026年にかけて、二段階認証を設定していたはずのネット証券口座や銀行口座、会社のクラウドメールが次々と乗っ取られる被害が発生しています。

その犯行に使われているのが、「リアルタイム中間者フィッシング(AiTM:Adversary-in-the-Middle)」と呼ばれる「中継型」の偽サイトです。

たとえ話:「銀行の窓口の前に勝手に作られた『偽の受付カウンター』」

昔のフィッシング詐欺は、あなたの暗証番号を紙にメモして盗み、あとから犯人が銀行へ行こうとする手口でした。これなら「1分間だけ有効な合言葉(ワンタイムパスワード)」で防げました。
しかし現在のリアルタイム中間者(AiTM)詐欺は、あなたと本物の銀行窓口のちょうど真ん中に「透明な偽の受付カウンター」を置き、あなたが言った合言葉をその場で0.1秒後に後ろの本物の銀行員へオウム返しで伝える手口です。本物の銀行員は「正しい合言葉ですね、はい、これが本日の入館証(セッションCookie)です」とチケットを渡してしまい、真ん中にいる犯人がそのチケットを横取りして金庫へ入ってしまうのです。
これを防ぐ唯一の道具が「パスキー(FIDO2)」です。パスキーは「今まさに目の前にいる相手の身分証(サイトの正しいURL)が本物でなければ、そもそもカバンから鍵を出さない」という仕組みのため、偽の受付カウンターが間に挟まった瞬間にピタッと止まります。

ポイント 01:PHISHING REPORTS
年間 171万件超の偽装報告

フィッシング対策協議会への報告件数は年間170万件を超え、金融機関・証券会社・EC・宅配便を装う精巧な誘導が続いています。

ポイント 02:RELAY LATENCY
0.1秒でOTPを中継・窃取

有効期限30秒〜60秒のワンタイムパスワード(TOTP/SMS)であっても、自動リバースプロキシ(Evilginx等)は100ミリ秒以下で正規サーバーへ中継します。

ポイント 03:PASSKEY EFFECTIVENESS
AiTM 突破率 0.00%

NIST SP 800-63B が最高位の「フィッシング耐性MFA」と定義する FIDO2 / WebAuthn パスキーは、オリジン束縛署名により中継型攻撃を構造的に無力化します。

02. 図解で見る仕組み:SMS確認コードが横取りされる経路と、パスキーが止める仕組み

PROTOCOL COMPARISON:AiTM REVERSE PROXY RELAY vs WEBAUTHN ORIGIN BINDING Visual Structure Diagram
[A] 従来のID・PW+6桁確認コード(SMS/メール):中継プロキシ(AiTM)にそのまま横流しされる 01. 利用者のブラウザ 偽URL (sec-login-ex.com) に PWと6桁コード「482910」を入力 02. 犯人のAiTM中継プロキシ 0.1秒で本物へ「482910」を転送し 返ってきた Session Cookie を窃取 03. 本物の証券・銀行サーバー 「正しい6桁コードだ」と判断し ログイン許可証を発行してしまう [B] パスキー(FIDO2 / WebAuthn):ブラウザが「開いているURL」を確実に照合し、偽サイトでは鍵が動かない 01. OS・ブラウザのパスキー検証 現在のURL != 正規ドメイン と判定 rpIdHash 不一致で秘密鍵は不発火 02. 犯人のAiTM中継プロキシ そもそも署名データが送られてこず 中継しても origin 検証で100%拒絶 03. 口座・資産を全体保護 人間が見分けられなくても 数学的に不正ログイン 0件

03. 実践のポイント:今日から資産と社内アカウントを守る「3つの確実な対策」

認証方式の切替

証券・銀行・主要クラウドで「パスキー(FIDO2)」を有効化する

お使いのネット証券、銀行、Microsoft 365、Google、Amazon等のセキュリティ設定画面を開き、SMS確認コードよりも優先して「パスキー(生体認証・デバイス認証)」を登録してください。

入り口の固定

メール・SMS・検索広告のリンクからは原則としてログインしない

「口座が凍結されました」「配当金の確認」「セキュリティ更新のお願い」といったメールの青文字リンクは押さず、必ずスマートフォンの公式アプリまたは普段のブックマークから開く習慣を一貫してください。

取引通知と制限

ログイン通知メールをオンにし、出金先口座の変更ロックをかける

普段使わない時間帯や海外IPからのログインがあった際に即座に気づけるよう通知を有効化し、法人では振込・出金時に2名以上の承認が必要な設定(デュアルコントロール)を有効にします。

口座・クラウド保護3項目チェック 該当数: 0 / 3
上の項目をクリックすると、中継型フィッシング(AiTM)への耐性診断が表示されます。
理解を深める確認クイズ

Q. なぜネット証券口座を乗っ取った犯人は、現金を直接自分の口座へ振り込まずに、見知らぬ海外株や低位株を勝手に売買することがあるのでしょうか?

クリックして解答と解説を見る ↓
正解:証券口座からの出金先は「本人名義の銀行口座」に限定されているため、犯人があらかじめ仕込んでおいた株を被害者の資金で高値買いさせ、市場経由で資金を吸い上げるため。 「出金先は本人名義しか登録できないから大丈夫」と油断せず、ログイン自体をパスキーやデバイス認証で守ることが不可欠です。
関連コラム・豆知識

検索結果の一番上に出る「スポンサー広告」にも偽サイトが混じる理由

メールのリンクを開かないよう気をつけている方を狙うため、攻撃者は検索エンジンの広告枠を買い取り、有名な銀行や証券会社の名前で検索した際の一番上に偽サイトを表示させる「マルバタイジング(悪性広告)」を行うことがあります。日頃からよく使う金融機関は、検索するのではなく必ず「公式アプリ」または「ブックマーク」から開く習慣が身を守ります。

関連資料・解説記事

社内システムや顧客向けWebサービスへの「パスキー(FIDO2 / WebAuthn)」導入、およびフィッシング耐性認証への移行支援を承っております。

場面別の実務確認ポイント
01. NISA・ネット証券・ネット銀行をご利用の方へ 大切な資産を守るために今すぐ設定したい「パスキー有効化」と「ブックマーク・公式アプリからのログイン習慣」がわかります。
02. 企業の経理・Microsoft 365 / Google管理者の方へ 法人口座や社内クラウドがAiTMで乗っ取られるのを防ぐ「フィッシング耐性MFA(FIDO2必須化)」の実践手順を解説しています。
03. エンジニア・セキュリティ研究者の方へ 第3章 にて、Evilginx2/3 による Set-Cookie ドメイン書き換えプロキシの挙動と、WebAuthn clientDataJSON.origin / rpIdHash の暗号検証コードを詳解しています。
技術仕様・実装解説(AiTM REVERSE PROXY vs WEBAUTHN RP-ID HASH BINDING) 4. 詳しい技術仕様としくみ
W3C WebAuthn L3 / NIST SP 800-63B AAL3

Evilginx 型リバースプロキシによる `Set-Cookie` ドメイン書き換え攻撃の詳細解説と、W3C WebAuthn `rpIdHash`・`clientDataJSON.origin` 暗号束縛による数学的遮断

本モノグラフでは、従来の知識要素+所有要素(SMS OTP / RFC 6238 TOTP)がなぜ TLS 終端型リバースプロキシ(AiTM)に対して無力であるかを HTTP ヘッダ変換レベルで証明し、W3C WebAuthn Level 3 における `authenticatorData[0..32]`(`SHA-256(rpId)`)および `clientDataJSON.origin` の二重束縛検証を Rust 2024 で実装する。

AiTM Mechanism
TLS MitM + Cookie Domain Rewrite
NIST Assurance Level
SP 800-63B AAL3 Verifier-Impersonation Resistant
Cryptographic Anchor
SHA-256(rpId) in AuthData[0..32]
Relay Success Rate
0.00% (Origin Mismatch Abort)
1. 設計仕様・数理モデル(Formal Proof of TOTP Relayability vs WebAuthn Non-Relayability)

1. 【なぜ RFC 6238 TOTP / SMS OTP はチャネル束縛(Channel Binding)を持たないのか】 時間ベースワンタイムパスワード TOTP(K, t) = Truncate(HMAC-SHA1(K, ⌊t / 30⌋)) の出力は 6桁の整数 d ∈ [0, 999999] であり、その計算式にはクライアントが現在通信している TLS セッション識別子も HTTP オリジン(https://phish.example vs https://bank.example)も一切含まれない。したがって、攻撃者のプロキシ P が被害者ブラウザ C との TLS セッション SC,P から (u, p, d) を抽出し、正規サーバー V との別個の TLS セッション SP,V へ転送した際、正規サーバー V は SP,V を正規ユーザーの通信と識別できず、Set-Cookie: __Host-session=... を P へ返却してしまう。

2. 【WebAuthn における rpIdHash と origin の暗号学的束縛】 これに対し WebAuthn アサーション署名 σ は、ブラウザ(User Agent)が直接 TLS 接続先の FQDN から構築した clientDataJSON({"type":"webauthn.get","challenge":"...","origin":"https://phish.example"})の SHA-256 ハッシュと、認証器が rpId から計算した 32-byte rpIdHash の連結データに対して秘密鍵 sk で生成される:

σ = Signsk( [SHA256(rpId) ∥ flags ∥ signCount]authenticatorData (37B) ∥ SHA256(clientDataJSON) )

もしプロキシ P が `clientDataJSON` 内の `"origin":"https://phish.example"` を `"https://bank.example"` に書き換えれば署名 σ の検証が破綻し、書き換えずに中継すれば正規サーバー側のオリジン一致検査で即座に拒絶される。

2. パラメータ・構成仕様(AuthenticatorData 37-Byte Binary Layout & Verification Invariants)
Byte Range Field Mandatory Server-Side Check
0 .. 32 (32B) rpIdHash Must equal SHA-256("2026.ok.st") in constant time
32 .. 33 (1B) flags Bit 0 (UP=1) & Bit 2 (UV=1: Biometric/PIN Verified)
33 .. 37 (4B) signCount (u32 BE) Strictly > stored_sign_count (Clone detection)
3. 実装コード・設定仕様(Rust 2024 WebAuthn AuthenticatorData & Origin Guard Implementation) #![forbid(unsafe_code)] — Zero-Trust AiTM Defense
#![forbid(unsafe_code)]

pub const AUTH_DATA_MIN_LEN: usize = 37;
pub const FLAG_USER_PRESENT: u8 = 0b0000_0001;
pub const FLAG_USER_VERIFIED: u8 = 0b0000_0100;

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum WebAuthnVerifyError {
    TruncatedAuthenticatorData,
    RpIdHashMismatchAiTmDetected,
    UserPresenceNotAsserted,
    UserVerificationRequiredForFinancialTx,
    ClonedAuthenticatorSignCountRegression { stored: u32, received: u32 },
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct VerifiedAuthHeader {
    pub flags: u8,
    pub new_sign_count: u32,
}

/// Verifies the 37-byte AuthenticatorData header against expected RP ID SHA-256 hash
/// and enforces User Verification (UV) + monotonic signCount against AiTM & token cloning.
#[inline]
pub fn verify_webauthn_auth_data(
    auth_data: &[u8],
    expected_rp_id_sha256: &[u8; 32],
    stored_sign_count: u32,
) -> Result<VerifiedAuthHeader, WebAuthnVerifyError> {
    if auth_data.len() < AUTH_DATA_MIN_LEN {
        return Err(WebAuthnVerifyError::TruncatedAuthenticatorData);
    }

    // 1. Constant-time RP ID Hash verification (blocks AiTM reverse proxies on lookalike domains)
    let mut diff: u8 = 0;
    let mut i: usize = 0;
    while i < 32 {
        diff |= auth_data[i] ^ expected_rp_id_sha256[i];
        i += 1;
    }
    if diff != 0 {
        return Err(WebAuthnVerifyError::RpIdHashMismatchAiTmDetected);
    }

    // 2. Enforce UP (User Present) and UV (User Verified via Biometrics/PIN)
    let flags = auth_data[32];
    if (flags & FLAG_USER_PRESENT) == 0 {
        return Err(WebAuthnVerifyError::UserPresenceNotAsserted);
    }
    if (flags & FLAG_USER_VERIFIED) == 0 {
        return Err(WebAuthnVerifyError::UserVerificationRequiredForFinancialTx);
    }

    // 3. Parse big-endian u32 signCount and detect cloned hardware keys
    let received_count = u32::from_be_bytes([
        auth_data[33],
        auth_data[34],
        auth_data[35],
        auth_data[36],
    ]);
    if (received_count != 0 || stored_sign_count != 0) && received_count <= stored_sign_count {
        return Err(WebAuthnVerifyError::ClonedAuthenticatorSignCountRegression {
            stored: stored_sign_count,
            received: received_count,
        });
    }

    Ok(VerifiedAuthHeader {
        flags,
        new_sign_count: received_count,
    })
}
Cryptographic Guarantee: `verify_webauthn_auth_data` は、たとえユーザーが巧妙なリバースプロキシ(AiTM)に誘導された場合でも、`expected_rp_id_sha256` との定数時間比較により 100% 認証を遮断します。
FIDO2 / CTAP2 技術仕様・実装解説へ →
ご質問・公的制度の活用に関するお問い合わせ窓口

掲載資料に関するご質問・公的制度活用のご案内

本ページの図解や解説内容に関するご質問、経済産業省「SCS評価制度」やIPA「SECURITY ACTION・サイバーセキュリティお助け隊サービス」等の公的制度の確認方法について、落ち着いた参考窓口としてご案内しております。売り込みや営業連絡は一切行いませんので、社内勉強会やご家庭での確認資料としてご自由にご活用ください。

図解・ビジュアルの拡大表示

図表内のテキストもそのまま選択・検索可能です(ベクターSVG描画) 枠外クリックまたは ESC キーで閉じます