Nmap (Network Mapper) は、ネットワーク上のホストとサービスを発見するためのオープンソースのスキャンツール。1997 年に Gordon Lyon (ハンドル Fyodor) が公開して以来、ペネトレーションテスト・脆弱性診断・ネットワーク管理の現場で事実上の標準となっている。指定した IP レンジに対してパケットを送信し、応答パターンから 「どのホストが生きているか」「どのポートが開いているか」「何のサービスがどのバージョンで動いているか」「OS は何か」 を推測する。
Nmap でできること — 4 つの中核機能 #
Nmap の機能は次の 4 つに整理できる。
- ホスト発見 (Host Discovery) — ICMP / ARP / TCP のパケットを組み合わせ、指定レンジ内で生きているホストを列挙する。
-snでポートスキャンを行わずホスト発見だけを実行できる - ポートスキャン (Port Scanning) — TCP / UDP の各ポートに探索パケットを送り、応答パターンから open / closed / filtered を判定する
- サービス・バージョン検出 (
-sV) — 開いているポートに対し、内蔵のnmap-service-probesデータベースからプローブを送り、レスポンス文字列を照合してサービス名とバージョンを推定する - OS 推測 (
-O) — TCP/IP スタックの実装差 (TCP オプションの並び、TTL の既定値、Window Size、IP ID の挙動など) を指紋としてnmap-os-dbから最も近い OS を確率付きで推定する
これらに加えて NSE (Nmap Scripting Engine) を使うと、Lua スクリプトによって脆弱性検査・ブルートフォース・追加情報収集など独自のタスクを実行できる。--script vuln のようにカテゴリ指定で複数スクリプトを一括実行できる。
法的・倫理的な注意 #
Nmap は強力なツールであるがゆえに、使い方を誤ると刑事責任を問われる可能性がある。日本の不正アクセス禁止法や各国の同種の法律では、ポートスキャンそのものを直接禁じているわけではないが、許可を得ていないネットワークに対するスキャンは「攻撃の準備行為」として違法と解釈され得る。罰金・懲役・前科のリスクがある。
- 自分が所有・管理しているネットワーク — 自宅 LAN、自分が契約している VPS、隔離した学習用ラボ環境
- 書面で明示的に許可を得た対象 — ペネトレーションテスト契約、脆弱性診断契約、レッドチーム演習など。スコープと期間が文書で定義されていること
- 正規の学習プラットフォーム — Hack The Box、TryHackMe、VulnHub、OverTheWire など、運営側がスキャンを許可している学習環境
「軽い気持ちでちょっと試してみる」のが人生で一番高くつくミスになりうる。著名な逮捕事例や訴訟は国内外で複数あり、好奇心であっても他人のネットワークに対する無断スキャンは行ってはならない。
歴史 — Phrack 創刊号から NSE まで #
ホスト発見 (Host Discovery) #
Nmap は指定されたターゲット (IP / CIDR / ホスト名) に対し、ポートスキャンの前にまず「そのホストは生きているか」を判定する。デフォルトでは ICMP Echo / TCP SYN to 443 / TCP ACK to 80 / ICMP Timestamp の組み合わせを送る。
| オプション | 振る舞い |
|---|---|
-sn |
ポートスキャンを行わず、ホスト発見のみ (旧 -sP、Ping Scan) |
-Pn |
ホスト発見をスキップし、全ターゲットを「生きている」とみなしてポートスキャン (ICMP ブロック環境向け) |
-PS<port> / -PA<port> |
指定ポートに TCP SYN / ACK を送って応答確認 (FW 越しでも応答することがある) |
-PE / -PP / -PM |
ICMP Echo / Timestamp / Address Mask を送る |
-PR |
ARP を明示 (ローカル LAN 内では Nmap が自動的に ARP を使う) |
ローカル LAN 内では Nmap は自動的に ARP を使う。ICMP よりも高速・確実で、ICMP がフィルタされていても動く。-PR で明示することも可能。
ポートスキャンの方式 #
Nmap には複数のスキャン手法があり、TCP フラグの組合せやプロトコル選択が異なる。ステルス性・必要権限・速度・調査目的の違いによって使い分ける。
TCP SYN スキャン (-sS) — 既定 #
ハーフオープンスキャン とも呼ばれる、Nmap の既定 (root 権限がある場合)。SYN パケットを送信し、SYN/ACK が返れば open、RST なら closed、無応答 (もしくは ICMP Unreachable) なら filtered と判定。3-way handshake を完成させない ためサーバ側のアプリケーションログには接続として記録されにくく、比較的目立たない。
実装上は raw socket を使うため Linux / macOS では root 権限が必要、Windows では Npcap 経由となる。
TCP Connect スキャン (-sT) #
OS の connect() システムコールを使い、3-way handshake を最後まで完成させてから RST で切断するスキャン。root 権限不要 のため一般ユーザでも実行できる。
トレードオフとして、(1) サーバ側のアプリケーションログに接続記録が残りやすい、(2) handshake 分のオーバーヘッドがあり遅い、という欠点がある。SYN スキャンが使えない環境のフォールバック。
UDP スキャン (-sU) #
UDP ポートにプロトコル固有のペイロード (DNS / SNMP / NTP など) を送り、応答パターンから状態を判定する。UDP はコネクションレスのため判定が難しい — プロトコル応答が返ってくれば open、ICMP Port Unreachable が返れば closed、無応答は open|filtered。非常に遅い ので、必要なときだけスコープを絞って使う。
DNS (53/udp)、SNMP (161/udp)、NTP (123/udp)、TFTP (69/udp) など、UDP でのみ提供されているサービスを発見したいときに必須。
ACK スキャン (-sA) #
SYN ではなく ACK パケットを送るスキャン。ステートフルファイアウォールが ACK パケットを「既存セッションの一部」と誤認して通過させることを利用する。応答 (RST) が返れば unfiltered、無応答もしくは ICMP unreachable は filtered と判定。open か closed かは判定しない — ファイアウォールのルールセット推測に使う特殊スキャン。
NULL / FIN / Xmas スキャン (-sN / -sF / -sX) #
それぞれフラグなし / FIN のみ / FIN+PSH+URG をセットしたパケットを送る。RFC 793 では、open ポートはこれらの「無効な組み合わせ」のパケットを無視し、closed ポートは RST を返すと定められている。無応答→ open|filtered、RST → closed、ICMP Unreachable → filtered。
これらの一部実装は RFC に従わないので NULL / FIN / Xmas スキャンの結果は信頼できない。Linux / Solaris / UNIX 系には有効。古いステートレスファイアウォールをすり抜けるテクニックとして使われた。
Idle / Zombie スキャン (-sI) #
第三者ホスト (zombie) の IP ID 変化を観測してターゲットのポート状態を推測する高度なスキャン。自分の IP アドレスを直接ターゲットに送らない ため、IDS / FW のログに自分の IP が一切残らない。
要件 — IP ID をグローバルに連番でインクリメントする古い実装の zombie ホストが必要。現代の OS はこの実装を採用していないため適切な zombie を見つけるのが難しいが、CTF / 学習用途で覚えておく価値はある。
- 既定は
-sS— root 権限があり、速度・ステルス性・互換性のバランスが最も良い - root が無いときだけ
-sT— ログに残るが手段がない時の代替 - UDP は必要なときに
-sUを追加 —-sS -sUで TCP/UDP 同時可 - 目的特化のときに
-sA / -sN / -sF / -sX / -sI— FW 挙動の調査、IDS 検証、痕跡を残さない高度な調査
ポート状態の 6 判定 #
Nmap は応答パターンから 6 つの状態を判定する。
| 状態 | 意味 | 典型的な応答 |
|---|---|---|
| open | サービスがアクティブにリッスン | SYN/ACK が返る |
| closed | ポートに到達できるがサービスは無い | RST が返る |
| filtered | パケットがフィルタされ判定できない | 無応答 / ICMP Unreachable |
| unfiltered | 到達はできるが open/closed 不明 | RST が返る (ACK スキャンの結果) |
| open|filtered | open と filtered のどちらかと判定できない | 無応答 (UDP / NULL / FIN / Xmas) |
| closed|filtered | closed と filtered のどちらかと判定できない | Idle スキャン特有 |
「そのホスト自体が存在しないわけではなく、ファイアウォールやルータでパケットが落とされている」状態。攻撃者から見ると filtered は閉じているのと同じ意味で進めなくなり、防御側にとっては最も望ましい状態。
サービス・バージョン検出 (`-sV`) と OS 推測 (`-O`) #
サービス・バージョン検出 #
ポートが open と判定された後、-sV を付けると Nmap は実際にそのポートが「何のサービスのどのバージョンか」を推定する。
nmap-service-probes からそのポート番号に対する優先プローブを順に送信。product / version / extrainfo / ostype / hostname を抽出。--version-intensity 0..9 で網羅度を変えられる (デフォルトは 7)。-A を付けると -sV -O --traceroute --script=default が一括で有効になる。
OS 推測 (-O) #
-O を付けると Nmap はターゲットの TCP/IP スタックの挙動を多面的にテストして OS を推定する。
- TCP ISN (Initial Sequence Number) の生成パターン (乱数性、周期性)
- TCP オプションの順序と値 (MSS / SACK / Timestamp / Window Scale / NOP の並びは OS ごとに異なる)
- TCP Window Size の初期値
- IP ID の生成方式 (連番 / 乱数 / ゼロ固定)
- ICMP メッセージの構造
- TCP/IP のエッジケース挙動 (異常パケットへの応答)
これらを 16 種類の探索パケットで採取し、nmap-os-db と照合する。出力には「Linux 5.x (confidence 92%)」のように一致度が表示される。
NSE (Nmap Scripting Engine) #
NSE は Lua インタプリタを Nmap に組み込み、ユーザがスクリプトで機能を拡張できる仕組み。--script で指定する。
| カテゴリ | 内容 |
|---|---|
default (= -sC) |
安全で情報量の多い既定スクリプト群 |
discovery |
ホスト・サービスの追加情報収集 |
version |
-sV の補助 |
vuln |
既知の脆弱性チェック (CVE 対応スクリプト多数) |
exploit |
実際にエクスプロイトを試みる (注意) |
auth |
認証関連 (匿名 FTP、デフォルトクレデンシャル等) |
brute |
ブルートフォース |
intrusive |
ターゲットに影響が出る可能性がある |
safe |
影響なしと明示されたスクリプト |
malware |
マルウェア感染チェック |
dos |
DoS テスト |
代表的なスクリプト例:
--script vuln— 既知 CVE の総当たりチェック--script http-enum— HTTP サーバ上のディレクトリ列挙--script smb-os-discovery— SMB 経由で OS 情報取得--script ssl-enum-ciphers— SSL/TLS の暗号スイート列挙--script ssh-hostkey— SSH ホスト鍵取得
NSE スクリプトは /usr/share/nmap/scripts/ (Linux) に格納され、ユーザが自作することもできる。
検出回避と防御側の見え方 #
Nmap には IDS / IPS / FW に見つからないための回避オプションが多数ある。いずれも合法な調査範囲内で使うこと。
| オプション | 効果 |
|---|---|
-T0 〜 -T5 |
タイミングテンプレート。-T0 (paranoid) は超低速で IDS の閾値に引っかかりにくい。-T4 (aggressive) が実務の既定 |
-D <decoy1>,<decoy2>,ME |
おとり IP を混在させて自分の IP を埋もれさせる |
-f / --mtu |
パケットを小さくフラグメント化してシグネチャ検査をかいくぐる |
--data-length |
パディングを追加してパケットサイズを変える |
--source-port <port> |
送信元ポートを指定 (DNS の 53 や FTP の 20 など、FW で例外的に許可されているポート) |
--randomize-hosts |
複数ターゲットへのスキャン順序をシャッフル |
- 短時間に多数のポートへの接続試行 (1 IP から数百〜数千)
- TCP SYN だけ送って ACK を返さない (
-sS) → アプリログには残らないが、ステートフル FW や IDS の SYN フラッディング判定に引っかかる - 異常な TCP フラグの組み合わせ (
-sN / -sF / -sX) - 短時間の ICMP / ARP の大量送信 (ホスト発見)
Snort / Suricata / Zeek などの IDS には Nmap シグネチャが標準で組み込まれている。
実践例 — 学習環境で使うコマンド #
HTB / TryHackMe など、許可された学習環境でよく使うコマンド例。
$ sudo nmap -sS -sV -O -A -T4 -p- <target>
# -sS SYN スキャン (既定だが明示)
# -sV サービス・バージョン検出
# -O OS 推測
# -A -sV -O --traceroute --script=default 一括
# -T4 速度優先
# -p- 全 65535 ポート# 素早い概要を取りたいとき
$ sudo nmap -sS --top-ports 1000 -T4 <target>
# 特定の脆弱性チェック
$ sudo nmap --script vuln -p 80,443 <target>
# UDP も含めて見たいとき
$ sudo nmap -sS -sU -p T:80,443,U:53,161 <target>
# 結果を XML で保存して別ツールに連携 (-oA は normal/XML/grepable 3 形式同時)
$ sudo nmap -sS -sV -oA scan_results <target>
# XML は Metasploit の db_import 等から読み込める単一のコマンドで終わらせず、目的に合わせてオプションを段階的に追加していくのが定石。最初は控えめに、必要に応じて詳細スキャンを重ねるのが「ターゲットを乱さず、効率よく情報を得る」鉄則となる。