Nmapの概要 (ESP)
Reading time: 28 minutes
tip
AWSハッキングを学び、実践する:
HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:
HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。
nmap -sV -sC -O -n -oA nmapscan 192.168.0.1/24
パラメータ
スキャンする IP
<ip>,<net/mask>: IP を直接指定します-iL <ips_file>: IP リストファイル-iR <number>: ランダムな IP の数。--exclude <Ips>や--excludefile <file>で除外できます。
機器の検出
デフォルトでは Nmap は次からなる検出フェーズを実行します: -PA80 -PS443 -PE -PP
-sL: 非侵入型で、名前解決のために DNS リクエストを行いターゲットを一覧化します。例えば www.prueba.es/24 の全 IP が対象かどうかを知るのに便利です。-Pn: No ping。すべてがアクティブであると分かっている場合に有用です(そうでないと時間を大きく浪費する可能性があり、また非アクティブと誤検出する偽陰性を生むこともあります)。検出フェーズを無効にします。-sn: No port scan。偵察(reconnaissance)フェーズ完了後にポートスキャンを行いません。比較的ステルスで、小規模なネットワーク探索に向きます。権限がある場合は ACK (-PA) を 80 に、SYN(-PS) を 443 に送り、echo と Timestamp リクエストを送ります。権限がない場合は常に接続を完了します。ターゲットがネットワークの場合は ARP(-PR) のみを使用します。他のオプションと併用した場合は、他オプションのパケットだけが送られます。-PR: Ping ARP。自ネットワーク内のホスト解析時にデフォルトで使用され、ping より速いです。ARP パケットを送信したくない場合は--send-ipを使用します。-PS <ports>: SYN パケットを送信し、相手が SYN/ACK で応答したら open(接続を終了させるために RST で応答することが多い)、RST で応答したら closed、応答がなければ unreachable と判断します。権限がない場合はフルコネクションが自動的に使われます。ポート指定がなければデフォルトで 80 に送ります。-PA <ports>: 前述と同様ですが ACK を使います。両方を組み合わせると精度が上がります。-PU <ports>: 逆の目的で、通常閉じていることが期待されるポートへ送ります。一部のファイアウォールは TCP 接続のみをチェックします。closed の場合は port unreachable、別の ICMP で応答されたり無応答であれば destination unreachable とされます。-PE, -PP, -PM: ICMP PING(echo replay, timestamp, addresmask)。ターゲットが生きているかを確認するために送られます。-PY<ports>: デフォルトで 80 に SCTP INIT プローブを送信します。INIT-ACK(open)や ABORT(closed)、無応答や ICMP unreachable(inactive)で応答される可能性があります。-PO <protocols>: ヘッダにプロトコルを指定します。デフォルトは 1(ICMP), 2(IGMP), 4(Encap IP)。ICMP、IGMP、TCP(6)、UDP(17) はプロトコルヘッダを送信し、それ以外は IP ヘッダのみ送ります。ヘッダの不正により Protocol unreachable や同プロトコルの応答が返ることがあり、それで up を判断します。-n: DNS 未使用-R: 常に DNS を使う
ポートスキャン手法
-sS: 接続を完了させないため痕跡が残りにくい(権限が必要)。デフォルトで使用されます。-sT: 接続を完了させるため痕跡が残りますが、権限不要で確実に使えます(デフォルトは権限なし)。-sU: UDP 用で遅め。主に DNS(53), SNMP(161,162), DHCP(67,68) など。応答は open(reply)、closed(port unreachable)、filtered(別の ICMP)、open/filtered(無応答)。open/filtered の場合、-sV が多数のリクエストを送りバージョン検出を試み、真の状態を検出できることがあります。時間が大幅に増えます。-sY: SCTP のスキャン。接続が確立されないためログが残らず、-PY と同様に動作します。-sN,-sX,-sF: Null, Fin, Xmas。いくつかのファイアウォールをすり抜け情報を得られる場合があります。標準準拠のマシンは SYN/RST/ACK のいずれも立っていない要求に対し RST で応答するはず、という点を利用します:open/filtered(無応答)、closed(RST)、filtered(ICMP unreachable)。Windows, Cisco, BSDI, OS/400 では信頼性が低い。Unix 系では有効なことが多いです。-sM: Maimon スキャン。FIN と ACK を送ります。BSD 向けでしたが現在は全て closed を返すことが多いです。-sA, sW: ACK と Window スキャン。ファイアウォールの検出に使い、ポートがフィルタされているかどうかを判定します。-sW は open/closed を区別できます(open は RST で window 値が 0 以外、closed は RST で window = 0、filtered は ICMP unreachable または無応答)。すべてのホストがこの挙動をするわけではないので、すべて closed ならこの手法は機能していない可能性があり、少数 open なら機能していると判断できます。-sI: Idle scan(ゾンビスキャン)。アクティブなファイアウォールがあるが特定の IP にはフィルタされない場合や匿名性を保ちたい場合にゾンビを利用してスキャンします(全ポート対象)。ゾンビ候補の探索には ipidseq スクリプトや exploit auxiliary/scanner/ip/ipidseq が使えます。このスキャンは IPID 値に基づきます。--badsum: チェックサムを不正にして送信します。本来はホストがパケットを破棄しますが、ファイアウォールが何らかの応答を返すことがあり、ファイアウォールの検出に使われます。-sZ: "Weird" な SCTP スキャナー。cookie echo フラグメントでプローブを送ると、open は破棄、closed は ABORT で応答するはずです。INIT が通らないファイアウォールをすり抜けることがありますが、filtered と open を区別できない欠点があります。-sO: IP プロトコルスキャン。不正または空のヘッダを送り、場合によりプロトコルすら判別できないことがあります。ICMP protocol unreachable が来れば closed、port unreachable が来れば open、別のエラーなら filtered、無応答なら open|filtered。-b <server>: FTP bounce。別ホスト経由でスキャンを行うために使用します。別マシンの FTP に接続して、そこからターゲットのポートへファイル送信を指示し、応答から開閉を判断します。[<user>:<password>@]<server>[:<port>] ほとんどの FTP サーバはこの機能を無効にしているため実用性は低いです。
フォーカス(分析)
-p: スキャンするポートを指定します。全 65,535 ポートを選ぶには -p- または -p all。Nmap は人気度に基づく内部分類を持ち、デフォルトでは上位 1000 ポートを使用します。-F(高速スキャン)で上位 100 をスキャンします。--top-ports
-sV バージョン検出。強度は 0〜9 で調整可能、デフォルトは 7。
--version-intensity
-O OS 検出
--osscan-limit ホストごとに正しくスキャンするには少なくとも 1 つの open と 1 つの closed ポートが必要です。この条件が満たされない場合、これを有効にすると OS 予測を試みません(時間節約)。
--osscan-guess OS 検出が確実でないときにより多くの推測を試みます。
スクリプト
--script
デフォルトスクリプトを使うには -sC または --script=default
利用可能なタイプ: auth, broadcast, default, discovery, dos, exploit, external, fuzzer, intrusive, malware, safe, version, vuln
- Auth: 利用可能な認証スクリプトをすべて実行します
- Default: 基本的なデフォルトスクリプトを実行します
- Discovery: ターゲットから情報を取得します
- External: 外部リソースを利用するスクリプト
- Intrusive: ターゲットに対して侵襲的と見なされるスクリプトを使用します
- Malware: マルウェアやバックドアによって開かれた接続をチェックします
- Safe: 非侵襲的なスクリプトのみを実行します
- Vuln: よく知られた脆弱性を発見します
- All: 利用可能な NSE スクリプトをすべて実行します
スクリプト検索:
nmap --script-help="http-*" -> http- で始まるもの
nmap --script-help="not intrusive" -> intrusive を除くすべて
nmap --script-help="default or safe" -> いずれか(または両方)に属するもの
nmap --script-help="default and safe" -> 両方に属するもの
nmap --script-help="(default or safe or intrusive) and not http-*"
--script-args
--script-args-file
--script-help
--script-trace ---> スクリプトの進行状況に関する情報を提供します
--script-updatedb
スクリプトを使うには: nmap --script Script_Name target と入力します --> スクリプトとスキャナの両方が実行されるため、スキャナオプションも追加可能です。"safe=1" を加えると安全なスクリプトのみを実行します。
時間制御
Nmap は秒、分、ms 単位で時間を指定できます: --host-timeout 引数 900000ms, 900, 900s, および 15m は同じ意味です。
Nmap はスキャン対象ホストをグループ分けしてブロックごとに解析します。1 ブロックの解析が完了するまで次のブロックに進まず、ユーザにはそのブロックが解析されるまで更新が届きません。これにより大きなグループを使う方が効率的です。デフォルトではクラス C で 256 を使用します。
これは --min-hostgroup
並列スキャナ数は制御できますが、Nmap はネットワーク状態に基づいて自動制御するため、あまり触らない方がよいです: --min-parallelism
RTT タイムアウトを変更できますが通常は不要です: --min-rtt-timeout , --max-rtt-timeout , --initial-rtt-timeout
試行回数を変更できます: --max-retries
ホストあたりのスキャン時間を変更できます: --host-timeout
各テスト間の遅延で速度を落とせます: --scan-delay ; --max-scan-delay
1 秒あたりのパケット数を変更できます: --min-rate
filtered や closed のポートは応答が遅いことが多いです。open のみに注目したい場合は高速化のために: --defeat-rst-ratelimit
Nmap の侵襲性を定義するには: -T paranoid|sneaky|polite|normal|aggressive|insane
-T (0-1)
-T0 --> 1 ポートずつスキャンし次のポートまで 5 分待機
-T1 と T2 --> 似ていますが、それぞれ 15 秒および 0.4 秒の待機
-T3 --> デフォルト動作、並列スキャンを含む
-T4 --> --max-rtt-timeout 1250ms --min-rtt-timeout 100ms --initial-rtt-timeout 500ms --max-retries 6 --max-scan-delay 10ms
-T5 --> --max-rtt-timeout 300ms --min-rtt-timeout 50ms --initial-rtt-timeout 250ms --max-retries 2 --host-timeout 15m --max-scan-delay 5ms
Firewall/IDS
ポートへのアクセスを阻止したりパケットを解析します。
-f パケットをフラグメント化します。デフォルトではヘッダ後 8 バイトごとに分割します。サイズを指定するには ..mtu を使います(この場合 -f は使わないでください)。オフセットは 8 の倍数でなければなりません。Version scanners と scripts はフラグメンテーションをサポートしません。
-D decoy1,decoy2,ME Nmap はスキャン元を他の IP に偽装して送信します。リストに ME を入れると自分の位置をその中に挿入します。完全にマスクするには前に 5~6 個の偽装を置くのが良いです。RND:
ランダム IP を使う例: nmap -D RND:10 Target_IP
-S IP Nmap があなたの IP を捕捉できない場合に指定します。別のホストがスキャンしているように見せる用途にも使えます。
-e
多くの管理者は運用上の理由で特定のポートをすべて通すルールを作ることがあります(例: DNS, FTP)。これを悪用するために Nmap は --source-port
--data
--data-string
--data-length
IP パケットのオプションを完全に設定するには --ip-options
送信/受信パケットのオプションを見たい場合は --packet-trace を指定します。IP options を使った例については http://seclists.org/nmap-dev/2006/q3/52 を参照してください。
--ttl
--randomize-hosts 攻撃を目立たなくする
--spoof-mac <MAC address, prefix, or vendor name> MAC を変更します。例: Apple, 0, 01:02:03:04:05:06, deadbeefcafe, 0020F2, Cisco
--proxies
-sP ARP による自ネットワーク内ホスト検出
管理者が特定ポート(例: 20,53,67)からのパケットをすべて通すルールを作ることがあります。その場合 Nmap にそのポートを送信元として使わせることができます: nmap --source-port 53 IP
出力
-oN file 通常出力
-oX file XML 出力
-oS file Script kiddies 形式出力
-oG file Greppable 出力
-oA file -oS を除くすべて
-v level 冗長度
-d level デバッグレベル
--reason host と state の理由を表示
--stats-every time 指定時間ごとの進捗報告
--packet-trace 送出パケットを確認、フィルタ指定可(例: --version-trace, --script-trace)
--open open, open|filtered, unfiltered を表示
--resume file サマリを出力して再開
その他
-6 IPv6 を有効にする
-A は -O -sV -sC --traceroute と同等
実行時
Nmap 実行中に次の操作でオプションを変更できます:
v / V 冗長度を上げる / 下げる
d / D デバッグレベルを上げる / 下げる
p / P パケットトレースのオン/オフ
? ランタイムインタラクションのヘルプ表示
Vulscan
Nmap スクリプトで、得られたサービスのバージョン情報をオフライン DB(他の大規模 DB から取得)と照合して既知の脆弱性を返します。
使用する DB:
- Scipvuldb.csv | http://www.scip.ch/en/?vuldb
- Cve.csv | http://cve.mitre.org
- Osvdb.csv | http://www.osvdb.org
- Securityfocus.csv | http://www.securityfocus.com/bid/
- Securitytracker.csv | http://www.securitytracker.com
- Xforce.csv | http://xforce.iss.net
- Exploitdb.csv | http://www.exploit-db.com
- Openvas.csv | http://www.openvas.org
Nmap フォルダへダウンロードとインストール:
wget http://www.computec.ch/projekte/vulscan/download/nmap_nse_vulscan-2.0.tar.gz && tar -czvf nmap_nse_vulscan-2.0.tar.gz vulscan/ && sudo cp -r vulscan/ /usr/share/nmap/scripts/
さらに DB パッケージをダウンロードして /usr/share/nmap/scripts/vulscan/ に追加する必要があります。
使用例:
すべての DB を使う: sudo nmap -sV --script=vulscan HOST_TO_SCAN
特定 DB を使う: sudo nmap -sV --script=vulscan --script-args vulscandb=cve.csv HOST_TO_SCAN
Nmap サービススキャンを x16 で高速化
to this post によると、/usr/share/nmap/nmap-service-probes 内のすべての totalwaitms 値を 300 に、tcpwrappedms を 200 に変更すると nmap のサービス解析を高速化できます。
さらに、特定のプローブに servicewaitms が定義されていない場合はデフォルトで 5000 が使われます。したがって、各プローブに値を追加するか、nmap を自分でコンパイルして service_scan.h 内のデフォルト値を変更することができます。
/usr/share/nmap/nmap-service-probes 内の totalwaitms や tcpwrappedms の値をまったく変更したくない場合は、parsing code を編集してこれらの値を無視するようにできます。
制限環境向けに静的リンクされた Nmap をビルド
ハード化された環境や最小限の Linux(コンテナ、アプライアンス)では、動的リンクされた Nmap バイナリがランタイムローダや共有ライブラリ(例: /lib64/ld-linux-x86-64.so.2, libc.so)不足で動作しないことがあります。静的リンクされた Nmap をビルドし、NSE データをバイナリに同梱すれば、システムパッケージをインストールせずに実行できます。
概略手順
- Docker でクリーンな amd64 Ubuntu ビルダーを使う
- OpenSSL と PCRE2 を静的ライブラリとしてビルドする
- libpcap/libdnet を同梱して動的依存を避け、Nmap を静的リンクでビルドする
- NSE スクリプトとデータディレクトリをバイナリに同梱する
ターゲットアーキテクチャの確認(例)
uname -a
# If building from macOS/ARM/etc., pin the builder arch:
docker run --rm --platform=linux/amd64 -v "$(pwd)":/out -w /tmp ubuntu:22.04 bash -lc 'echo ok'
ステップ1 — ツールチェーンを準備する
set -euo pipefail
export DEBIAN_FRONTEND=noninteractive
apt-get update && apt-get install -y --no-install-recommends \
build-essential ca-certificates curl bzip2 xz-utils pkg-config perl python3 file git \
automake autoconf libtool m4 zlib1g-dev
ステップ 2 — OpenSSL (1.1.1w) を静的にビルド
OSSL="1.1.1w"
curl -fsSLO "https://www.openssl.org/source/openssl-$OSSL.tar.gz"
tar xzf "openssl-$OSSL.tar.gz" && cd "openssl-$OSSL"
./Configure no-shared no-zlib linux-x86_64 -static --prefix=/opt/ossl
make -j"$(nproc)" && make install_sw
cd /tmp
ステップ3 — 静的 PCRE2 (10.43) のビルド
PCRE2=10.43
curl -fsSLO "https://github.com/PCRE2Project/pcre2/releases/download/pcre2-$PCRE2/pcre2-$PCRE2.tar.bz2"
tar xjf "pcre2-$PCRE2.tar.bz2" && cd "pcre2-$PCRE2"
./configure --disable-shared --enable-static --prefix=/opt/pcre2
make -j"$(nproc)" && make install
cd /tmp
ステップ 4 — 静的な Nmap をビルドする (7.98)
NMAP=7.98
curl -fsSLO "https://nmap.org/dist/nmap-$NMAP.tar.bz2"
tar xjf "nmap-$NMAP.tar.bz2" && cd "nmap-$NMAP"
export CPPFLAGS="-I/opt/ossl/include -I/opt/pcre2/include"
export LDFLAGS="-L/opt/ossl/lib -L/opt/pcre2/lib -static -static-libstdc++ -static-libgcc"
export LIBS="-lpcre2-8 -ldl -lpthread -lz"
./configure \
--with-openssl=/opt/ossl \
--with-libpcre=/opt/pcre2 \
--with-libpcap=included \
--with-libdnet=included \
--without-zenmap --without-ndiff --without-nmap-update
# Avoid building shared libpcap by accident
sed -i -e "s/^shared: /shared: #/" libpcap/Makefile || true
make -j1 V=1 nmap
strip nmap
要点
- -static, -static-libstdc++, -static-libgcc は静的リンクを強制します。
- --with-libpcap=included/--with-libdnet=included を使うとシステム共有ライブラリの使用を避けられます。
- sed の調整は、存在する場合に共有 libpcap ターゲットを無効化します。
Step 5 — バイナリとNSEデータをバンドルする
mkdir -p /out/nmap-bundle/nmap-data
cp nmap /out/nmap-bundle/nmap-linux-amd64-static
cp -r scripts nselib /out/nmap-bundle/nmap-data/
cp nse_main.lua nmap-services nmap-protocols nmap-service-probes \
nmap-mac-prefixes nmap-os-db nmap-payloads nmap-rpc \
/out/nmap-bundle/nmap-data/ 2>/dev/null || true
tar -C /out -czf /out/nmap-linux-amd64-static-bundle.tar.gz nmap-bundle
検証および運用ノート
- アーティファクトに対してfileを使い、静的にリンクされていることを確認する。
- Nmapがインストールされていないホストでもスクリプトの互換性を保つため、NSEデータをbinaryと一緒に保持する。
- 静的なbinaryであっても、AppArmor/seccomp/SELinuxによって実行がブロックされる可能性がある。DNSやegressは引き続き機能する必要がある。
- Deterministic buildsは、不透明な“static” binariesをダウンロードするよりもサプライチェーンのリスクを低減する。
One-liner (Dockerized)
ビルド、バンドル、アーティファクト情報を出力する
docker run --rm --platform=linux/amd64 -v "$(pwd)":/out -w /tmp ubuntu:22.04 bash -lc '
set -euo pipefail
export DEBIAN_FRONTEND=noninteractive
apt-get update && apt-get install -y --no-install-recommends \
build-essential ca-certificates curl bzip2 xz-utils pkg-config perl python3 file git \
automake autoconf libtool m4 zlib1g-dev
OSSL="1.1.1w"; curl -fsSLO "https://www.openssl.org/source/openssl-$OSSL.tar.gz" \
&& tar xzf "openssl-$OSSL.tar.gz" && cd "openssl-$OSSL" \
&& ./Configure no-shared no-zlib linux-x86_64 -static --prefix=/opt/ossl \
&& make -j"$(nproc)" && make install_sw && cd /tmp
PCRE2=10.43; curl -fsSLO "https://github.com/PCRE2Project/pcre2/releases/download/pcre2-$PCRE2/pcre2-$PCRE2.tar.bz2" \
&& tar xjf "pcre2-$PCRE2.tar.bz2" && cd "pcre2-$PCRE2" \
&& ./configure --disable-shared --enable-static --prefix=/opt/pcre2 \
&& make -j"$(nproc)" && make install && cd /tmp
NMAP=7.98; curl -fsSLO "https://nmap.org/dist/nmap-$NMAP.tar.bz2" \
&& tar xjf "nmap-$NMAP.tar.bz2" && cd "nmap-$NMAP" \
&& export CPPFLAGS="-I/opt/ossl/include -I/opt/pcre2/include" \
&& export LDFLAGS="-L/opt/ossl/lib -L/opt/pcre2/lib -static -static-libstdc++ -static-libgcc" \
&& export LIBS="-lpcre2-8 -ldl -lpthread -lz" \
&& ./configure --with-openssl=/opt/ossl --with-libpcre=/opt/pcre2 --with-libpcap=included --with-libdnet=included --without-zenmap --without-ndiff --without-nmap-update \
&& sed -i -e "s/^shared: /shared: #/" libpcap/Makefile || true \
&& make -j1 V=1 nmap && strip nmap
mkdir -p /out/nmap-bundle/nmap-data \
&& cp nmap /out/nmap-bundle/nmap-linux-amd64-static \
&& cp -r scripts nselib /out/nmap-bundle/nmap-data/ \
&& cp nse_main.lua nmap-services nmap-protocols nmap-service-probes nmap-mac-prefixes nmap-os-db nmap-payloads nmap-rpc /out/nmap-bundle/nmap-data/ 2>/dev/null || true \
&& tar -C /out -czf /out/nmap-linux-amd64-static-bundle.tar.gz nmap-bundle \
&& echo "===== OUTPUT ====="; ls -lah /out; echo "===== FILE TYPE ====="; file /out/nmap-bundle/nmap-linux-amd64-static || true
'
参考資料
- Compiling static Nmap binary for jobs in restricted environments
- Static Nmap Binary Generator (helper tool)
- OpenSSL sources
- PCRE2 releases
- Nmap source tarballs
tip
AWSハッキングを学び、実践する:
HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:
HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。
HackTricks