# ARPスプーフィング・中間者攻撃（MITM）の仕組みと防御【2026】— L2の信頼を突く攻撃を検知・無害化する

> L2 攻撃の王様『ARPスプーフィング』と、それを土台にした中間者攻撃（MITM）を、仕組みから検知・防御まで体系的に解説。ARP に認証がない根本原因、被害者の通信を自分経由に捻じ曲げる流れ、Dynamic ARP Inspection・DHCP Snooping・802.1X・そして TLS による無害化を、型安全な検知コードとともに示します。すべて隔離ラボに閉じた合法手順で、攻めの理解を防御設計に変えます。

- 公開日: 2026-06-28
- 著者: 友田 陽大
- タグ: セキュリティ, ネットワーク, TCP/IP, 脆弱性診断, ホワイトハッカー, 倫理的ハッキング
- URL: https://tomodahinata.com/blog/arp-spoofing-mitm-attack-detection-defense-guide
- カテゴリ: 実践ネットワーク攻撃と防御
- 総合ガイド: https://tomodahinata.com/blog/network-penetration-testing-methodology-attack-defense-guide

## 要点

- ARPスプーフィングは『このIPのMACは私だ』と偽のARP応答を撒き、被害者とゲートウェイの通信を自分経由に捻じ曲げるL2攻撃。ARPに送信元認証がない（言った者勝ち）のが根本原因
- MITM が成立すると、経路上で盗聴（平文を読む）・改ざん（書き換える）・セッションハイジャックが可能になる。同一セグメント（同じLAN/Wi-Fi）にいることが前提条件
- 検知は『1つのMACが複数IPを主張』『ゲートウェイのMACが突然変わった』を監視する。arpwatch やスイッチのログ、エンドポイントでのARPテーブル監視で気づける
- 予防の本命は L2 のインフラ統制：スイッチの Dynamic ARP Inspection(DAI) + DHCP Snooping が偽ARPを物理的に落とす。802.1X でそもそも無許可端末を接続させない
- 最後の砦は TLS。経路を奪われても、正しく検証された TLS なら中身は読めず・書き換えれば検知される。『ネットワークは信頼しない』ゼロトラストが ARP 攻撃を無意味化する

---

同じ Wi-Fi・同じLANにいる誰かが、あなたとインターネットの間に**こっそり割り込む**——これが**中間者攻撃（Man-in-the-Middle, MITM）**で、その最も古典的かつ強力な入口が **ARPスプーフィング**です。攻撃者は一発の銃弾も撃たず、ただ「嘘のARP応答」を撒くだけで、被害者の全通信を自分の手のひらに乗せます。

この記事は、[ネットワークペンテストの全体像](/blog/network-penetration-testing-methodology-attack-defense-guide)に続き、ARPスプーフィング/MITM の仕組みを正確に解説し、**検知と、RFC・ベンダ標準に準拠した防御**を型安全なコードとともに示します。核心は「ARP に認証がない」という[TCP/IP の根本的な信頼の前提](/blog/tcp-ip-protocol-suite-fundamentals-complete-guide)です。

> **安全地帯の徹底**：ARPスプーフィングは**同一セグメントの第三者の通信を巻き込む**性質上、特に危険です。本記事の手順は[隔離ラボ](/blog/ethical-hacking-home-lab-kali-juice-shop-ctf-self-study-roadmap-guide)（内部ネットワークの自分のVM 3台）の中だけで実行します。**職場・学校・カフェ・自宅の共有Wi-Fiで試すことは、他人の通信の秘密を侵害し、不正アクセス禁止法・電気通信事業法に明確に違反します**。攻撃ツールの「コマンド」より、向ける「先」を間違える方が、はるかに重大です。[法律の記事](/blog/ethical-hacker-law-japan-unauthorized-access-act-active-cyber-defense-disclosure-guide)を必ず先に。

---

## 1. なぜ ARP は騙せるのか — 「認証なき信頼」

ARP（Address Resolution Protocol）は、「IPアドレス → MACアドレス」を解決するL2のプロトコルです。同じLAN内で `10.10.10.1`（ゲートウェイ）に通信したいホストは、こう尋ねます。

```text
[ Who has 10.10.10.1? Tell 10.10.10.10 ]   ← ブロードキャストで全員に質問
[ 10.10.10.1 is at aa:bb:cc:dd:ee:ff   ]   ← ゲートウェイが応答
```

ホストはこの応答を**ARPキャッシュ**に保存し、以後そのMAC宛に送ります。問題は——**ARPには送信元を検証する仕組みが一切ない**こと。誰でも「私が 10.10.10.1 だ」と応答でき、しかも**尋ねられてもいないのに勝手に応答（Gratuitous ARP）**を撒けます。受け取った側は無条件に信じ、キャッシュを上書きします。**「言った者勝ち」**——これが全ての元凶です。

---

## 2. ARPスプーフィング → MITM の成立

攻撃者（`10.10.10.5`）は、被害者とゲートウェイの双方に嘘をつき、自分を経路に挿入します。

```text
攻撃者が撒く2つの嘘（偽 ARP 応答）：
  ① 被害者(10.10.10.10) へ → 「10.10.10.1(GW) のMACは 攻撃者のMAC だよ」
  ② ゲートウェイ(10.10.10.1) へ → 「10.10.10.10(被害者) のMACは 攻撃者のMAC だよ」

結果、通信経路が捻じ曲がる：
  被害者 ──► [ 攻撃者 ] ──► ゲートウェイ ──► インターネット
         ◄──          ◄──
  （双方は「直接やり取りしている」と思い込んでいる）
```

経路を奪った攻撃者は、IP フォワーディングを有効にして通信を素通しさせれば**被害者に気づかれず**、その上で：

- **盗聴**：流れる平文（HTTP・古いプロトコル）をそのまま読む（→[パケット盗聴](/blog/packet-sniffing-wireshark-tls-encryption-defense-guide)）。
- **改ざん**：応答を書き換える（HTTPSへのリダイレクトを剥がす SSL ストリップ等）。
- **セッションハイジャック**：[TCPセッションを奪う](/blog/tcp-session-hijacking-rst-injection-ip-spoofing-defense-guide)土台にする。

> ラボでは `arpspoof`（dsniff）や `ettercap`/`bettercap` が教材として使われます。**本記事では攻撃の発射コマンドは示しません**——仕組みの理解が目的であり、無害化（防御）にページを割きます。再現が必要なら、必ず隔離ラボの自分のVM間でのみ、各ツールの公式ドキュメントに従ってください。

---

## 3. 検知 — 「MACとIPの矛盾」を見張る

ARPスプーフィングには、消せない痕跡が残ります：**「1つのMACアドレスが複数のIPを主張する」「ゲートウェイのMACが突然変わる」**。これを監視すれば気づけます。

### 3.1 現場でまず使うもの

- **`arpwatch`**：MAC↔IP の対応を学習し、変化したらアラートする古典的な定番。
- **エンドポイントでのARPテーブル監視**：`ip neigh`（Linux）/ `arp -a`。ゲートウェイのMACが既知の値か。
- **スイッチのログ**：管理スイッチは DAI（後述）でドロップを記録する。

### 3.2 仕組みを理解する最小の検知ロジック（型安全）

ARP 観測イベントから「矛盾」を検出する純粋関数を書きます。原理の可視化であり、本番では `arpwatch`/IDS に乗せるべきものです。

```ts
/** 観測した1件のARPアナウンス（IP がこの MAC を主張した、の記録）。 */
interface ArpObservation {
  readonly ip: string;
  readonly mac: string;
  readonly timestamp: number;
}

interface ArpAnomaly {
  readonly kind: "mac-claims-multiple-ips" | "ip-mac-changed";
  readonly detail: string;
}

/**
 * ARP 観測列から、スプーフィングの兆候を検出する純粋関数。
 * - 同一 MAC が多数の IP を主張（経路に挿入しようとする攻撃者の典型）
 * - 既知の IP↔MAC 対応が別 MAC に変化（ゲートウェイ詐称の典型）
 * 副作用なし＝決定的でテスト容易。誤検知は既知の信頼マップで除外する。
 */
export function detectArpSpoofing(
  observations: readonly ArpObservation[],
  trustedIpToMac: ReadonlyMap<string, string>,
  ipCountThreshold = 3,
): readonly ArpAnomaly[] {
  const anomalies: ArpAnomaly[] = [];
  const ipsByMac = new Map<string, Set<string>>();

  for (const o of observations) {
    // (1) 信頼済みの IP↔MAC が変化していないか（ゲートウェイ詐称の検出）
    const trusted = trustedIpToMac.get(o.ip);
    if (trusted !== undefined && trusted !== o.mac) {
      anomalies.push({
        kind: "ip-mac-changed",
        detail: `${o.ip} expected ${trusted} but saw ${o.mac}`,
      });
    }
    // (2) 1つの MAC が複数 IP を主張していないか
    const ips = ipsByMac.get(o.mac) ?? new Set<string>();
    ips.add(o.ip);
    ipsByMac.set(o.mac, ips);
  }

  for (const [mac, ips] of ipsByMac) {
    if (ips.size >= ipCountThreshold) {
      anomalies.push({
        kind: "mac-claims-multiple-ips",
        detail: `${mac} claims ${ips.size} IPs: ${[...ips].join(", ")}`,
      });
    }
  }
  return anomalies;
}
```

`trustedIpToMac`（ゲートウェイ等の既知の正しい対応）を渡すことで、**誤検知を構造的に減らしつつ**、ゲートウェイ詐称という最も危険なケースを確実に捉えます。検知ロジックを純粋関数に切り出す利点は、ゴールデンベクタでテストを固定でき、運用中に閾値を安全に調整できることです。

---

## 4. 防御 — 3層で無害化する

ARP攻撃は、**インフラ統制（予防）→ 認証（接続制御）→ 暗号化（最後の砦）**の3層で無害化します。

### 4.1 L2 インフラ統制：Dynamic ARP Inspection + DHCP Snooping（本命）

管理スイッチの機能で、**偽のARPを物理的にドロップ**します。これが最も効く予防です。

- **DHCP Snooping**：スイッチが「どのポートのどのMACに、どのIPが正規に割り当てられたか」を信頼テーブルとして学習する。
- **Dynamic ARP Inspection（DAI）**：ARP応答をこの信頼テーブルと突き合わせ、**矛盾するARP（＝スプーフィング）をポートで落とす**。

```text
[ Cisco IOS の概念例（ベンダ公式手順に従う） ]
  ip dhcp snooping
  ip dhcp snooping vlan 10
  ip arp inspection vlan 10           ← VLAN10 で DAI 有効化
  interface gi0/1
    ip dhcp snooping trust            ← アップリンク(GW側)だけ信頼
  ! 端末ポートは untrust のまま → 端末からの偽ARPは検査され落ちる
```

### 4.2 接続制御：802.1X でそもそも入れない

[IEEE 802.1X](https://1.ieee802.org/security/802-1x/) によるポートベース認証で、**認証を通らない端末はLANに接続すらできません**。攻撃者の物理/無線アクセス自体を断つ、ゼロトラストの入口です。

### 4.3 最後の砦：TLS — 「経路を奪われても中身は守る」

ここが本質的に重要です。**たとえ ARP で経路を奪われても、正しく検証された TLS なら攻撃は無害化されます。**

- **盗聴**：TLS で暗号化されていれば、攻撃者が読むのは暗号文だけ。
- **改ざん**：TLS は完全性を保証する。書き換えれば検知され接続が切れる。
- **なりすまし**：証明書検証により、攻撃者は正規サーバーの証明書を提示できない。

ただし条件があります——**証明書検証を絶対に無効化しない**こと（`rejectUnauthorized: false` は厳禁）。そして HTTP→HTTPS の格上げ前を突く SSL ストリップを防ぐため **HSTS**（`Strict-Transport-Security`）を効かせること。

```ts
import { request } from "node:https";

// ✅ TLS 検証は既定で有効。MITM 下でも証明書不一致で接続が落ちる＝安全側に倒れる
const req = request(
  { hostname: "api.example.com", port: 443, path: "/", method: "GET" },
  (res) => {
    // res.socket は TLSSocket。検証済みでなければここに到達しない
    res.resume();
  },
);
// ❌ 絶対にやってはいけない：rejectUnauthorized: false（MITM を自ら招き入れる）
req.on("error", (e) => console.error("TLS handshake/verify failed:", e.message));
req.end();
```

> **ゼロトラストの結論**：「社内LANだから安全」という前提を捨て、**ネットワーク位置を信頼の根拠にしない**。すべてのサービス間通信を相互TLS（mTLS）等で暗号化・認証すれば、ARP で経路を奪われても**攻撃者は何も得られません**。これが ARP 攻撃を時代遅れにする最終解です。

---

## 5. まとめ

- **ARPスプーフィングの根本原因は「認証なき信頼」**。誰でも「私がそのIPだ」と偽れ、受信側は無条件に信じる。
- **MITM が成立すると盗聴・改ざん・[セッションハイジャック](/blog/tcp-session-hijacking-rst-injection-ip-spoofing-defense-guide)が可能**。前提は「同一セグメントにいること」。
- **検知**：MAC↔IP の矛盾（1MACが複数IP・GWのMAC変化）を `arpwatch`/IDS/純粋関数で監視。
- **防御は3層**：①DAI+DHCP Snooping（偽ARPを物理ドロップ）②802.1X（無許可端末を入れない）③**TLS/mTLS（経路を奪われても中身を守る最後の砦）**。
- **TLS の証明書検証を無効化しない・HSTS を効かせる**。ゼロトラストが ARP 攻撃を無意味化する。

次は、名前解決そのものを乗っ取る**[DNSスプーフィング / キャッシュポイズニング](/blog/dns-spoofing-cache-poisoning-dnssec-defense-guide)**を、DNSSEC による防御まで含めて扱います。

---

私（友田 陽大）は、サービス間通信の TLS/mTLS 化、証明書運用、ゼロトラストなネットワーク設計（プライベートサブネット分離・最小権限・暗号化必須）を本番で実装してきました。「社内ネットワークの MITM 耐性を上げたい」「平文通信が残っていないか棚卸ししたい」「mTLS を導入したい」——こうした“経路を信頼しない”設計を、攻撃者の視点で診断し、検知と暗号化の両輪で実装します。お気軽にご相談ください。
