nmapのスキャン方法
最近趣味でCTFの勉強したりしているが、よく使用するのがnmap。
nmapはポートスキャンツールとして知られているが、実際にどういう原理で動作しているのかは知らなかったので、今回勉強したことをまとめる。
nmapでよく使用されるスキャン方法は以下のようなものがある。カッコ内はnmapでのオプション。
- TCP Connectスキャン(-sT)
- TCP SYNスキャン(-sS) ※ハーフスキャン、ハーフオープンスキャンとも呼ばれる
- UDP スキャン(-sU)
- TCP Nullスキャン(-sN)
- TCP FINスキャン(-sF)
- TCP クリスマススキャン(-sX)
なお、nmapのデフォルトスキャン方法はユーザの権限によって異なり、
特権ユーザの場合はTCP SYNスキャン、特権でない場合はTCP Connectスキャンとなる。
-sS (TCP SYN scan) SYN scan is the default and most popular scan option for good reasons.
-sT (TCP connect scan) TCP connect scan is the default TCP scan type when SYN scan is not an option. This is the case when a user does not have raw packet privileges.
TCP Connectスキャン
3ウェイハンドシェイクにより、コネクションを確立させることでポートが開いているかを確認するスキャン方法。
対象サーバからSYN/ACKが返ってくれば、そのポートは開いていると判断できる。
もしポートが開いていないならば、対象サーバからはRSTが返ってくる。
この仕様はRFC793で定義されている。
- If the connection does not exist (CLOSED) then a reset is sent in response to any incoming segment except another reset. In particular, SYNs addressed to a non-existent connection are rejected by this means.
1.もし接続が存在しないなら(CLOSED)、リセット以外どんな入ってくる セグメントに対しても、リセットが送られる。特に、非実在の接続へのSYNs がこの手段によって拒絶される。
実際にwiresharkで挙動を確認するのが分かりやすい。
まずはポートが開いていた場合。
$ sudo nmap -sT -p 80 10.10.149.87 -vv -Pn Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower. Starting Nmap 7.91 ( https://nmap.org ) at 2021-08-02 20:02 JST Initiating Parallel DNS resolution of 1 host. at 20:02 Completed Parallel DNS resolution of 1 host. at 20:02, 0.02s elapsed Initiating Connect Scan at 20:02 Scanning 10.10.149.87 [1 port] Discovered open port 80/tcp on 10.10.149.87 Completed Connect Scan at 20:02, 0.25s elapsed (1 total ports) Nmap scan report for 10.10.149.87 Host is up, received user-set (0.25s latency). Scanned at 2021-08-02 20:02:58 JST for 0s PORT STATE SERVICE REASON 80/tcp open http syn-ack Read data files from: /usr/bin/../share/nmap Nmap done: 1 IP address (1 host up) scanned in 0.33 seconds
今回80番ポートは開いているので、サーバからSYN/ACKが返却された。
最後のRST/ACKについては、接続を張ったままとしないようにクライアントから送られたものだと考えられる。
次に、ポートが開いていなかった場合。
$ sudo nmap -sT -p 80 localhost -vv -Pn Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower. Starting Nmap 7.91 ( https://nmap.org ) at 2021-08-02 20:21 JST Warning: Hostname localhost resolves to 2 IPs. Using 127.0.0.1. Initiating Connect Scan at 20:21 Scanning localhost (127.0.0.1) [1 port] Completed Connect Scan at 20:21, 0.00s elapsed (1 total ports) Nmap scan report for localhost (127.0.0.1) Host is up, received user-set (0.00012s latency). Other addresses for localhost (not scanned): ::1 Scanned at 2021-08-02 20:21:22 JST for 0s PORT STATE SERVICE REASON 80/tcp closed http conn-refused Read data files from: /usr/bin/../share/nmap Nmap done: 1 IP address (1 host up) scanned in 0.07 seconds
ローカルホストの80番ポートは開けていないため、RSTが返却されている。
ただし、一般的な構成ではファイアウォールを置いていることが多く、
その場合はパケットがドロップされる=対象サーバまで届かない=RSTが返却されない。
結果としてはSYNに対する応答が返ってこないため、nmapはフィルタリングされていると判断する。
$ sudo nmap -sT -p 85 10.10.149.87 -vv -Pn Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower. Starting Nmap 7.91 ( https://nmap.org ) at 2021-08-02 20:28 JST Initiating Parallel DNS resolution of 1 host. at 20:28 Completed Parallel DNS resolution of 1 host. at 20:28, 0.01s elapsed Initiating Connect Scan at 20:28 Scanning 10.10.149.87 [1 port] Completed Connect Scan at 20:28, 2.00s elapsed (1 total ports) Nmap scan report for 10.10.149.87 Host is up, received user-set. Scanned at 2021-08-02 20:28:18 JST for 2s PORT STATE SERVICE REASON 85/tcp filtered mit-ml-dev no-response Read data files from: /usr/bin/../share/nmap Nmap done: 1 IP address (1 host up) scanned in 2.07 seconds
TCP SYNスキャン
TCP SYNスキャンはTCP Connectスキャンと似ているが、コネクションを成立させないという特徴がある。
以下の図のように、サーバからSYN/ACKが返却された後にRSTでコネクションを切断するのだ。
確かに、nmapからはSYN/ACKが返却された時点でポートが開いていることは判明しているので、
余計なやり取りをしなくて済む。
(我々が行いたいのはポートスキャンであって、コネクションの成立ではないのだ)
また、この方法では接続が成立していないため、サーバにログが残らないメリット(?)がある。
ただし、間のファイアウォールにはログが記録される可能性がある。
$ sudo nmap -sS -p 80 10.10.149.87 -vv -Pn Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower. Starting Nmap 7.91 ( https://nmap.org ) at 2021-08-02 20:35 JST Initiating Parallel DNS resolution of 1 host. at 20:35 Completed Parallel DNS resolution of 1 host. at 20:35, 0.03s elapsed Initiating SYN Stealth Scan at 20:35 Scanning 10.10.149.87 [1 port] Discovered open port 80/tcp on 10.10.149.87 Completed SYN Stealth Scan at 20:35, 0.29s elapsed (1 total ports) Nmap scan report for 10.10.149.87 Host is up, received user-set (0.25s latency). Scanned at 2021-08-02 20:35:34 JST for 0s PORT STATE SERVICE REASON 80/tcp open http syn-ack ttl 127 Read data files from: /usr/bin/../share/nmap Nmap done: 1 IP address (1 host up) scanned in 0.41 seconds Raw packets sent: 1 (44B) | Rcvd: 1 (44B)
ポートが開いていなかった場合の挙動は、TCP connectスキャンと同様に、サーバからRSTが返却される。
UDP スキャン
UDPはTCPと異なり相手の応答を待たないため、ポートスキャンにおいては厄介である。
基本的には接続要求に対して応答を行わないため、nmapからはopen|filteredと判断される。(開いているのかドロップされているのか判断できないため)
$ sudo nmap -sU -p 80 10.10.149.87 -vv -Pn Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower. Starting Nmap 7.91 ( https://nmap.org ) at 2021-08-02 20:49 JST Initiating Parallel DNS resolution of 1 host. at 20:49 Completed Parallel DNS resolution of 1 host. at 20:49, 0.02s elapsed Initiating UDP Scan at 20:49 Scanning 10.10.149.87 [1 port] Completed UDP Scan at 20:49, 2.04s elapsed (1 total ports) Nmap scan report for 10.10.149.87 Host is up, received user-set. Scanned at 2021-08-02 20:49:08 JST for 2s PORT STATE SERVICE REASON 80/udp open|filtered http no-response Read data files from: /usr/bin/../share/nmap Nmap done: 1 IP address (1 host up) scanned in 2.15 seconds Raw packets sent: 2 (84B) | Rcvd: 0 (0B)
ただし、ポートが閉じている場合にはICMPパケット(Destination unreachable(Port unreachable))が返却されるため、
閉じているポートについては判断できる。
$ sudo nmap -sU -p 80 localhost -vv -Pn Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower. Starting Nmap 7.91 ( https://nmap.org ) at 2021-08-02 20:40 JST Warning: Hostname localhost resolves to 2 IPs. Using 127.0.0.1. Initiating UDP Scan at 20:40 Scanning localhost (127.0.0.1) [1 port] Completed UDP Scan at 20:40, 0.03s elapsed (1 total ports) Nmap scan report for localhost (127.0.0.1) Host is up, received user-set (0.000052s latency). Other addresses for localhost (not scanned): ::1 Scanned at 2021-08-02 20:40:16 JST for 0s PORT STATE SERVICE REASON 80/udp closed http port-unreach ttl 64 Read data files from: /usr/bin/../share/nmap Nmap done: 1 IP address (1 host up) scanned in 0.14 seconds Raw packets sent: 1 (42B) | Rcvd: 2 (112B)
TCP Nullスキャン
TCP Nullスキャンは、何のフラグも立てていないパケットを送信する方法。
コネクションの成立はできないため、UDPスキャンと同じく開いているポートの判断ができない。
しかし、閉じているポートからはRSTが返却されるため、閉じているポートが何かを調査する場合に使用する。
$ sudo nmap -sN -p 80 10.10.149.87 -vv -Pn Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower. Starting Nmap 7.91 ( https://nmap.org ) at 2021-08-02 20:50 JST Initiating Parallel DNS resolution of 1 host. at 20:50 Completed Parallel DNS resolution of 1 host. at 20:50, 0.01s elapsed Initiating NULL Scan at 20:50 Scanning 10.10.149.87 [1 port] Completed NULL Scan at 20:50, 2.04s elapsed (1 total ports) Nmap scan report for 10.10.149.87 Host is up, received user-set. Scanned at 2021-08-02 20:50:51 JST for 2s PORT STATE SERVICE REASON 80/tcp open|filtered http no-response Read data files from: /usr/bin/../share/nmap Nmap done: 1 IP address (1 host up) scanned in 2.14 seconds Raw packets sent: 2 (80B) | Rcvd: 0 (0B)
wiresharkで確認すると、このように何のフラグも立っていないことが分かる。
TCP FINスキャン
TCP FINスキャンは、FINフラグのみを立てたパケットを送信する方法。
こちらもNullスキャンと同じく、コネクションの成立ができないため、閉じているポートが何かを調査する場合に使用する。
TCP クリスマススキャン
なんか楽しそうな名前であるが、FIN、URG(緊急に処理すべきデータを含んでいる)、PUSH(データを即座に上位層に渡す)フラグを立てたパケットを送信する方法。
こちらもNullスキャン、FINスキャンと同様に閉じているポートの調査に使用する。
名前の由来は、フラグがクリスマスツリーのごとく点灯しているように見えることから。
TCP Nullスキャン、FINスキャン、クリスマススキャンについては、特定のファイアウォールによるフィルタリングを回避するために使用される。