【実務・中級編】 DHCP(ポート67/68)およびARPスプーフィングを伴う内部ネットワークの侵害 – サイバーセキュリティとプライバシー保護実践ガイド

「ネットワークの裏口はいつも開いている」― DHCPとARPを悪用した内部侵害のリアルと防衛策

ネットワークエンジニアとして現場を渡り歩いていると、たまに「境界防御さえ固めればLAN内は聖域」と信じ込んでいる層に出くわします。しかし、現実はどうでしょう。一度侵入を許せば、攻撃者は真っ先にL2レベルの泥沼へ潜り込みます。

今日は、教科書には載っていない、しかし現場で最も恐ろしい「DHCP Rogue Server」と「ARPスプーフィング」による内部侵害のメカニズムと、それを実務でどう防ぐかについて、少しばかり「現場の空気感」を交えてお話ししましょう。

—

1. 牙を剥くDHCP:正規サーバーを出し抜く「なりすまし」

DHCPプロトコル(ポート 67/68)は、善意に基づいた古い設計です。クライアントがネットワークに参加する際、ブロードキャストで DHCPDISCOVER を投げ、誰かが DHCPOFFER を返せば、先着順でその設定を受け入れてしまう。この「早い者勝ち」こそが、マルウェアがゲートウェイを掌握する最大の隙となります。

なぜこれが脅威なのか

攻撃者は、同じセグメント内に不正なDHCPサーバーを立ち上げます。これに成功すると、クライアントの Default Gateway や DNS Server の設定を攻撃者自身に向けることが可能になります。これにより、全トラフィックは攻撃者のマシンを経由し、中間者攻撃(MitM)の完成です。

防御の要:DHCP Snooping

L2スイッチが「誰がDHCPサーバーを名乗って良いか」を管理する機能、それが DHCP Snooping です。

# Cisco Catalystスイッチでの設定例
# 1. まずSnooping全体を有効化
ip dhcp snooping
# 2. 信頼できるポート(正規のDHCPサーバーに繋がるポート)を指定
interface GigabitEthernet0/1
 ip dhcp snooping trust
# 3. 不信頼ポート(アクセスポート)ではレートリミットをかける
interface Range GigabitEthernet0/2 - 24
 ip dhcp snooping limit rate 10

この設定を忘れると、オフィスの一角に誰かが持ち込んだポケットルーター一台で、全端末の通信が抜き取られるリスクがあることを忘れてはいけません。

—

2. ARPスプーフィング:MACアドレスを偽装する「嘘つきのプロトコル」

DHCPで通信経路を奪うのが「外交戦」なら、ARPスプーフィングは「直接的な詐欺」です。ARPには認証がありません。攻撃者は、被害者のIPアドレスと自分のMACアドレスを紐付けた ARP Reply を、まるで「私はゲートウェイです」と言わんばかりに撒き散らします。

Pythonによる攻撃のロジック(検証用)

攻撃者がどのようなロジックでパケットを送り込んでいるのか、scapy ライブラリを使うと一目瞭然です。

from scapy.all import Ether, ARP, send
import time

# ターゲット(被害者)とゲートウェイのIP
target_ip = "192.168.1.50"
gateway_ip = "192.168.1.1"

def spoof_target():
    # ターゲットに対して「私がゲートウェイだ」と嘘をつく
    packet = ARP(op=2, pdst=target_ip, hwdst="ターゲットのMAC", psrc=gateway_ip)
    send(packet, verbose=False)

# 無限ループで定期的に送信し、キャッシュを上書きし続ける
while True:
    spoof_target()
    time.sleep(2)

現場での防御:DAI(Dynamic ARP Inspection)

この攻撃を防ぐ唯一の実効的な手段は、DHCP Snooping で作成されたバインディングデータベースに基づき、不審なARPパケットを破棄する DAI です。

# DAIを有効化するコマンド
ip arp inspection vlan 10
# 特定のインターフェースを信頼設定
interface GigabitEthernet0/1
 ip arp inspection trust

—

3. Web APIエンジニアが知っておくべき「その先」

もし皆さんがAPI開発者であれば、ネットワークレベルでの改ざんを前提とした「ゼロトラストな設計」を心がける必要があります。

ネットワークが侵害された場合、攻撃者はSSL/TLS通信の途中で中間者として割り込もうとします。ここで重要になるのが TLS証明書の固定(Certificate Pinning) です。

curl でデバッグする際、もし中間者攻撃を疑うなら、以下のオプションで証明書を厳密に検証してください。

# 安全な接続を強制し、証明書の検証をスキップさせない
curl -v --cacert /path/to/trusted_ca.crt https://api.internal.service/v1/data

また、PythonでAPIを叩く際も、デフォルトの検証を無効にするようなコード(verify=False)は絶対にコードレビューで弾かなければなりません。

import requests

# 警告:verify=Falseは絶対に本番環境で使わないこと!
# ネットワーク侵害時に攻撃者の証明書を素通りさせてしまいます
response = requests.get(
    "https://api.internal.service/v1/data",
    verify="/path/to/ca.pem"  # 信頼できる証明書パスを明示する
)

—

最後に:ネットワークは「性悪説」で設計せよ

内部ネットワークは信頼できる、という考えはもはや幻想です。DHCPもARPも、設計当時は「善良なノードしかいない」という前提で書かれた古いプロトコルです。

1. スイッチのポートをセキュアに保つ(Snooping/DAIの徹底)
2. 通信経路を暗号化し、さらに検証する(TLS Pinningの検討)
3. 異常なARPトラフィックを監視する(ZabbixやPrometheusでARPテーブルの変動をアラート化)

これらは地味な作業ですが、一つ一つ積み上げることで、攻撃者にとって「コストのかかる、面倒な標的」になることができます。セキュリティとは、鉄壁を築くことではなく、攻撃者のROI(投資対効果)を極限まで下げることなのです。

現場の皆さんの奮闘を応援しています。何かネットワークの挙動で不可解なことがあれば、まずは tcpdump を握りしめてパケットの声を聞いてみてください。答えは必ずそこにあります。

コメント

タイトルとURLをコピーしました