Linux/nmap

nmap(2014-10-28)


調査対象のポートが開いているかどうかを調べるためのツールです。
使う為の前提として、TCP/UDP/ICMPの知識は必要です。
個人的にはクラッカーが攻撃対象のセキュリティホールを探す為の常とう手段な印象を持っています。

触ってみると、意外と便利というか、面白いツールですね。これ。

まずポートスキャンで分かる状態について。~

nmapを実行したら、通常は以下のいずれかの状態が判定結果として出力されます。

open接続できたり、応答が帰ってきたりした場合。このポートは開いているぞ、と
closed明確に接続「できない」と分かった場合。言い換えると、対象のアドレスまで届いたことも示唆する
(途中でファイアウォールに邪魔されなかった。filteredとの違いに注目)
filtered何らかの理由でopenかcloseか判定できなかった。ファイアウォールで破棄されたかもしれないし、通信状態が悪いのかもしれない。
unfilteredTCPポートにはアクセスできたが、openかcloseか判断できない。少し複雑な事情なので割愛 [worried]

あとはopen|filteredとclosed|fiteredという組み合わせもある。(どっちなのか判断できないケース)

以下、オプションの例

スキャンタイプ(-s)

-sPデフォルトの設定。pingと、TCP80(HTTP)への接続を試みる。なので、この結果がUDPの可否と直結はしないので注意
-sSデフォルトの設定。Synスキャン。TCPのSynに対してAckが帰ってくるかを確認するがTCPコネクションは確立しないのでログに残りにくい。
応答がSYN/ACKなら対象ポートはOpen、RSTやICMP不到達ならばFilterされているとみなされる
-sTTCP接続を確立する。-sSと違うのは3Wayハンドシェイクを最後まで実行する点。
言い換えると-sSは管理者権限以外やIPv6では使えない。
途中までしか接続しない-sSよりも処理速度は遅くなる
-sUUDPを送信する。応答があればOpen、なければOpenかFilter、ICMP不到達ならClosedかFilterと判定する
TCPと違って接続の概念が無いから無応答待ちのケースが多く、-sSや-sTよりも大幅な検証時間がかかる
-sN
-sF
-sX
-sTの変化球。TCPのヘッダフラグを何も付けない/FINを付ける/FIN-PSH-URG*1全部付ける
使用例としてステートフルなファイアウォール(接続状態を監視してパケットを破棄する機器)の防御力を試す為に使ったりする

pingを軸にしたホスト検索

-P0(ゼロ)ホスト検索を省く。調査対象のIPアドレスが明確だったり、ICMPが無効と分かっているなら指定するべきオプション
-PSpingとTCP-SYNを試みる。ポートを指定することも可能。デフォルトだと-PS,80 (HTTPへ接続)
-PUpingとUDPを送る。ポートを指定することも可能。デフォルトだと-PU,31338という応答を期待していないポート番号
-PE
-PP
-PM
ICMPのバリエーションで、Echo、Timestamp、AddressMaskの要求を投げる。
デフォルトのEcho(ping)以外の制御の調査を行うときに有効
-PRARPによる同一LAN(Ehternet)上のホスト検索を行う。
ルータを越える必要が無いなら、pingよりもarpの方がスキャン処理は早い

スキャンの効率化

-T0 ~ -T5送信間隔やタイムアウト時間を調整して、スキャンの効率化を図る。
デフォルトは3(normal)、一番遅いのが0(paranoid)で、一番早いのが5(isan)。
ネットワーク環境の処理性能に合わせて調整する

対象のポート

-p 指定ポート[,指定ポート][...]
-p 開始ポート-終了ポート
-p T:TCPのポート,U:UDPのポート
デフォルトは-p 1-1024 に加えてnmap-services記載の全ポート

出力先

-oN ファイル名ノーマルな出力方式
-oX ファイル名XML形式。他のツールに食わせたりする場合はこっちが多い
--resume ファイル名中断したスキャンを再開することが可能。スキャンに数日かかる時などに有効

そのほかのオプションの例

-v冗長モード。リアルタイムに結果を観察したい場合
-sVサービス検出。開いているポートに加えてOpenSSHやらApacheやら使っているプロセス情報も分かる
-O対象のOSを推測する
-A色々やる。OSの推測と、より細かいサービスの推測(例えばtcp80が開いていて、Apache/nginxで、Titleタグが何かとか)、tracerouteの結果
-rスキャンする際はデフォルトだと対象ポートをランダム選択する。これを順番にやるように変える
-nDNSの逆引き機能をOFFして高速化を図る
-6IPv6のスキャン

実は今回、一番やりたかったのがこれ。
スキャン用のスクリプトを用意して複雑なスキャンを実行することができます。

--script ファイル名指定した nse スクリプトでスキャンする

パッケージからインストールした場合はデフォルトで
/usr/share/nmap/scripts
に~.nseというファイル群があると思いますが、これがlua*2で書かれたスキャン用のスクリプトです。


対象のホストの指定 コマンドラインの最後にIPアドレスを書けばいいが、リスト指定もできる。

-iL ファイル名リストファイルからの指名。パイプつなぎで標準入力からならば - (ハイフン)を使用
-iR 指定数ランダムに、指定した数だけ探す。0は無限に探す
--exclude 対象1[,対象2][...]指定対象以外の全てを探す
--excludefile ファイル名指定したリストファイル以外の全てを探す

以下、実行例。

# nmap -v -p 1-1024 localhost

Starting Nmap 5.51 ( http://nmap.org ) at 2014-10-28 19:45 JST
Initiating SYN Stealth Scan at 19:45
Scanning localhost (127.0.0.1) [1024 ports]
Discovered open port 22/tcp on 127.0.0.1
Discovered open port 80/tcp on 127.0.0.1
Completed SYN Stealth Scan at 19:45, 0.04s elapsed (1024 total ports)
Nmap scan report for localhost (127.0.0.1)
Host is up (0.0000050s latency).
Other addresses for localhost (not scanned): 127.0.0.1
Not shown: 1021 closed ports
PORT    STATE SERVICE
22/tcp  open  ssh
80/tcp  open  http

Read data files from: /usr/share/nmap
Nmap done: 1 IP address (1 host up) scanned in 0.10 seconds
           Raw packets sent: 1024 (45.056KB) | Rcvd: 2051 (86.148KB)

ちなみに、-pでポート指定した方が、想定外のポートでサービスが行われている場合も検出できる模様
(例えばhttpdをtcp/80ではなく、tcp/880で開いている場合とか)

あるいはこんなとか。

# nmap -sS -P0 -T4 -p 1024-65535 -oN output.txt -r -v -A localhost

理由もなく世界中のWebサイトを探してみた。案外見つからない(filteredが多かった)

# nmap -T5 -iR 10 -p 80 -sV

で、今回nmapを調べた目的はこれです。

# map -p 443 -d --script ssl-heartbleed localhost

HeartBleed の脆弱性チェックを行います。
nmapの6.47には ssl-heartbleed.nseが入っていました。なかなか便利です。


*1 ちなみに、FINは終了、PSHは強制転送、URGは緊急を示す。これをクリスマススキャンと言い、サービスが提供されていない場合はRSTが帰ってくる
*2 スクリプト言語。ポルトガル語で「月」を意味する洒落たやつ。計算系は特にpythonやrubyよりも早いんですって。*3
*3 余談ですが、nmapのビルドに凄い苦戦しまして。nse_openのreferenceエラーで、原因はyum installしたluaと、ソースからbuildしたluaが混在して参照エラーになっていました。古い方のluaをyum removeして解決 [worried]