Nmapでのポートスキャン

これは シーエー・アドバンス Advent Calendar2024 23日目の記事です。
昨日は@syk_nakayama さんの記事でした。
明日は@gussann0505 さんの記事です。

## はじめに
初めまして。
シーエー・アドバンス(CAAD)技術統括本部セキュリティチームの@AzmYshrです。
社内(グループ会社含む)サービスの脆弱性診断に関わる業務を行っています。
最近ポートスキャン業務に携わることとなり、Nmap を使用する機会がありましたので、自身の備忘録も兼ねて皆さんが使用する際の少しでも手助けとなればと思いこの記事を書かせていただきました。
* ポートとは[^1]
ポートとは、IP ネットワークの各ホスト上で、複数アプリケーションへ通信を振り分けるために用意された、論理的な情報の送受信口です。主に TCP・UDP で定義されています。 
* ポートスキャンとは[^2]
ポートスキャンとは、コンピュータネットワークにおいて、対象のコンピュータの複数のポートに対して接続要求を行い、要求に対する応答を確認することにより、利用可能なポートを探すことです。
* Nmap (「Network Mapper」)とは[^3]
ネットワーク調査およびセキュリティ監査を行うためのオープンソースのツールです
※更に詳しく知りたい方は「参考」に記載した **Nmap** のリンクをご参照ください。
:::note alert
ポートスキャンを自身の管理していないサービスに実施すると攻撃とみなされることもありますので、悪用は厳禁でお願いします。
:::

## 動作環境
* macOS Sonoma v14.5
* Nmap version 7.95

## 事前準備
1\. まずはじめに Nmap 環境を準備するため下記のコマンドで Nmap をインストールします。
```terminal
$ brew install nmap
```
※Windows を使用している場合は winget からのインストールがおすすめです。
```terminal
$ winget install --id=Insecure.Nmap  -e
```
※またはこちら Nmap の[公式サイト](https://nmap.org/download.html)からもダウンロードが可能です。自身の環境に合わせてダウンロードしてください。
![スクリーンショット 2024-12-10 午後7.05.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517080/825f9281-3d69-8493-6656-0ed6b24ef4ec.png)

2\. インストールが完了したら下記のコマンドで確認します。
```terminal
$ nmap -V
Nmap version 7.95 ( https://nmap.org )
Platform: arm-apple-darwin23.4.0
Compiled with: liblua-5.4.6 openssl-3.4.0 libssh2-1.11.0 libz-1.2.12 libpcre2-10.44 nmap-libpcap-1.10.4 nmap-libdnet-1.12 ipv6
Compiled without:
Available nsock engines: kqueue poll select
```
こちらのように Nmap のバージョン情報が返ってきたら無事インストール完了です。

## Nmap のコマンドとオプション

1\. インストールができたら下記のコマンドでポートスキャンを実施します。
```terminal:TCP
$ nmap -6 -n -p1-65535 -P0 -T4 -sV -sS IPアドレス --append-output -oN 出力ファイル名
```
```terminal:UDP
$ nmap -6 -n -p1-65535 -P0 -T4 -sV -sU --max-rtt-timeout 150ms --max-retries 2 IPアドレス --append-output -oN 出力ファイル名
```
### オプションの詳細
* -6 = IPv6での指定方法(IPv4の場合はこちらを指定しない)
* -n = ホストを検出した場合でもDNSの逆引きを行わない
* -p = ポート指定(-で繋いでレンジ指定も可)
* -P0 = 0番ポートから全スキャンかけたい場合のオプション
* -T4 = スキャンの間隔と速度(T4が推奨値)
* -sV = サービスとバージョンの特定
* -sS = スキャン方法の指定(TCP SYNスキャン/TCPハーフスキャン)
* -sU = スキャン方法の指定(UDP Scan)
* --max-rtt-timeout = プローブのタイムアウトを調節(コマンド例では150msでタイムアウト)
* --max-retries = 総スキャン時間の上限の設定で再送信の回数を制限できる
* --append-output = 出力ファイルは上書きせず追加する
* -oN = 出力方法の指定(通常出力(Output scan in normal))

コマンド例では IPv6 を対象としてポートスキャンを実施しています。
IPv4 を対象としたい場合はオプションの「-6」を省いて実行してください。
今回は通常よく使用する「-sS」、「-sU」のスキャン方法を指定しております。
(他のスキャン方法が知りたい場合は「参考」に記載した Nmap のリンクをご参照ください)
出力ファイルが不要な場合は「--append-output」、「-oN」は省いて大丈夫です。

## 実行結果と確認方法
### 出力例
```terminal
127.0.0.1   localhost    tcp 80  open    http    ResponseCode:401 Server:nginx Redirect_1_code:301 Redirect_1_URL:https://localhost/
```
### 出力詳細
```terminal
IPアドレス：127.0.0.1
ホスト名：localhost
プロトコル：tcp
ポート：80
ステータス：open
サービス：http
レスポンス詳細：ResponseCode:401 Server:nginx Redirect_1_code:301Redirect_1_URL:https://localhost/
```
1\. ポートスキャンの診断観点では、不要なポートが開放されていないかを主にチェックしていくため、出力結果を確認し、ステータスが **open** もしくは **open|filterd** の結果に注力して確認していきます。
2\. 実際の確認方法はステータスが open のポートがあった場合に、出力結果のホスト名にブラウザから直接アクセスをして確認します。
```terminal:例
http://localhost:80
```
TIPS
※IPv6 をブラウザで確認する際は[]でIPアドレスを囲む必要があります
```terminal:例
http://[IPアドレス]:ポート番号
```
※ポートが 80(http)・443(https) などの場合にはポートを省略しても大丈夫ですが、他ポートの場合は必要になるためあえて記載しております。
3\. 直アクセスをした結果、ポートが開放されている場合でも、何らかのアクセス制限がされていれば問題はない認識としております。
4\. これを繰り返し行い、対象のサービスで不要なポートが開放されていないか確認することがポートスキャンの役割です。
## 終わりに
ぜひ皆さんも自身のサービスにポートスキャンを実施してネットワーク環境のセキュリティ向上に繋げていただければと思います。
最後までお読みいただきありがとうございます。
この記事がこれからポートスキャンを学ぼうとする方の少しでも手助けになれば幸いです。
皆様素敵なクリスマスをお過ごしください。

### 参考
[^1]:[ポート](https://ja.wikipedia.org/wiki/%E3%83%9D%E3%83%BC%E3%83%88_(%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%82%BF%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF))
[^2]:[ポートスキャン](https://ja.wikipedia.org/wiki/%E3%83%9D%E3%83%BC%E3%83%88%E3%82%B9%E3%82%AD%E3%83%A3%E3%83%B3)
[^3]:[Nmap](https://nmap.org/man/ja/index.html)