- Published on
Wiresharkとネットワークセキュリティ完全ガイド:パケットスニッフィングから侵入検知まで開発者のための実践セキュリティ
- Authors

- Name
- Youngju Kim
- @fjvbn20031
- 1. なぜ開発者(かいはつしゃ)にネットワークセキュリティが重要(じゅうよう)なのか
- 2. Wireshark完全征服(せいふく)
- 3. tcpdump実践(じっせん)(サーバー環境)
- 4. パケットで読むプロトコル分析
- 5. 攻撃検知(こうげきけんち)実践
- 6. セキュリティツールエコシステム
- 7. ゼロトラストアーキテクチャ
- 8. 開発者のためのセキュリティチェックリスト
- 9. セキュリティ資格証(しかくしょう)ロードマップ
- 10. クイズ
- 11. 参考資料(さんこうしりょう)
1. なぜ開発者(かいはつしゃ)にネットワークセキュリティが重要(じゅうよう)なのか
セキュリティは選択(せんたく)ではなく必須(ひっす)
2025年のIBM Cost of a Data Breach Reportによると、データ漏洩(ろうえい)事故の平均(へいきん)コストは488万ドルに達(たっ)しています。これは前年比(ぜんねんひ)10%上昇(じょうしょう)した数値(すうち)であり、史上最高値(しじょうさいこうち)です。さらに衝撃的(しょうげきてき)なのは、セキュリティ事故の60%以上がアプリケーションレイヤーで発生(はっせい)しているという点です。
OWASP Top 10 2025を見ると、開発者が直接関与(かんよ)すべき脆弱性(ぜいじゃくせい)がほとんどです:
| 順位(じゅんい) | 脆弱性 | 開発者関連度(かんれんど) |
|---|---|---|
| 1 | Broken Access Control | 非常(ひじょう)に高い |
| 2 | Cryptographic Failures | 高い |
| 3 | Injection (SQL, XSS, LDAP) | 非常に高い |
| 4 | Insecure Design | 非常に高い |
| 5 | Security Misconfiguration | 高い |
| 6 | Vulnerable Components | 高い |
| 7 | Authentication Failures | 非常に高い |
| 8 | Data Integrity Failures | 高い |
| 9 | Logging/Monitoring Failures | 中程度(ちゅうていど) |
| 10 | SSRF (Server-Side Request Forgery) | 非常に高い |
2026年のサイバー脅威環境(きょういかんきょう)
2026年はサイバーセキュリティ史上(しじょう)最も危険(きけん)な年として記録(きろく)されています。米(べい)イラン紛争(ふんそう)の激化(げきか)に伴(ともな)い、国家(こっか)支援ハッキンググループの活動(かつどう)が700%以上急増(きゅうぞう)しました。主なトレンド:
- APT グループ活動急増: 国家支援グループが金融(きんゆう)、エネルギー、医療(いりょう)インフラを集中攻撃(こうげき)
- サプライチェーン攻撃拡大(かくだい): npm、PyPIなどのパッケージリポジトリを通じたマルウェア配布(はいふ)が3倍増加
- AI基盤攻撃: LLMを活用(かつよう)したフィッシングメール、自動化(じどうか)された脆弱性スキャニングが日常化
- ランサムウェア進化(しんか): 二重恐喝(きょうかつ)(データ流出(りゅうしゅつ)+暗号化(あんごうか))戦略が標準化
DevSecOpsとShift-Leftセキュリティ
従来(じゅうらい)のセキュリティは開発完了後のテスト段階(だんかい)で実施(じっし)されていました。しかしShift-Leftアプローチは開発初期段階からセキュリティを統合(とうごう)します。
従来のアプローチ:
設計 → 開発 → テスト → [セキュリティテスト] → デプロイ
← 問題発見時のコストが指数的に増加 →
Shift-Left:
[セキュリティ設計] → [セキュアコーディング] → [セキュリティテスト] → [セキュリティモニタリング]
← 早期発見でコスト削減 →
開発者がネットワークパケットを読めると:
- API呼び出しで機密(きみつ)データが平文(ひらぶん)で送信されていないか直接確認可能
- TLS設定エラーをデプロイ前に発見可能
- サードパーティライブラリの怪しいネットワーク活動を検知可能
- パフォーマンスボトルネックとセキュリティ脆弱性を同時に診断(しんだん)可能
2. Wireshark完全征服(せいふく)
2-1. インストールと初期設定(しょきせってい)
macOS:
brew install --cask wireshark
Ubuntu/Debian:
sudo apt update
sudo apt install wireshark
sudo usermod -aG wireshark $USER
# ログアウト後、再ログインが必要
Windows:
公式(こうしき)サイト(wireshark.org)からインストーラーをダウンロードします。インストール時にNpcapも一緒にインストールしてください。
2-2. インターフェース構成(こうせい)
Wiresharkのメイン画面は3つのパネルで構成されています:
- パケットリストパネル(上段):キャプチャされた全パケットの要約情報
- パケット詳細(しょうさい)パネル(中段):選択したパケットのプロトコル階層別詳細情報
- パケットバイトパネル(下段):生のバイナリデータ(Hex + ASCII)
2-3. Capture Filters vs Display Filters
この2つのフィルタはWiresharkを効果的に使用するための核心(かくしん)です。最も重要な違いは適用(てきよう)タイミングです。
| 区分(くぶん) | Capture Filter | Display Filter |
|---|---|---|
| 適用タイミング | キャプチャ開始前 | キャプチャ後(リアルタイム変更可能) |
| 文法 | BPF (Berkeley Packet Filter) | Wireshark独自文法 |
| パフォーマンス | 高い(カーネルレベルフィルタリング) | 低い(全パケットキャプチャ後フィルタリング) |
| 柔軟性(じゅうなんせい) | 制限的(せいげんてき) | 非常に柔軟 |
| 例 | host 192.168.1.1 | ip.addr == 192.168.1.1 |
| 例 | port 80 | tcp.port == 80 |
| 例 | tcp and port 443 | tcp.port == 443 |
Capture Filter例:
host 10.0.0.1
port 443
net 192.168.0.0/24
tcp and port 80
not arp
Display Filter例:
ip.addr == 10.0.0.1
tcp.port == 443
http.request.method == "GET"
dns.qry.name contains "google"
2-4. 必須Display Filter 30選(せん)
| 番号 | フィルタ | 用途(ようと) |
|---|---|---|
| 1 | ip.addr == 10.0.0.1 | 特定IP フィルタリング |
| 2 | tcp.port == 443 | HTTPSトラフィック |
| 3 | tcp.port == 80 | HTTPトラフィック |
| 4 | http.request.method == "POST" | POSTリクエストのみ |
| 5 | http.request.method == "GET" | GETリクエストのみ |
| 6 | dns.qry.name contains "example" | 特定ドメインDNSクエリ |
| 7 | tcp.flags.syn == 1 and tcp.flags.ack == 0 | SYNスキャン検知 |
| 8 | tcp.analysis.retransmission | TCP再送検知 |
| 9 | tcp.analysis.duplicate-ack | 重複ACK検知 |
| 10 | tcp.analysis.zero-window | Zero Window検知 |
| 11 | http.response.code == 500 | サーバーエラー応答 |
| 12 | http.response.code >= 400 | 全エラー応答 |
| 13 | tls.handshake.type == 1 | TLS Client Hello |
| 14 | tls.handshake.type == 2 | TLS Server Hello |
| 15 | arp | ARPパケットのみ |
| 16 | icmp | ICMP(ping)パケットのみ |
| 17 | dns | DNSパケットのみ |
| 18 | tcp.analysis.flags | TCP問題のあるパケット |
| 19 | http.cookie contains "session" | セッションCookie含むリクエスト |
| 20 | frame.time_delta > 1 | 1秒以上遅延パケット |
| 21 | tcp.len > 0 | データのあるTCPパケット |
| 22 | ip.src == 10.0.0.0/8 | 内部ネットワークソース |
| 23 | not arp and not dns | ARP、DNS除外 |
| 24 | http.host contains "api" | API呼び出しフィルタリング |
| 25 | tcp.stream eq 5 | 特定TCPストリーム |
| 26 | frame.len > 1500 | MTU超過(ちょうか)パケット |
| 27 | http.content_type contains "json" | JSONレスポンス |
| 28 | tcp.analysis.lost_segment | 損失(そんしつ)セグメント |
| 29 | ip.ttl < 10 | 低いTTL(ルーティング問題) |
| 30 | tls.handshake.extensions_server_name | SNIベースフィルタリング |
2-5. Follow Stream機能(きのう)
TCP Stream追跡はWiresharkの最も強力な機能の一つです:
- パケットを右クリックします
- Follow > TCP Stream を選択
- その接続の全データフローを確認できます
# TCP Stream例(HTTPリクエスト/レスポンス)
GET /api/users HTTP/1.1
Host: api.example.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
Accept: application/json
HTTP/1.1 200 OK
Content-Type: application/json
Set-Cookie: session=abc123; HttpOnly; Secure
[Response Body]
HTTP StreamはHTTP/2マルチプレキシング環境で個別HTTPトランザクションを追跡する際に有用です。
2-6. Statisticsメニュー活用
Conversations:どのIP間で最もトラフィックが往来しているか確認
Source Destination Packets Bytes
10.0.0.5 52.85.132.99 1,234 890KB
10.0.0.5 142.250.80.46 567 234KB
10.0.0.5 104.18.32.68 345 156KB
Protocol Hierarchy:プロトコル別トラフィック比率確認
Ethernet (100%)
├── IPv4 (98.5%)
│ ├── TCP (85.2%)
│ │ ├── TLS (62.1%)
│ │ ├── HTTP (15.3%)
│ │ └── Other (7.8%)
│ ├── UDP (12.8%)
│ │ ├── DNS (8.2%)
│ │ └── QUIC (4.6%)
│ └── ICMP (0.5%)
└── ARP (1.5%)
I/O Graphs:時間帯別トラフィックパターンを可視化します。DDoS攻撃やトラフィックスパイクの検知に必須です。
2-7. プロファイル設定とカラムカスタム
プロファイルを作成すると用途別に最適化された環境を切り替えられます:
プロファイル例:
- Default: 一般分析
- Security: セキュリティ分析(色規則、セキュリティ関連カラム)
- Performance: パフォーマンス分析(遅延時間、再送カラム)
- DNS: DNS分析専用
便利なカスタムカラム:
- Delta Time:前パケットとの時間差
- TCP Stream Index:ストリーム番号
- HTTP Host:HTTPリクエストのHostヘッダー
- TLS SNI:TLS Server Name Indication
3. tcpdump実践(じっせん)(サーバー環境)
3-1. 基本文法(きほんぶんぽう)とBPFフィルタ
tcpdumpはサーバーでGUIなしにパケットをキャプチャするツールです。WiresharkとBPF(Berkeley Packet Filter)文法が同じです。
基本構造:
tcpdump [オプション] [BPFフィルタ式]
主要(しゅよう)オプション:
-i eth0 # インターフェース指定
-w output.pcap # ファイルに保存
-r input.pcap # ファイル読み込み
-c 100 # パケット100個のみキャプチャ
-n # DNS逆引き無効化(速度向上)
-nn # ポート番号も名前変換しない
-v / -vv / -vvv # 詳細度増加
-X # Hex + ASCII出力
-A # ASCIIのみ出力
-s 0 # 全パケットキャプチャ(デフォルト: 262144 bytes)
-tttt # タイムスタンプを読みやすい形式で
3-2. 実践コマンド20選
| 番号 | コマンド | 用途 |
|---|---|---|
| 1 | sudo tcpdump -i eth0 | 基本キャプチャ |
| 2 | sudo tcpdump -i eth0 -w capture.pcap | ファイルに保存 |
| 3 | sudo tcpdump -i eth0 host 10.0.0.1 | 特定ホスト |
| 4 | sudo tcpdump -i eth0 port 443 | 特定ポート |
| 5 | sudo tcpdump -i eth0 src 10.0.0.1 | ソースIPフィルタ |
| 6 | sudo tcpdump -i eth0 dst port 80 | 宛先ポートフィルタ |
| 7 | sudo tcpdump -i eth0 net 192.168.0.0/24 | サブネットフィルタ |
| 8 | sudo tcpdump -i eth0 'tcp[tcpflags] & tcp-syn != 0' | SYNパケットのみ |
| 9 | sudo tcpdump -i eth0 -c 1000 -w sample.pcap | 1000個のみキャプチャ |
| 10 | sudo tcpdump -i eth0 -nn port 53 | DNSトラフィック |
| 11 | sudo tcpdump -i eth0 icmp | ICMP(ping)のみ |
| 12 | sudo tcpdump -i eth0 'port 80 and host 10.0.0.1' | 複合フィルタ |
| 13 | sudo tcpdump -i eth0 -A port 80 | HTTP内容表示 |
| 14 | sudo tcpdump -i eth0 'tcp[32:4] = 0x47455420' | GETリクエストのみ |
| 15 | sudo tcpdump -i eth0 greater 1000 | 1000バイト超過 |
| 16 | sudo tcpdump -i eth0 arp | ARPパケットのみ |
| 17 | sudo tcpdump -i eth0 -tttt -c 50 port 443 | タイムスタンプ付き |
| 18 | sudo tcpdump -i any port 8080 | 全インターフェース |
| 19 | sudo tcpdump -i eth0 not port 22 | SSH除外 |
| 20 | sudo tcpdump -i eth0 -G 3600 -w 'capture_%Y%m%d_%H.pcap' | 時間別ローテーション |
3-3. リモートサーバーキャプチャ → Wireshark分析
サーバーでキャプチャしたpcapファイルをローカルに持ってきてWiresharkで分析するワークフロー:
# 1. サーバーでキャプチャ
ssh user@server 'sudo tcpdump -i eth0 -c 5000 -w /tmp/capture.pcap port 443'
# 2. ローカルにコピー
scp user@server:/tmp/capture.pcap ./analysis/
# 3. Wiresharkで開く
wireshark ./analysis/capture.pcap
3-4. tcpdump + sshパイプライン(リアルタイム)
リモートサーバーのパケットをリアルタイムでローカルWiresharkで分析:
# 方法1: sshパイプ
ssh user@server 'sudo tcpdump -i eth0 -w - port 443' | wireshark -k -i -
# 方法2: named pipe使用
mkfifo /tmp/remote_capture
wireshark -k -i /tmp/remote_capture &
ssh user@server 'sudo tcpdump -i eth0 -w - port 443' > /tmp/remote_capture
# 方法3: 特定期間のみキャプチャ
ssh user@server 'sudo timeout 60 tcpdump -i eth0 -w - port 80' | wireshark -k -i -
この技法はプロダクションサーバーで発生するネットワーク問題をリアルタイムで分析する際に非常に有用です。
4. パケットで読むプロトコル分析
4-1. TCP 3-Way Handshakeパケット分析
TCP接続確立(かくりつ)の3-Way Handshakeをパケットレベルで分析します:
Step 1: SYN(クライアント → サーバー)
Source: 10.0.0.5:54321
Dest: 93.184.216.34:443
Flags: [SYN]
Seq: 0 (ISN: Initial Sequence Number)
Win: 65535
Options: MSS=1460, SACK Permitted, Window Scale=6
Step 2: SYN-ACK(サーバー → クライアント)
Source: 93.184.216.34:443
Dest: 10.0.0.5:54321
Flags: [SYN, ACK]
Seq: 0(サーバーのISN)
Ack: 1(クライアントISN + 1)
Win: 65535
Options: MSS=1400, SACK Permitted, Window Scale=7
Step 3: ACK(クライアント → サーバー)
Source: 10.0.0.5:54321
Dest: 93.184.216.34:443
Flags: [ACK]
Seq: 1
Ack: 1
Win: 65535
Wiresharkフィルタ:tcp.flags.syn == 1 でSYNパケットを見つけ、Follow TCP Streamで全ハンドシェイクを確認します。
問題診断ポイント:
- SYNのみでSYN-ACKがない場合:サーバーが応答していない(ファイアウォールブロックの可能性)
- SYN-ACKは来るが最終ACKがない場合:クライアント側の問題
- RSTパケットが即座に来る場合:ポートが閉じているかファイアウォールが接続拒否
4-2. HTTPリクエスト/レスポンス分析
# HTTPリクエストパケット詳細
Frame 45: 342 bytes on wire
Ethernet II: Src=aa:bb:cc:dd:ee:ff, Dst=11:22:33:44:55:66
Internet Protocol Version 4: Src=10.0.0.5, Dst=93.184.216.34
Transmission Control Protocol: Src Port=54321, Dst Port=80
Hypertext Transfer Protocol:
GET /api/v1/users?page=1 HTTP/1.1
Host: api.example.com
User-Agent: Mozilla/5.0 ...
Accept: application/json
Authorization: Bearer eyJhbGci...
Cookie: session_id=abc123
Connection: keep-alive
# HTTPレスポンスパケット詳細
Frame 47: 1280 bytes on wire
Hypertext Transfer Protocol:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Length: 956
Set-Cookie: session_id=xyz789; HttpOnly; Secure; SameSite=Strict
X-Request-Id: req_abc123
Strict-Transport-Security: max-age=31536000
X-Content-Type-Options: nosniff
セキュリティ観点での確認事項(じこう):
- Authorizationヘッダーが平文HTTPで送信されていないか
- Set-CookieにHttpOnly、Secureフラグがあるか
- セキュリティヘッダー(HSTS、X-Content-Type-Optionsなど)が設定されているか
- レスポンスに機密情報が含まれていないか
4-3. DNSクエリ/レスポンスパケット構造
# DNSクエリ(Query)
Domain Name System (query)
Transaction ID: 0x1a2b
Flags: 0x0100 Standard query
Questions: 1
Queries:
api.example.com: type A, class IN
# DNSレスポンス(Response)
Domain Name System (response)
Transaction ID: 0x1a2b
Flags: 0x8180 Standard query response, No error
Questions: 1
Answer RRs: 2
Answers:
api.example.com: type A, class IN, addr 93.184.216.34
TTL: 300 (5 minutes)
api.example.com: type A, class IN, addr 93.184.216.35
TTL: 300 (5 minutes)
DNSセキュリティ点検:
- DNSクエリが暗号化(あんごうか)されずに送信されていないか(DoH/DoT使用有無)
- 異常に長いドメイン名(DNSトンネリング疑い)
- 不明なDNSサーバーへのクエリ(DNSハイジャックの可能性)
4-4. TLS Handshakeパケット分析
TLS 1.3ハンドシェイクは1-RTT(Round Trip Time)で以前のバージョンより高速です:
Step 1: Client Hello
TLS Record Layer:
Content Type: Handshake (22)
Version: TLS 1.0(互換性)
Handshake Protocol: Client Hello
Version: TLS 1.2(互換性のため)
Random: [32 bytes]
Session ID: [32 bytes]
Cipher Suites (17 suites):
TLS_AES_256_GCM_SHA384
TLS_AES_128_GCM_SHA256
TLS_CHACHA20_POLY1305_SHA256
Extensions:
server_name: api.example.com (SNI)
supported_versions: TLS 1.3
key_share: x25519 [public key]
signature_algorithms: ecdsa_secp256r1_sha256, rsa_pss_rsae_sha256
Step 2: Server Hello + Certificate + Finished
Handshake Protocol: Server Hello
Cipher Suite: TLS_AES_256_GCM_SHA384
Key Share: x25519 [server public key]
[Encrypted Extensions]
[Certificate]
[Certificate Verify]
[Finished]
Step 3: Client Finished (Encrypted)
[Change Cipher Spec]
[Finished]
4-5. TLS復号化:SSLKEYLOGFILE環境変数設定
開発/デバッグ環境でTLSトラフィックを復号化できます:
# 1. 環境変数設定(bash)
export SSLKEYLOGFILE="$HOME/.ssl-keys.log"
# 2. ChromeまたはFirefoxを起動(この環境変数を自動認識)
# ブラウザがTLSセッションキーをファイルに記録します
# 3. curlでも使用可能
SSLKEYLOGFILE=$HOME/.ssl-keys.log curl https://api.example.com/health
Wireshark設定:
- Edit > Preferences > Protocols > TLS
- (Pre)-Master-Secret log filenameにキーファイルパスを入力
- 以降キャプチャされたTLSトラフィックが復号化されて表示されます
注意:プロダクション環境では絶対に使用しないでください。開発/ステージング環境でのみ使用してください。
5. 攻撃検知(こうげきけんち)実践
5-1. ARPスプーフィング検知
ARPスプーフィングはローカルネットワークでMACアドレスを偽造(ぎぞう)してトラフィックを傍受(ぼうじゅ)する攻撃です。
正常なARP動作:
Who has 10.0.0.1? Tell 10.0.0.5
→ 10.0.0.1 is at aa:bb:cc:dd:ee:ff
ARPスプーフィング検知シナリオ:
# 攻撃者がゲートウェイ(10.0.0.1)を詐称
10.0.0.1 is at [攻撃者MAC: 11:22:33:44:55:66] ← 異常!
10.0.0.1 is at [実際MAC: aa:bb:cc:dd:ee:ff] ← 正常
# 同じIPに対して2つの異なるMACアドレス → ARPスプーフィング!
Wiresharkフィルタ:
arp.duplicate-address-detected
arp.duplicate-address-frame
検知スクリプト:
#!/bin/bash
# ARPテーブルモニタリング
while true; do
arp -a | sort > /tmp/arp_current.txt
if [ -f /tmp/arp_previous.txt ]; then
diff /tmp/arp_previous.txt /tmp/arp_current.txt
if [ $? -ne 0 ]; then
echo "[ALERT] ARP table changed at $(date)"
diff /tmp/arp_previous.txt /tmp/arp_current.txt
fi
fi
cp /tmp/arp_current.txt /tmp/arp_previous.txt
sleep 10
done
5-2. ポートスキャン検知
SYN Scan(Half-Open Scan)パターン:
Nmapのデフォルトスキャン方式です。SYNパケットだけ送って接続を完了しません。
攻撃者 → 対象:22 [SYN]
対象:22 → 攻撃者 [SYN,ACK] ← ポート開放
攻撃者 → 対象:22 [RST] ← 接続未完了
攻撃者 → 対象:23 [SYN]
対象:23 → 攻撃者 [RST,ACK] ← ポート閉鎖
Wiresharkフィルタ:
# SYNスキャン検知(ACKなしのSYNのみ)
tcp.flags.syn == 1 and tcp.flags.ack == 0
# 短時間に多数のポートへSYN
tcp.flags.syn == 1 and tcp.flags.ack == 0 and ip.src == 10.0.0.100
Nmapスキャン種類別パケット特徴:
| スキャン種類 | コマンド | TCPフラグ | 特徴 |
|---|---|---|---|
| SYN Scan | nmap -sS | SYN | 最も一般的、Half-open |
| Connect Scan | nmap -sT | Full handshake | 完全なTCP接続 |
| FIN Scan | nmap -sF | FIN | ステルススキャン |
| XMAS Scan | nmap -sX | FIN,PSH,URG | Christmas Tree |
| NULL Scan | nmap -sN | (なし) | フラグなしパケット |
| ACK Scan | nmap -sA | ACK | ファイアウォール規則検知 |
| UDP Scan | nmap -sU | UDP | ICMPレスポンスで判断 |
5-3. DDoSパターン分析
SYN Flood:
# 大量のSYNパケットが様々なソースIPから同時に流入
# Wiresharkフィルタ
tcp.flags.syn == 1 and tcp.flags.ack == 0
# tcpdumpでSYNパケットカウント
sudo tcpdump -i eth0 'tcp[tcpflags] & tcp-syn != 0' -c 10000 2>&1 | tail -1
# 結果: 数秒で"10000 packets captured"が出ればSYN Flood疑い
HTTP Flood:
# 同一URLに対する大量リクエスト
# Wiresharkフィルタ
http.request.uri == "/api/login"
# 毎秒リクエスト数確認
# Statistics > I/O Graphでhttp.requestをY軸に設定
DNS Amplification:
# DNSレスポンスがクエリよりはるかに大きい場合(増幅比率)
# 小さなクエリ(約60 bytes)→ 大きなレスポンス(約3000+ bytes)
# Wiresharkフィルタ
dns.response and frame.len > 1000
# 増幅比率 = レスポンスサイズ / リクエストサイズ
# ANYクエリの増幅比率: 約28x ~ 54x
DDoS検知チェックリスト:
- I/O Graphでトラフィック急増を確認
- Conversationsで上位ソースIPを確認
- Protocol Hierarchyで特定プロトコル比率の急増を確認
- 同一パターンの繰り返しリクエストを確認
- 異常なソースIP帯域を確認(GeoIP活用)
5-4. SQLインジェクション検知
HTTP POST BodyからSQLキーワードを検索します:
# Wireshark Display Filter
http.request.method == "POST" and (
http contains "UNION" or
http contains "SELECT" or
http contains "DROP" or
http contains "DELETE" or
http contains "1=1" or
http contains "OR 1" or
http contains "--" or
http contains "/*"
)
実際のSQLインジェクションパケット例:
POST /api/login HTTP/1.1
Host: vulnerable-app.com
Content-Type: application/x-www-form-urlencoded
username=admin' OR '1'='1&password=anything
異常レスポンスサイズパターン:
- 正常ログイン失敗レスポンス:約200 bytes
- SQLインジェクション成功時:数千bytes(データ流出)
# 異常レスポンスサイズ検知
http.response and http.content_length > 10000
5-5. データ流出(りゅうしゅつ)検知
DNSトンネリング検知:
DNSトンネリングはDNSクエリにデータをエンコードしてファイアウォールを迂回(うかい)する技法です。
# 正常DNSクエリ
api.example.com(15文字)
# DNSトンネリングクエリ(異常に長いドメイン)
dGhpcyBpcyBhIHNlY3JldCBtZXNzYWdl.tunnel.evil.com(48文字)
Wiresharkフィルタ:
# 異常長DNSクエリ検知
dns.qry.name.len > 50
# TXTレコードクエリ(トンネリングに頻繁に使用)
dns.qry.type == 16
# 特定ドメインへの異常に多いクエリ
dns.qry.name contains "tunnel.evil.com"
異常アウトバウンドトラフィック検知:
# tcpdumpで大容量アウトバウンドモニタリング
sudo tcpdump -i eth0 'src net 10.0.0.0/8 and dst net not 10.0.0.0/8 and greater 10000' -c 100
# 異常ポートへのアウトバウンド
sudo tcpdump -i eth0 'src net 10.0.0.0/8 and not (dst port 80 or dst port 443 or dst port 53 or dst port 22)'
6. セキュリティツールエコシステム
6-1. Nmap:ネットワークスキャナー
Nmapはネットワーク探索(たんさく)とセキュリティ監査(かんさ)のためのオープンソースツールです。
# 基本ポートスキャン
nmap 192.168.1.1
# サービスバージョン検知
nmap -sV 192.168.1.1
# OS検知
nmap -O 192.168.1.1
# アグレッシブスキャン(サービス、OS、スクリプト、traceroute)
nmap -A 192.168.1.1
# 全ポートスキャン
nmap -p- 192.168.1.1
# NSEスクリプト活用
nmap --script vuln 192.168.1.1
nmap --script ssl-heartbleed 192.168.1.1
nmap --script http-sql-injection 192.168.1.1
6-2. Burp Suite:Webアプリセキュリティテスト
Burp SuiteはWebアプリケーションセキュリティテストの標準ツールです。
主要機能:
- Proxy:ブラウザとサーバー間のリクエスト/レスポンスの傍受・修正
- Scanner:自動脆弱性スキャン(SQLインジェクション、XSS、CSRFなど)
- Intruder:自動化攻撃(ブルートフォース、ファジング)
- Repeater:個別リクエストの修正・再送
- Decoder:エンコード/デコードユーティリティ
6-3. OWASP ZAP:無料(むりょう)Webセキュリティスキャナー
# Dockerで素早くスキャン
docker run -t zaproxy/zap-stable zap-baseline.py -t https://target.com
# APIスキャン
docker run -t zaproxy/zap-stable zap-api-scan.py -t https://target.com/openapi.json -f openapi
# フルスキャン
docker run -t zaproxy/zap-stable zap-full-scan.py -t https://target.com
6-4. Snort / Suricata:IDS/IPS
# Suricataインストール(Ubuntu)
sudo apt install suricata
# ルール更新
sudo suricata-update
# IDSモードで実行
sudo suricata -c /etc/suricata/suricata.yaml -i eth0
# カスタムルール例
# /etc/suricata/rules/local.rules
# alert http any any -> any any (msg:"SQL Injection Attempt"; content:"UNION SELECT"; nocase; sid:1000001; rev:1;)
# alert dns any any -> any any (msg:"DNS Tunneling Suspected"; dns.query; content:".tunnel."; nocase; sid:1000002; rev:1;)
6-5. Metasploit:侵入(しんにゅう)テストフレームワーク
# Metasploit起動
msfconsole
# 脆弱性検索
# msf6> search type:exploit platform:linux apache
# モジュール使用例
# msf6> use exploit/multi/http/apache_log4j
# msf6> set RHOSTS target.com
# msf6> set RPORT 8080
# msf6> run
6-6. ツール比較表(ひかくひょう)
| ツール | 用途 | ライセンス | 難易度(なんいど) | 主な対象 |
|---|---|---|---|---|
| Wireshark | パケット分析 | 無料/OSS | 中級 | ネットワークエンジニア、開発者 |
| tcpdump | CLIパケットキャプチャ | 無料/OSS | 中級 | システム管理者 |
| Nmap | ポートスキャニング | 無料/OSS | 初級 | セキュリティエンジニア |
| Burp Suite | Webセキュリティテスト | 有料/無料版 | 上級 | ペンテスター |
| OWASP ZAP | Webセキュリティスキャン | 無料/OSS | 中級 | 開発者、QA |
| Snort | IDS/IPS | 無料/OSS | 上級 | セキュリティ運用 |
| Suricata | IDS/IPS | 無料/OSS | 上級 | セキュリティ運用 |
| Metasploit | 侵入テスト | 有料/無料版 | 上級 | ペンテスター |
7. ゼロトラストアーキテクチャ
7-1. 基本原則(きほんげんそく):Never Trust, Always Verify
従来のセキュリティモデルは「城(しろ)と堀(ほり)」アプローチでした。内部ネットワークは信頼(しんらい)し、外部のみをブロックします。しかしこのモデルは内部脅威やVPN侵害時に無力です。
ゼロトラストは根本的(こんぽんてき)に異なります:
従来モデル:
[インターネット] --ファイアウォール-- [内部ネットワーク: すべて信頼]
→ 内部侵入時、横方向移動(Lateral Movement)が自由
ゼロトラスト:
[すべてのリクエスト] --認証/認可-- [リソース]
→ すべてのアクセスを検証(場所に関係なく)
核心原則:
- 明示的検証(めいじてきけんしょう):すべてのリクエストを認証、認可、暗号化
- 最小権限(さいしょうけんげん):必要最小限の権限のみ付与(Just-In-Time、Just-Enough-Access)
- 侵害想定(しんがいそうてい):すでに侵害されたと想定して設計
7-2. マイクロセグメンテーション
ネットワークを小さな領域に分離して横方向移動を阻止(そし)します:
従来のネットワーク:
[Webサーバー] ←→ [Appサーバー] ←→ [DBサーバー]
すべて同じVLAN、自由な通信
マイクロセグメンテーション:
[Webサーバー] --ポリシー-→ [Appサーバー] --ポリシー-→ [DBサーバー]
各通信に別個のセキュリティポリシー適用
- Web → App: ポート8080のみ許可
- App → DB: ポート5432のみ許可
- Web → DB: ブロック
7-3. mTLS(相互認証(そうごにんしょう))実装
通常のTLSはサーバーのみ認証しますが、mTLSはクライアントも認証します:
通常TLS:
Client → Server: 「あなたが本物のサーバーであることを証明してください」
Server → Client: [サーバー証明書]
→ クライアントは検証されない
mTLS:
Client → Server: 「あなたが本物であることを証明してください」
Server → Client: [サーバー証明書] + 「あなたも証明してください」
Client → Server: [クライアント証明書]
→ 双方向認証完了
Node.js mTLSサーバー例:
const https = require('https')
const fs = require('fs')
const options = {
key: fs.readFileSync('server-key.pem'),
cert: fs.readFileSync('server-cert.pem'),
ca: fs.readFileSync('ca-cert.pem'), // CA証明書
requestCert: true, // クライアント証明書要求
rejectUnauthorized: true, // 無効な証明書を拒否
}
const server = https.createServer(options, (req, res) => {
const clientCert = req.socket.getPeerCertificate()
console.log('Client CN:', clientCert.subject.CN)
res.writeHead(200)
res.end('Mutual TLS authenticated!\n')
})
server.listen(443)
7-4. Service Mesh(Istio)でのセキュリティ
Istioはマイクロサービス間通信に自動的にmTLSを適用します:
# Istio PeerAuthentication - mTLS強制
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
namespace: production
spec:
mtls:
mode: STRICT # mTLS必須
---
# Istio AuthorizationPolicy - 細かいアクセス制御
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: api-access
namespace: production
spec:
selector:
matchLabels:
app: api-server
rules:
- from:
- source:
principals: ['cluster.local/ns/production/sa/frontend']
to:
- operation:
methods: ['GET', 'POST']
paths: ['/api/v1/*']
7-5. ゼロトラストとKubernetes
# Kubernetes NetworkPolicy - Pod間通信制御
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: api-network-policy
namespace: production
spec:
podSelector:
matchLabels:
app: api-server
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
egress:
- to:
- podSelector:
matchLabels:
app: database
ports:
- protocol: TCP
port: 5432
- to: # DNS許可
- namespaceSelector: {}
ports:
- protocol: UDP
port: 53
---
# Pod Security Standards
apiVersion: v1
kind: Pod
metadata:
name: secure-pod
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 2000
seccompProfile:
type: RuntimeDefault
containers:
- name: app
image: myapp:latest
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
resources:
limits:
memory: '256Mi'
cpu: '500m'
8. 開発者のためのセキュリティチェックリスト
8-1. HTTPS強制とHSTS
# Nginx設定
server {
listen 80;
server_name example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# HSTSヘッダー(2年、サブドメイン含む、preload)
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
# TLS設定
ssl_protocols TLSv1.3 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
}
8-2. CORS設定
// Express.js - 安全なCORS設定
const cors = require('cors')
const corsOptions = {
origin: ['https://app.example.com', 'https://admin.example.com'],
methods: ['GET', 'POST', 'PUT', 'DELETE'],
allowedHeaders: ['Content-Type', 'Authorization'],
credentials: true,
maxAge: 86400, // Preflightキャッシュ24時間
}
app.use(cors(corsOptions))
// 絶対にこうしないでください:
// app.use(cors()); // 全オリジン許可 = セキュリティ脆弱
8-3. Rate Limiting
// Express.js - Rate Limiting
const rateLimit = require('express-rate-limit')
// 一般API
const apiLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15分
max: 100, // 最大100リクエスト
message: 'Too many requests, please try again later.',
standardHeaders: true,
legacyHeaders: false,
})
// ログインエンドポイント(より厳格)
const loginLimiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 5,
message: 'Too many login attempts, please try again after 15 minutes.',
})
app.use('/api/', apiLimiter)
app.use('/api/login', loginLimiter)
8-4. Input Validation
// Joiを使用した入力検証
const Joi = require('joi')
const userSchema = Joi.object({
username: Joi.string().alphanum().min(3).max(30).required(),
email: Joi.string().email().required(),
password: Joi.string()
.min(12)
.pattern(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])/)
.required(),
age: Joi.number().integer().min(13).max(120),
})
app.post('/api/register', (req, res) => {
const result = userSchema.validate(req.body)
if (result.error) {
return res.status(400).json({
error: result.error.details[0].message,
})
}
// 検証通過後の処理
})
8-5. SQLパラメータ化クエリ
// Node.js + PostgreSQL - 安全なクエリ
const { Pool } = require('pg')
const pool = new Pool()
// 絶対にしないでください(SQLインジェクション脆弱):
// const query = `SELECT * FROM users WHERE id = ${userId}`;
// 正しい方法: パラメータ化クエリ
async function getUser(userId) {
const result = await pool.query('SELECT id, username, email FROM users WHERE id = $1', [userId])
return result.rows[0]
}
// ORM使用(Prisma)
async function getUserPrisma(userId) {
return await prisma.user.findUnique({
where: { id: userId },
select: { id: true, username: true, email: true },
})
}
8-6. JWT/OAuth2セキュリティ
// JWTセキュリティベストプラクティス
const jwt = require('jsonwebtoken')
// Access Token: 短い有効期限
const accessToken = jwt.sign({ userId: user.id, role: user.role }, process.env.JWT_SECRET, {
expiresIn: '15m', // 15分
algorithm: 'RS256', // RSA非対称キー使用
issuer: 'api.example.com',
audience: 'app.example.com',
})
// Refresh Token: DBに保存、ローテーション適用
const refreshToken = jwt.sign(
{ userId: user.id, tokenVersion: user.tokenVersion },
process.env.REFRESH_SECRET,
{ expiresIn: '7d' }
)
// 検証ミドルウェア
function verifyToken(req, res, next) {
const token = req.headers.authorization?.split(' ')[1]
if (!token) return res.status(401).json({ error: 'No token' })
try {
const decoded = jwt.verify(token, process.env.JWT_PUBLIC_KEY, {
algorithms: ['RS256'],
issuer: 'api.example.com',
audience: 'app.example.com',
})
req.user = decoded
next()
} catch (err) {
return res.status(401).json({ error: 'Invalid token' })
}
}
8-7. シークレット管理
# HashiCorp Vault使用例
vault kv put secret/myapp/db \
username="dbuser" \
password="supersecret" \
host="db.internal.example.com"
# アプリケーションから読み取り
vault kv get -field=password secret/myapp/db
// AWS Secrets Manager
const { SecretsManagerClient, GetSecretValueCommand } = require('@aws-sdk/client-secrets-manager')
async function getSecret(secretName) {
const client = new SecretsManagerClient({ region: 'us-east-1' })
const response = await client.send(new GetSecretValueCommand({ SecretId: secretName }))
return JSON.parse(response.SecretString)
}
// 使用
const dbCreds = await getSecret('production/database')
8-8. セキュリティヘッダー
// Helmet.jsでセキュリティヘッダー設定
const helmet = require('helmet')
app.use(
helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'"],
styleSrc: ["'self'", "'unsafe-inline'"],
imgSrc: ["'self'", 'data:', 'https:'],
connectSrc: ["'self'", 'https://api.example.com'],
fontSrc: ["'self'", 'https://fonts.gstatic.com'],
objectSrc: ["'none'"],
mediaSrc: ["'none'"],
frameSrc: ["'none'"],
},
},
crossOriginEmbedderPolicy: true,
crossOriginOpenerPolicy: true,
crossOriginResourcePolicy: { policy: 'same-site' },
hsts: { maxAge: 63072000, includeSubDomains: true, preload: true },
noSniff: true, // X-Content-Type-Options: nosniff
referrerPolicy: { policy: 'strict-origin-when-cross-origin' },
xssFilter: true, // X-XSS-Protection
})
)
8-9. 依存関係(いぞんかんけい)脆弱性スキャン
# npm audit
npm audit
npm audit fix
# Snyk
npx snyk test
npx snyk monitor
# GitHub Dependabot(自動PR作成)
# .github/dependabot.yml
# .github/dependabot.yml
version: 2
updates:
- package-ecosystem: 'npm'
directory: '/'
schedule:
interval: 'weekly'
open-pull-requests-limit: 10
reviewers:
- 'security-team'
labels:
- 'dependencies'
- 'security'
総合セキュリティチェックリスト:
| 項目(こうもく) | 重要度 | 確認 |
|---|---|---|
| HTTPS強制 + HSTS | 必須 | - |
| TLS 1.2+のみ許可 | 必須 | - |
| CORSホワイトリスト | 必須 | - |
| Rate Limiting | 必須 | - |
| Input Validation | 必須 | - |
| パラメータ化クエリ | 必須 | - |
| JWT RS256 + 短い有効期限 | 高 | - |
| Refresh Tokenローテーション | 高 | - |
| シークレットマネージャー使用 | 必須 | - |
| CSPヘッダー | 高 | - |
| X-Content-Type-Options | 高 | - |
| Referrer-Policy | 中 | - |
| 依存関係脆弱性スキャン | 必須 | - |
| Dependabot有効化 | 高 | - |
| セキュリティログ/モニタリング | 必須 | - |
9. セキュリティ資格証(しかくしょう)ロードマップ
入門(にゅうもん) → 中級 → 上級ルート
入門(0〜1年目):
CompTIA Security+
├── 難易度: ★★☆☆☆
├── 費用: 約$404(試験料)
├── 準備期間: 2〜3ヶ月
├── 内容: セキュリティ基礎、脅威、暗号化、ネットワークセキュリティ
└── キャリアインパクト: ITセキュリティ入門、政府/軍関連で必須
中級(1〜3年目):
CEH (Certified Ethical Hacker)
├── 難易度: ★★★☆☆
├── 費用: 約$1,199(試験料)
├── 準備期間: 3〜4ヶ月
├── 内容: ハッキング技法、脆弱性分析、侵入テスト
└── キャリアインパクト: セキュリティアナリスト、ペンテスター
CISSP(セキュリティ管理者ルート)
├── 難易度: ★★★★☆
├── 費用: 約$749(試験料)
├── 準備期間: 4〜6ヶ月(経験5年必要)
├── 内容: セキュリティ管理、ガバナンス、リスク管理
└── キャリアインパクト: CISO、セキュリティアーキテクト
上級(3年目+):
OSCP (Offensive Security Certified Professional)
├── 難易度: ★★★★★
├── 費用: 約$1,649(トレーニング + 試験)
├── 準備期間: 6〜12ヶ月
├── 内容: 24時間実践侵入テスト試験
└── キャリアインパクト: シニアペンテスター、レッドチーム
資格証別詳細比較
| 資格証 | 対象 | 実技比率 | 更新周期 | 平均年収上昇 |
|---|---|---|---|---|
| CompTIA Security+ | 入門者 | 20% | 3年 | +15% |
| CEH | 中級者 | 40% | 3年 | +20% |
| CISSP | 管理者 | 0%(理論) | 3年 | +25% |
| OSCP | 専門家 | 100%(実技) | なし | +35% |
| GPEN | ペンテスター | 60% | 4年 | +25% |
| CISM | マネージャー | 0%(理論) | 3年 | +20% |
開発者向け推奨ルート
Web開発者:
Security+ → CEH → OSCP → Bug Bounty
クラウド開発者:
Security+ → AWS Security Specialty → CCSP
DevOpsエンジニア:
Security+ → CKS (Kubernetes Security) → OSCP
10. クイズ
ここまで学んだ内容を確認しましょう。
Q1. WiresharkでCapture FilterとDisplay Filterの最大の違いは?
正解:適用タイミングが異なります。
- Capture Filter:キャプチャ開始前に設定し、BPF文法を使用します。カーネルレベルでフィルタリングするためパフォーマンスが良いですが、キャプチャ中に変更できません。
- Display Filter:キャプチャ後に適用し、Wireshark独自の文法を使用します。既にキャプチャされたデータからフィルタリングするため、リアルタイムで変更可能です。
大量トラフィック環境ではCapture Filterで必要なトラフィックのみキャプチャし、Display Filterで精密に分析するのがベストプラクティスです。
Q2. TLSトラフィックをWiresharkで復号化するにはどの環境変数を設定する必要がありますか?
正解:SSLKEYLOGFILE
SSLKEYLOGFILE環境変数を設定すると、Chrome、Firefoxなどのブラウザが指定されたファイルにTLSセッションキーを記録します。Wiresharkでこのファイルを指定すれば(Edit - Preferences - Protocols - TLS)TLSで暗号化されたトラフィックの内容を確認できます。
注意:この機能は開発/デバッグ環境でのみ使用すべきであり、プロダクション環境では絶対に使用してはいけません。
Q3. SYN Flood DDoS攻撃をWiresharkで検知するにはどのフィルタを使用しますか?
正解:tcp.flags.syn == 1 and tcp.flags.ack == 0
このフィルタはACKフラグなしでSYNフラグのみ設定されたパケットを表示します。SYN Flood攻撃は大量のSYNパケットを送ってサーバーのTCP接続テーブルを溢れさせる攻撃です。
さらにStatistics - I/O Graphsでこのフィルタを適用すると、時間帯別のSYNパケット急増パターンを視覚的に確認できます。
Q4. ゼロトラストセキュリティモデルの3つの核心原則は?
正解:
- 明示的検証(Verify Explicitly):すべてのリクエストを常に認証・認可します。場所やネットワークに関係なく、すべてのアクセスを検証します。
- 最小権限(Least Privilege):Just-In-Time、Just-Enough-Access原則で必要最小限の権限のみ付与します。
- 侵害想定(Assume Breach):すでに侵害されたと想定し、横方向移動を最小化し、エンドツーエンド暗号化を適用します。
従来の「城と堀」モデルとは異なり、内部ネットワークも信頼しないことが核心です。
Q5. DNSトンネリングを検知するために確認すべき主な指標は?
正解:
- 異常に長いドメイン名:正常なDNSクエリは通常20〜30文字ですが、DNSトンネリングは50文字以上のエンコードされたデータを含みます。
- TXTレコードクエリの急増:DNSトンネリングはより多くのデータを送信するためにTXTレコードを頻繁に使用します。
- 特定ドメインへの異常なクエリ頻度:同じドメインに対して毎秒数十〜数百件のクエリが発生します。
Wiresharkフィルタ:dns.qry.name.len > 50 または dns.qry.type == 16(TXTレコード)で検知できます。
11. 参考資料(さんこうしりょう)
- Wireshark公式ドキュメント - wireshark.org/docs
- tcpdumpマニュアル - tcpdump.org/manpages
- OWASP Top 10 (2025) - owasp.org/Top10
- NISTゼロトラストアーキテクチャ (SP 800-207) - csrc.nist.gov
- IBM Cost of a Data Breach Report 2025 - ibm.com/security
- Nmapリファレンスガイド - nmap.org/book/man.html
- Metasploit Unleashed - offensive-security.com/metasploit-unleashed
- SANSネットワークフォレンジック - sans.org/cyber-security-courses/network-forensics
- Practical Packet Analysis, 3rd Edition - Chris Sanders (No Starch Press)
- The Web Application Hacker's Handbook - Dafydd Stuttard, Marcus Pinto
- CompTIA Security+ Study Guide - comptia.org/certifications/security
- OSCP Certification Guide - offensive-security.com/pwk-oscp
- Suricata IDSドキュメント - suricata.readthedocs.io
- Istioセキュリティドキュメント - istio.io/latest/docs/concepts/security
- Kubernetesネットワークポリシー - kubernetes.io/docs/concepts/services-networking/network-policies
- OWASP ZAPドキュメント - zaproxy.org/docs
- Burp Suiteドキュメント - portswigger.net/burp/documentation