はじめに
後編では、実際に実機を使いARPスプーフィングの検証をしていきます。 ARPの概要及び検証環境/環境構築については前編をご覧ください。
前編はこちら:【前編】社内LANは信頼できる?ARPスプーフィングの手口を実機で体感しよう
なお本記事のすべての内容は、実機のL3SW(Cisco Catalyst)とサーバ(PC模擬)で検証済みです。コマンド例・IPアドレス・MACアドレスはすべて検証で使った実値に統一し、要所には実際のスクリーンショットを証跡として掲載しています。
概要
本記事では、前編と後編の二部構成となっており実際に後編の内容である実機を使ったARPスプーフィングの検証をしていきます。後編の内容については以下となっております。
ARPの概要及び検証環境/環境構築については前編をご覧ください。
後編の内容:
・ハンズオンStep2: 攻撃前のARPテーブルの確認 ハンズオン
・ハンズオンStep3: arpspoofによるARPテーブルの上書き
・ハンズオンStep4: 偽サイトを表示させるパターン(フィッシング型)
・ハンズオンStep5: Wiresharkによるパケット解析
・ハンズオンStep6: DAI(Dynamic ARP Inspection)による防御の検証
・まとめ
それでは、実際にハンズオンを通してARPスプーフィングを検証していきましょう。
ハンズオンStep2: 攻撃前のARPテーブルの確認
攻撃を仕掛ける前に、ターゲットPCで正常なARPテーブルを確認し、事前の証跡として記録しておきます。
arp -a
インターフェイス: 192.168.56.3 --- 0x3f 192.168.56.1 08-00-27-5a-87-bc 動的 ← Kali 192.168.56.2 08-00-27-70-f1-c9 動的 ← Alma(本物) 192.168.56.255 ff-ff-ff-ff-ff-ff 静的

図: 攻撃前。サーバー 192.168.56.2のMACは 08-00-27-70-f1-c9。
ここで表示される 192.168.56.2(サーバー)のMACアドレス 08-00-27-70-f1-c9 が、この後の攻撃で ターゲットPCのARPテーブル上で 書き換わるかどうかを確認する基準になります。
参考までに、L2SW側の mac-address-table も見ておきます。この時点では各ポートに正規のMACが正しく学習されています。(Fa0/1=ターゲットPC、Fa0/2=サーバー、Fa0/3=攻撃元PC)。

ハンズオンStep3: arpspoofによるARPテーブルの上書き
攻撃元PC(Kali Linux)から、ターゲットPCとサーバーの双方に対して偽のARPリプライを送り続け、中間者攻撃を成立させます。
まず、攻撃元PCでIPフォワーディングを有効にし、自分を経由した通信がそのまま転送されるようにしておきます。
IPフォワーディングOFFのままだと、Kaliは「自分宛じゃない」これらのパケットを破棄 → ターゲット⇔サーバーの通信が途切れる → 被害者が異変に気づく。
IPフォワーディングONにすると、Kaliが受け取ったパケットを本物のサーバーへ中継(逆方向も同様)→ 被害者からは通信が正常 に見えたまま、実際は全通信がKaliを通過する=気づかれない盗聴(透過中継)が成立する。
echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward
続けて、2つのターミナルでarpspoofを実行します。
# ターゲットPCに対して「自分がサーバーだ」と偽装する sudo arpspoof -i eth0 -t 192.168.56.3 192.168.56.2
# サーバーに対して「自分がターゲットPCだ」と偽装する sudo arpspoof -i eth0 -t 192.168.56.2 192.168.56.3
この2つのコマンドを実行している間、攻撃元PCは「192.168.56.2 is-at 08:00:27:5a:87:bc(=私がサーバーです)」といった偽のARPリプライを一定間隔で送り続けます。

図: 2ターミナルで arpspoof を実行中。192.168.56.2/192.168.56.3 の両方に対して、Kaliの 8:0:27:5a:87:bc を「本人」と偽るARPリプライを送り続けている。
ここで再度ターゲットPCでarp -aを実行してみます。
arp -a
インターフェイス: 192.168.56.3 --- 0x3f 192.168.56.1 08-00-27-5a-87-bc 動的 192.168.56.2 08-00-27-5a-87-bc 動的 ← 攻撃元のMACアドレスに書き換わっている 192.168.56.255 ff-ff-ff-ff-ff-ff 静的

図: 攻撃後。192.168.56.2 のMACが、本来の 08-00-27-70-f1-c9 から攻撃者Kaliの 08-00-27-5a-87-bc に書き換わっている。
Step2で記録した本来のMACアドレス 08-00-27-70-f1-c9 が、攻撃元PCのMACアドレス 08-00-27-5a-87-bc に書き換わっていることが確認できます。ターゲットPCは、サーバー宛のつもりで送信したフレームを実際には攻撃元PCに送りつけてしまう状態になっています。
補足:L2SWのMACアドレステーブルは変わらない
ここで一つ、混同しやすいポイントを押さえておきます。攻撃中に L2SW の show mac address-table を見ても、Step2の攻撃前とまったく同じで、各ポートの学習内容は変化しません。

図: 攻撃中の L2SW の mac-address-table。Fa0/3=0800.275a.87bc(攻撃元PC)、Fa0/2=0800.2770.f1c9(サーバー)、Fa0/1=f8e4.3ba2.c92a(ターゲットPC) と、攻撃前から変わっていない。
これは、書き換わるのが各ホストのARPテーブルだけで、L2SWが持つMACアドレステーブルではないためです。
arpspoof が偽装するのはARPパケットの「中身」だけであり、そのフレームを運ぶEthernetの送信元MACは 攻撃元のMACアドレス(0800.275a.87bc)のまま Fa0/3 から送出されます。
L2SWは「送信元MAC+入ってきたポート」でMACアドレステーブルを学習するので、攻撃元PCの Fa0/3 のまま正しく学習され続け、テーブルは動きません。「ARPスプーフィングでL2SWのMACテーブルが汚染される」わけではない、という点は正確に区別しておきましょう。
ハンズオンStep4: 偽サイトを表示させるパターン(フィッシング型)
ここまでの手順(ip_forwardを有効にした透過中継)は、通信内容をそのまま本物のサーバーに転送するため、ターゲットPC側からは通信が正常に見え続け、攻撃に気づかれにくいという特徴があります。一方でARPスプーフィングは「通信経路の乗っ取り」に過ぎないため、攻撃者は転送する代わりに別の内容を返すこともできます。ここでは例として、Kali Linux自身が偽のWebページを返すフィッシング型のパターンを紹介します。
標的にしたいポート(例: HTTPの80番)宛の通信だけをKali自身に向けるため、iptablesでDNAT(宛先NAT)を設定します。
sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.56.1:80
これにより、ターゲットPCが 192.168.56.2(サーバー)の80番ポート宛に送ったパケットは、経路上でKali Linux自身(192.168.56.1)宛に書き換えられ、配送されるようになります。
続けて、Kali Linux上に簡易的なWebサーバーを立て、偽のページを配信します。偽ページはサーバーのWEBページとほぼ同じ構成ですが、Server: の表示だけを Kali にして、サーバーのWEBページと区別が付くようにしています(Step1のサーバー版 index.html の Alma を Kali に、見出しを hosted on kali に置き換えたものです)。
# /var/www/html/index.html に「Server: Kali」版のページを配置しておく cd /var/www/html sudo python3 -m http.server 80
ターゲットPC側でブラウザから http://192.168.56.2 にアクセスすると、実際にはサーバーのページではなく攻撃元PCが用意した偽ページが表示されます。

図: フィッシング型の成立。URLバーは正規の 192.168.56.2 のままなのに、表示されているのは 攻撃元PCが用意した偽ページ(hosted on kali / Server: Kali)。
Step1で確認したサーバーのページ(Server: Alma Linux)と見比べると、URLは正規のサーバーのままなのに、表示内容だけが差し替えられていることが分かります。見た目やアドレスバーだけでは気づきにくい点が、この手法の危険性です。
検証が終わったら、iptablesのルールを忘れずに削除しておきます。
sudo iptables -t nat -D PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.56.1:80
ハンズオンStep5: Wiresharkによるパケット解析
次に、攻撃元PCでWiresharkを起動し、実際に何が起きているのかをパケットレベルで観察します。
表示フィルタに arp と入力すると、arpspoof が送り続けている偽のARPリプライパケットを確認できます。
arp
キャプチャ結果には、192.168.56.2 is at 08:00:27:5a:87:bc のように、実際にはサーバーではない攻撃元PCが本人であるかのように応答しているARPリプライが、短い間隔で大量に流れています。
Wireshark自身も「同じIPに2つのMACが使われている」と気づき、Duplicate IP address detected の警告を出します。これはまさにARPスプーフィングが起きている動かぬ証拠です。

図: ターゲットPCのWiresharkでarp フィルタの観察。
攻撃元PC(Kali)の偽ARPリプライ(192.168.56.2 is at 08:00:27:5a:87:bc)が連続し、
Wiresharkが Duplicate IP address detected(192.168.56.2 のIPアドレスが 08:00:27:5a:87:bc と 08:00:27:70:f1:c9 両方でのMACアドレスで使われている)を検出している。
さらに表示フィルタを http(または ip.addr == 192.168.56.3 && ip.addr == 192.168.56.2)に変更すると、ターゲットPCとサーバー間の通信が攻撃元PCを経由して中継されていることが分かります。パケットのEthernetヘッダを見ると、送信元は f8:e4:3b:a2:c9:2a(ターゲットPC)なのに、宛先MACが 08:00:27:5a:87:bc(攻撃元PC)になっており、いったんKaliを通過していることが読み取れます。

図: 攻撃元PCのWiresharkでhttp フィルタの観察。192.168.56.3→192.168.56.2 のHTTP通信(Full request URI: http://192.168.56.2/)が、実際には攻撃元PCを経由して中継されている。
ターゲットPCから見れば通常通りサーバーと通信できているように見えますが、実際にはすべてのパケットが一度攻撃元PCを通過しており、内容の盗聴・改ざんが可能な状態になっています。
観察が終わったら、Step3で起動した2つのarpspoofコマンドをそれぞれのターミナルでCtrl+Cにより停止しておきます。
ハンズオンStep6: DAI(Dynamic ARP Inspection)による防御の検証
最後に、L2SW の機能であるDAI(Dynamic ARP Inspection)を使って、この攻撃を防げることを確認します。
DAIは通常、DHCP Snoopingによって収集した「どのポートにどのIPアドレス・MACアドレスの機器が接続されているか」という正当な対応表(バインディングテーブル)をもとに、流れてくるARPパケットの内容を検証し、対応表と矛盾するARPパケットを破棄するしくみです。
DAIは防御手法になるがただし注意点として、本ハンズオンのターゲットPC・サーバーはStep1で確認した通り静的IPで構成されており、DHCPでアドレスを払い出していません。
そのためDHCP Snoopingだけを有効にしてもバインディングテーブルは空のままとなり、DAIは攻撃者のARPだけでなく正規のターゲットPC・サーバーのARPまで無効なものとして破棄してしまいます。
静的IP環境でDAIを機能させるには、arp access-listで正規のIP-MAC対応をあらかじめ静的に定義しておく必要があります
今回の L2SW 構成のポイント
- VLANは 10(3台が収容されているアクセスVLAN)。
- ARP ACLには、攻撃者を含む3台すべてを登録します。攻撃元PCを除外すると、攻撃元PCが平常時に出す通常ARPまで破棄され、denyログが出続けてしまうためです。
- 今回は単一の L2SW に端末を直結しただけでアップリンクが無いため、
ip arp inspection trustは使いません
DAI設定
ip arp inspection vlan 10 を打った瞬間からDAIの検査が始まるので、ACLを用意する前に有効化すると、その瞬間から全ARPが破棄され、denyログが出続けます。
enable configure terminal ! ① 正規の3台すべて許可する arp access-list ARP-STATIC-ACL permit ip host 192.168.56.1 mac host 0800.275a.87bc ! 攻撃元PC permit ip host 192.168.56.2 mac host 0800.2770.f1c9 ! サーバー permit ip host 192.168.56.3 mac host f8e4.3ba2.c92a ! ターゲットPC exit ! ② ACLをDAIのフィルタとして適用する ip arp inspection filter ARP-STATIC-ACL vlan 10 static ! ③ 最後にDAIを有効化する ip arp inspection vlan 10 end write memory
正規の3台のARPはACLに一致するのでそのまま通り、平常時はログも出ません。一方、攻撃元PCが arpspoof を撃つと「送信元IPは 192.168.56.2 なのに送信元MACは攻撃元PCの 「0800.275a.87bc」という矛盾したARPになり、ACLの 192.168.56.2 = 0800.2770.f1c9 と一致しないため、そこだけがdenyと評価されます。
| 端末 | ARPの内容 | ACL照合 | 結果 |
|---|---|---|---|
| 攻撃元PC | 192.168.56.1 = 0800.275a.87bc | 一致 | 許可 |
| サーバー | 192.168.56.2 = 0800.2770.f1c9 | 一致 | 許可 |
| ターゲットPC | 192.168.56.3 = f8e4.3ba2.c92a | 一致 | 許可 |
| サーバー(攻撃後) | 192.168.56.2 != 0800.275a.87bc | 不一致 | 拒否 |
| ターゲットPC(攻撃後) | 192.168.56.3 != 0800.275a.87bc | 不一致 | 拒否 |
なぜ攻撃元PCの 192.168.56.1 も許可リストに入れるのか? 直感に反しますが、DAIで弾きたいのは「なりすまし(IP-MAC不一致)」だけです。
DAIを有効化して再攻撃してみる
DAIを有効化した状態で、Step3と同じarpspoofコマンドを再度実行してみます。
2つのターミナルでarpspoofを実行します。
# ターゲットPCに対して「自分がサーバーだ」と偽装する sudo arpspoof -i eth0 -t 192.168.56.3 192.168.56.2
# サーバーに対して「自分がターゲットPCだ」と偽装する sudo arpspoof -i eth0 -t 192.168.56.2 192.168.56.3
今度は攻撃元PCが送信した偽のARPリプライがL2SW側で破棄されるため、L2SWのコンソールには不正なARPを検知・破棄したログが記録され続けます。

図: DAIによるdenyログ。%SW_DAI-4-ACL_DENY: 1 Invalid ARPs (Res) on Fa0/3, vlan 10 ([0800.275a.87bc/192.168.56.1/0800.2770.f1c9/192.168.56.2 ...]) のように、Fa0/3(攻撃元PC)からの偽装ARPが破棄されている。
denyログの末尾 [送信元MAC / 送信元IP / 宛先MAC / 宛先IP] を読むと、「誰のARPが弾かれているか」を確認できます。 そしてこのとき、ターゲットPCの arp -a を見ると、192.168.56.2 のMACは本来の 08-00-27-70-f1-c9 のままで、書き換わっていません。

図: DAIによる防御成功。arpspoof を撃ってもターゲットPCのARPテーブルは汚染されず、 192.168.56.2 は正しい MACアドレス08-00-27-70-f1-c9 のまま。
Step3と比較すると、DAIの有無だけでARPスプーフィングが成立するかどうかが決まることが実機で確認できます。
まとめ
本記事では、ARPスプーフィングという攻撃について、プロトコルの仕組みから実機での攻撃・観察・防御まで一通り確認しました。
- ARPには送信元を検証する仕組みがなく、受け取ったARPリプライを無条件に信頼してARPテーブルを更新してしまう
- GARPの正当な性質が、そのままなりすましにも利用できてしまう
arpspoofを使えば、この性質を悪用して中間者攻撃を簡単に成立させられる(実機でも192.168.56.2のMACが攻撃者のものに書き換わり、URLは正規のまま偽ページに誘導できた)- Wiresharkで観察すると、偽のARPリプライと、それによって攻撃者経由に切り替わった通信の様子がはっきりと確認できる
- DAIのようにARPパケットの正当性をネットワーク機器側で検証する仕組みを導入することで、この攻撃を機械的に防ぐことができる
ARPスプーフィングは特別な脆弱性を突くものではなく、プロトコルの設計に起因する「そもそも防がれていない」攻撃です。
だからこそ、エンドポイント側の対策だけでなく、DHCP SnoopingやDAI、Port Securityといったスイッチ側の対策を組み合わせることが重要になります。
次のステップとして、DHCP Snoopingの詳細な仕組みや、MACアドレスの偽装を防ぐPort Securityについても学んでみることをおすすめします。
検証を通じての所感・考察
ARPスプーフィングは古典的な攻撃として名前は知っていましたが、実機を通してみて新たに認識した点がいくつかありました。
まず強く印象に残ったのは、攻撃が成立してもユーザー側にはほとんど手がかりが残らないという事実です。ターゲットPCのブラウザではURLが正規の IPアドレス 192.168.56.2 のまま表示され、アドレスバーの見た目も変わらず、(HTTP通信のため)証明書の警告も出ません。「表示が正常であること」がそのまま安全の根拠にはならない、という点を具体的な画面で確認できたことは、大きな収穫でした。
技術的にもっとも理解が深まったのは、攻撃によって書き換わるのはホストのARPテーブルであり、L2SWのMACアドレステーブルではないという切り分けです。当初はL2SW側にも変化が現れると想定し、攻撃前後で show mac address-table を比較しましたが、学習内容は一切変化しませんでした。
これは、arpspoof が偽装するのはARPパケットのペイロードのみで、フレームの送信元MACはKali本来のMACのまま送出されるためです。
L2SWは「送信元MACと受信ポート」を基準に学習するため、CAMテーブルは正常なまま保たれます。攻撃が作用するレイヤーの違いを、パケットの実データを見ながら整理できた点は実機検証ならではの学びでした。
総じて、物理の L2SW と実機を用いて検証したことで、「同一セグメント上に悪意ある端末が一台存在するだけで攻撃が成立する」という脅威を、より具体的に捉えることができました。
社内LANやフリーWi-Fiは接続できること自体が安全を意味するわけではなく、暗号化されていない通信の脆弱性や、L2レイヤーの対策の重要性を、実感を伴って理解できた検証でした。
1. We Are Hiring!
今回、私は自身の知的好奇心からARPスプーフィングというセキュリティ技術に触れてみましたが、ネットワークやインフラの仕組みを一段深く理解できると、自分のスキルをもっと実務で活かしたいと感じる方も多いのではないでしょうか。
FindConsultingには、異業種からAWSエンジニアへ転身し資格取得や後輩指導まで担うようになったメンバーや、フリーランスとしての基地局運用保守からTerraformを用いたAWS設計・構築案件に参画したメンバー、SQLのみのスキルから研修でPythonを習得しReact×Pythonの開発案件に挑戦したメンバーなど、入社後にキャリアを大きく広げた社員が多くいます。資格取得支援や実案件への早期参画など、次のステップへ踏み出すための環境が整っています。
「今のスキルだけでは先が不安」「新しい領域に挑戦してキャリアを広げたい」と感じている方は、ぜひ一度話を聞きに来ませんか?
現在、FindConsultingではキャリアチェンジ・スキルアップを目指す仲間を募集しています。
まずはカジュアル面談からでも、お気軽にお声がけください。


