ホストの発見

ネットワーク偵察ミッションの第一段階に行うべきことの1つは、一連の(非常に広範な場合もある)IP範囲を限定して、アクティブな状態であるか、関心のあるホストのリストを作成することである。各IPアドレスのポートを1つ1つスキャンするのは、時間はかかるもののなかなか進まない、通常は無駄な作業である。もちろん、あるホストに興味を引かれる要因は、スキャンの目的に大きく左右される。ネットワーク管理者なら、特定のサービスを実行しているホストにしか興味を示さないかもしれないし、セキュリティ監査人なら、IPアドレスを持つデバイス1つ1つに関心を引かれる場合もあるだろう。内部ネットワーク管理者なら、自分が管理するネットワーク上のホストの位置を確認するためにICMP pingを使えるだけで満足かもしれないし、外部のペネトレーションテストの実施担当者なら、ファイアウォールの制限をすり抜けようとして、多種多様な調査手法を使う場合もあるだろう。

このように、ホスト発見のニーズは多岐にわたるので、Nmapには、使用する技法をカスタマイズするための幅広い種類のオプションが備わっている。ホスト探索はpingスキャンと呼ばれることもあるが、一般的なpingツールによる単純なICMPエコー要求パケットよりもはるかに優れている。ユーザは、リストスキャン(-sL)を用いるか、pingを無効にして(-Pn)、このping段階を完全に省略するか、もしくはネットワークに対してマルチポートのTCP SYN/ACK、UDP、ICMPなどのプローブを任意に組み合わせて行うことができる。これらのプローブの目的は、IPアドレスが実際にアクティブな状態(ホストやネットワークデバイスによって使用中)であることを示す応答を誘い出すことである。多くのネットワークでは、いつでもアクティブなIPアドレスは全体のほんのわずかしかない。RFC1918で定められたプライベートアドレス空間(例:10.0.0.0/8)では特にそうなっている。このネットワークには、1600万個のIPアドレスがあるが、これが1000台足らずのマシンしかない企業で使われているのを見たことがある。ホスト発見を実行すると、こうした広大なIPアドレスの海の中から、まばらにIPアドレスを割り振られたマシンを探し出すことができる。

 ホスト発見のオプションが何も指定されない場合、Nmapはポート80宛てのTCP ACKパケットと、ICMPエコー要求クエリを各ターゲットマシンに送信する。この例外は、ローカル イーサネット ネットワーク上にあるターゲットに対して、ARPスキャンが用いられている場合である。高い権限のないUNIXシェルユーザでは、connect()システムコールを使って、ACKの代わりにSYNパケットが送られる。これらのデフォルトは、-PA -PE オプションに相当する。このホスト発見機能は、ローカルネットワークをスキャンする場合は十分だが、より包括的な一連の発見調査は、セキュリティ監査に任せた方がよい。

-P*オプション(pingの種類を選ぶ)を組み合わせることもできる。様々なTCPポート/フラグやICMPコードを用いた多種多様なプローブを送ることで、制限の厳しいファイアウォールをすり抜ける確率を上げることができる。さらに留意すべき点は、ローカル イーサネット ネットワーク上のターゲットに対しては、その他の-P*オプションを指定している場合でも、ARP探索(-PR)がデフォルトで行われることである。これはほとんどの場合、他よりも高速で効果的に実施できるからである。

ホスト発見を制御するオプションを以下に挙げる。

-sL (リストスキャン)

ホスト発見の縮小版で、単に指定されたネットワークの全ホストを一覧するだけであり、ターゲットホストには何もパケットを送らない。デフォルトでは、Nmapはホスト名を知るために、ホスト上でDNSの逆引き解決も行う。単なるホスト名とはいえ、意外なほど有用な情報をもたらしてくれることも多い。例えばfw.chi.playboy.comは、プレイボーイ社(Playboy Enterprises)のシカゴ(Chicago)支社のファイアウォールである。また最終的には、IPアドレスの総数についての報告もある。リストスキャンは、自分のターゲットに対して正しいIPアドレスが得られていることを確認するための有効な健全性検査になる。ターゲットのホストが見覚えのないドメイン名を示している場合は、間違って別の会社のネットワークをスキャンしてしまわないように、さらに詳しく調査するだけの価値はある。

リストスキャンの狙いは、単にターゲットホストのリストを出力するだけなので、ポートスキャン、OS検出、pingスキャンなどのより高度なレベルの機能を実現するためのオプションは、これと組み合わせることはできない。これらのハイレベルの機能を実行する際に、pingスキャンを無効にしたい場合は、-Pnオプションの項を参照のこと。

-sn (Ping スキャン)

このオプションを使うと、Nmapはpingスキャン(ホスト発見)のみを実行し、応答した利用可能なホストの一覧を出力する。それ以上の調査(ポートスキャンやOS検出など)は行わない。リストスキャンよりも一歩立ち入った調査になるが、同じ目的で使用される場合が多い。ターゲットネットワークの予備調査を、あまり注意を引かずに軽く実行できる。攻撃者にとっては、IPおよびホスト名を1つ1つリストスキャンして得られるリストよりも、アクティブなホストがいくつあるかを知ることのほうが価値がある。

またこのオプションは、システム管理者の役に立つ場合も多く、ネットワーク上の利用可能なマシンの数を数えたり、サーバの可用性を監視したりするために容易に利用できる。pingスウィープと呼ばれることも多く、ブロードキャストのクエリには応答しないホストが多いために、ブロードキャストアドレスにpingを打つよりも信頼性が高い。

-snオプションはデフォルトで、ICMPエコー要求と80番ポート宛てのTCPパケットを送信する。高い権限がないユーザが実行する場合は、SYNパケットが(connect()コールを使って)ターゲットの80番ポートに送られる。高い権限を持つユーザが、ローカル イーサネット ネットワーク上のターゲットのスキャンを試みる場合は、--send-ipが指定されていない限り、ARP要求(-PR)が用いられる。-snオプションを、発見プローブタイプ(-Pnを除く-P*タイプ)のオプションと組み合わせると、さらに柔軟に対応できる。このプローブタイプのどれかとポート番号のオプションを使うと、デフォルトのプローブ(ACKやエコー要求)よりも優先される。Nmapを実行している発信元ホストとターゲットネットワークの間に、制限の厳しいファイアウォールが設置してある場合は、これらの高度なテクニックを用いるべきである。さもないと、ファイアウォールでプローブパケットやホストの応答パケットが破棄された場合に、ホストを検出し損ねる可能性がある。

-Pn (ping なし)

このオプションを指定すると、Nmapが実行するホスト発見の段階が完全に省略される。Nmapは通常この検出段階で、さらに立ち入ったスキャンを行うためのアクティブなマシンを割り出す。Nmapはデフォルトでは、ポートスキャン、バージョン検出、OS検出などの立ち入ったプローブは、作動していることが判明したホストに対してしか実行しないようになっている。-Pnを使ってホスト発見を無効にすると、Nmapはターゲットに指定されたIPアドレスすべてに対して、要求されたスキャン機能を実行しようとする。つまり、クラスBのサイズのアドレス空間(/16)を、コマンドラインでターゲットに指定した場合、65,536個のIPアドレスすべてがスキャンされる。-Pnの2番目の文字は数字のゼロであり、英字のオーではない。リストスキャンの場合と同様に、本来行うべきホスト発見の段階は省略されるが、Nmapはそこで停止してターゲットのリストを出力するのではなくて、各ターゲットIPがアクティブであるかのように、要求された機能を実行し続ける。

-PS <portlist> (TCP SYN Ping)

このオプションによって、SYNフラグ付きの空のTCPパケットが送信される。デフォルトの送信先ポートは80番(この設定は、nmap.hのDEFAULT_TCP_PROBE_PORTを書き換えてコンパイルすると変更できる)だが、代わりのポートをパラメタとして指定できる。また、コンマ区切りのポート番号リスト(例:-PS22,23,25,80,113,1050,35000)を指定することも可能である。この場合、各ポートに対するプローブは同時並行で試みられる。

SYNフラグによって、こちら側がコネクションの確立を試みていることをリモートのシステムに知らせる。通常は送信先ポートが閉じており、RST(リセット)パケットが送り返される。このポートがたまたま開いていた場合は、ターゲットはSYN/ACK TCPパケットで応答し、TCPの3ウェイハンドシェイクの第二段階に進む。続いて、Nmapを実行しているマシンが、ACKパケットを送って3ウェイハンドシェイクを完了すれば、完全なコネクションが確立されるが、その代わりにRSTで応答することで、生成途中のコネクションを切断する。このRSTパケットは、Nmap自身ではなくて、Nmapを実行しているマシンのカーネルが、予期せぬSYN/ACKに応答して送るものである。

Nmapでは、対象のポートが開いているか閉じているかは問題にしない。対象のホストがアクセス可能で、反応があることをNmapに告げるのは、上で述べたRSTかSYN/ACKの応答である。

UNIXマシンでは通常、生のTCPパケットを送受信できるのはroot権限を持つユーザに限られる。こうした権限のないユーザの場合は、次善策が自動的に採用され、各ターゲットポートに対してconnect()システムコールが起動される。これにより、SYNパケットをターゲットホストに送信し、コネクションの確立を試みる。connect()の戻り値としてすみやかに成功か失敗(ECONNREFUSED)が得られた場合、下位のTCPスタックではSYN/ACKかRSTパケットを受信したことになり、ターゲットホストはアクセス可能と見なされる。このコネクションの試みが未確立のままでタイムアウトに達した場合は、ホストはダウンしていると見なされる。Nmapは生のIPv6パケットの生成にはまだ対応していないので、この次善策はIPv6による接続にも用いられる。

-PA <portlist> (TCP ACK Ping)

TCP ACK pingは、すぐ上で述べたSYN pingのケースに酷似している。異なる点は、想像される通り、SYNフラグの代わりにTCP ACKフラグが付けられることである。こうしたACKパケットは、確立されたTCPコネクション上のデータを承認していると称しているが、そのようなコネクションは存在しないのである。そのため、リモートホストは常にRSTパケットで応答しなければならなくなり、この過程で自らの存在を明らかにすることになる。

-PAオプションは、SYNプローブと同じデフォルトポート(80)を使用し、同じ形式の目的ポートリストを得ることができる。権限のないユーザがこれを試みる場合や、IPv6ターゲットが指定された場合は、上で述べたconnect()の次善策が用いられる。ただし実際には、connect()はACKではなくてSYNパケットを送るので、この次善策は完全とは言えない。

SYNおよびACKの両方の pingが使えるようになっている理由は、ファイアウォールをすり抜ける可能性を最大限高くするためである。多くの管理者は、内向きのSYNパケットに関しては、企業のWebサイトやメールサーバなどの共用サービス宛てのもの以外はすべてブロックするように、ルータや簡易ファイアウォールを設定している。これにより、組織へのその他の内向きコネクションは阻止されるものの、ユーザが利用するインターネットへの外向きコネクションは、何にも妨げられずに許可されている。このようなステートフル(処理状態を把握して動的に対処する)でないアプローチは、ファイアウォール/ルータ上でリソースをほとんど消費せず、ハードウェアおよびソフトウェアフィルタで広くサポートされている。Linux用ファイアウォールソフトウェア「Netfilter/iptables」には、こうしたステートレスなアプローチを実装するための「--syn」という便利なオプションが用意されている。このようなステートレスなファイアウォールルールが設定されている場合、SYN pingプローブ(-PS)を閉じたターゲットポートに送ってもブロックされる可能性が高い。そうした場合は、ACKプローブが効力を発揮し、このルールを突破する。

またよく使われるファイアウォールで、別の種類のものには、想定外のパケットは破棄するというステートフルルールが採用されている。当初こうした機能はハイエンドのファイアウォールでしか見られなかったが、ここ数年の間に一般に広く普及してきている。LinuxのNetfilter/iptablesシステムは、--stateオプションでこの機能をサポートしており、コネクションの状態に応じてパケットを分類する。このようなシステムでは、想定外のACKパケットは通常、偽物と認識されて破棄されるので、SYNプローブのほうが有効である可能性が高い。この難題に対する解決策の1つは、-PS および -PAを指定して、SYN および ACKの両方のプローブを送ることである。

-PU <portlist> (UDP Ping)

これもホスト発見用オプションで、空の(--data-lengthが指定されている場合を除き)UDPパケットを特定のポートに送信する。ポートリストは、上で述べた-PS-PAのオプションの場合と同じ形式にする。特にポートが指定されていない場合、デフォルトでは31338番になる。このデフォルト値を設定するには、nmap.hのDEFAULT_UDP_PROBE_PORTを書き換えてコンパイルする。ほとんど使われることがないポートがデフォルトで使用されている理由は、開放ポートへの送信が、このスキャンタイプでは特に望ましくない場合が多いからである。

UDPプローブがターゲットマシンで閉じたポートに行き着いた場合は、ICMPポート到達不能パケットが返送されるはずである。Nmapはこれにより、ターゲットマシンが稼動中でアクセス可能であることを知ることになる。ICMPにはこの他にも、ホスト/ネットワーク到達不能やTTL超過などの、ホストがダウンしているか到達不能であることを示す多様なエラーメッセージがある。応答がないのも、これと同様に解釈される。空のパケットが開放ポートに到達した場合、ほとんどのサービスはこれを無視して、何の応答も返さない。デフォルトのプローブポートが、ほぼ使用中ではない31338番になっているのは、このためである。「chargen」などのサービスには、空のUDPパケットに応答するものがいくつかあり、マシンが利用可能であることをNmapに知らせることになる。

この種類のスキャンの主なメリットは、TCPしかふるいに掛けないファイアウォールやフィルタをすり抜けることである。例えば、筆者が以前持っていたLinksys社の無線ブロードバンドルータ、BEFW11S4の外部インターフェースは、デフォルトですべてのTCPポートにフィルタ処理するようになっていたが、UDPプローブを使うと、ポート到達不能メッセージを引き出し、デバイスの正体を明らかにすることができた。

-PE; -PP; -PM (ICMP Ping タイプ)

Nmapは、上で述べたようなTCP や UDPによるホスト発見の特異なタイプに加えて、どこにでもあるpingプログラムによって送信される標準的なパケットを送ることもできる。Nmapは、ICMPタイプ8(エコー要求)パケットをターゲットのIPアドレスに送信し、利用可能なホストからタイプ0(エコー応答)が返されるのを待ち受ける。ネットワーク調査を行う者にとっては残念なことに、最近のホストやファイアウォールは、RFC1122の要件通り応答を返すよりは、これらのパケットをブロックするものが多い。そのため、インターネット上の未知のターゲットに対しては、ICMPスキャンだけでは十分な信頼性が得られない。だが、内部ネットワークを監視しているシステム管理者にとっては、実用的で効率的なアプローチになる場合もある。このエコー要求動作を有効にするには、-PEオプションを使用すること。

エコー要求は標準的なICMP pingクエリであるが、Nmapはそれだけにとどまらない。ICMP規格(RFC792)には、タイムスタンプ要求、情報要求、アドレスマスク要求などのパケットが、それぞれコード13、15、17として指定されている。これらのクエリの表向きの目的は、アドレスマスクや現在の時刻などの情報を知ることだが、ホスト発見にも容易に利用できる。応答を返すシステムはすなわち、稼動中で利用可能なのである。情報要求パケットは、それほど広くサポートされているわけではないので、今のところNmapには実装されていない。RFC 1122ではホストにはこの種のメッセージを実装するべきではありませんと提唱されている。タイムスタンプとアドレスマスクに関するクエリは、それぞれ-PP-PMのオプションを付けることで送信できる。タイムスタンプ応答(ICMP コード14)やアドレスマスク応答(コード18)によって、ホストが利用可能であることが明らかになる。これら2つのクエリは、管理者がエコー要求パケットを限定してブロックしているが、他のICMPクエリが同じ目的で用いられる可能性があることを見落としている場合に有効である。

-PR (ARP Ping)

Nmapの最も一般的な使用法の1つは、イーサネットLANのスキャンである。たいていのLAN、特にRFC1918提唱のプライベートアドレス範囲が用いられているLANでは、IPアドレスの大部分は常に未使用のままになっている。NmapがICMPエコー要求のような生のIPパケットを送信する場合、OSはイーサネットフレームのアドレスを正しく指定できるように、ターゲットIPに対応する送信先ハードウェア(ARP)のアドレスを決める必要がある。だがこの処理は遅く、不確実である場合が多い。なぜなら、OSは、利用できないホストに対して何百万という数のARP要求を短時間で行わなければならないことを想定して作られているわけではないからである。

NmapのARPスキャンでは、ARP要求の処理を行うのに、そのために最適化したアルゴリズムを用いている。応答が返された場合、Nmapはすでにそのホストが稼動中であることがわかるので、IPベースのpingパケット処理の心配はしなくてよくなる。これにより、ARPスキャンはIPベースのスキャンよりもずっと高速で信頼性の高い処理を行うことができる。そのため、Nmapがローカル イーサネット ネットワーク上で検出したイーサネット ホストをスキャンする場合は、デフォルトでARPスキャンが行われるようになっている。別のpingタイプ(-PE-PSなど)が指定されている場合でも、同一のLAN上にあるターゲットに対しては、Nmapはそれらの代わりにARPを用いる。あくまでもARPスキャンを行いたくない場合は、--send-ipを指定すること。

-n (DNS解決を行わない)

Nmapが発見したアクティブなIPアドレスに対して逆引きのDNS解決を行わないように指定する。DNSは処理が遅いことが多いので、これによって進行を速めることができる。

-R (全ターゲットにDNS解決を行う)

ターゲットのIPアドレスに対して常に逆引きDNS解決を常に行うように指定する。この指定は通常、対象のマシンが稼動していることが判明している場合にのみ行われる。

--system-dns (システムのDNSリゾルバを使う)

Nmapはデフォルトでは、ホスト上に構成されたネームサーバに直接クエリを送り、応答を待ち受けることで、IPアドレスを解決する。パフォーマンスを上げるために、数多くの要求(数十件に及ぶことも多い)が並行処理される。代わりに自分のシステムのリゾルバを使いたい(getnameinfo()コールを介して1回に1個のIPを処理する)場合は、このオプションを指定すること。だがこれは低速でほとんど使い物にならない。ただし、NmapのDNSコードにバグがある場合はこの限りではない--その場合は連絡していただきたい。IPv6スキャンでは常に、システムのリゾルバが使われる。