Nmap を GUI で回して「怪しい端末」を可視化するツールを作った話 – rogue-finder
社内ネットワークや自宅の LAN に、**いつの間にか増えた「誰のものか分からない端末」**ってありませんか?
- いつの間にか生えている Wi-Fi ルーター
- 情報システムは知らない NAS
- 放置された Windows 機・Raspberry Pi
- シャドー IT 的なクラウドゲートウェイ
こういった 「Rogue(不正/未管理)な端末」をどう見つけるか は、ゼロトラストや ASM(Attack Surface Management)が叫ばれる昨今でも、現場レベルでは結構な手作業だったりします。
そこで今回は、Nmap をベースに LAN 上のホストをディスカバリして、「怪しさスコア」でソートしてくれる GUI ツールを作りました。
- リポジトリ: unagi/rogue-finder
名前はそのまま rogue-finder です。
この記事で書くこと
- なぜ rogue-finder を作ったのか(問題意識)
- ツールの概要と特徴
- 「怪しさスコア」の設計(何をどう点数化しているか)
- 実際の使い方(Nmap CLI に馴染みがなくても触れるレベルで)
- 実装のポイント(PySide6 / multiprocessing /
nmap --script safe連携) - 今後の拡張アイディア
なぜ作ったか – Nmap + 表計算の限界
ネットワーク上の未管理端末を見つけるだけなら、正直 Nmap だけでも十分です。
nmap -sn 192.168.0.0/24
nmap -O -p 22,80,443,445,3389 192.168.0.0/24
…といったコマンドでスキャンして、結果を CSV に落として Excel やスプレッドシートで整理する、という運用をしている方も多いと思います。
ただ、実務でやってみると次のようなところでつまずきがちです。
- コマンドライン前提のため、Nmap に不慣れなメンバーには渡しにくい
- 照合・ソート・色付けなどを 毎回 Excel / Spreadsheet でやり直す
- 「どのホストから優先的に見るべきか」が 人の感覚に依存してしまう
「nmap の出力 → 表計算で加工 → 怪しそうなものに目視でフラグ」というフローを自動化したい
というのが最初のモチベーションです。
rogue-finder とは
一言でいうと
Nmap を GUI からたたいて、ホストの「怪しさスコア」を自動で付けてくれる軽量ツール
です。
README の定義を要約すると、こんな感じのツールです:
- Python / PySide6 製の クロスプラットフォーム GUI アプリ
- ローカルにインストール済みの
nmapコマンドを 外部プロセスとして呼び出す - ICMP / ポートスキャン / OS 推定の 3 フェーズで軽量ディスカバリ
- 結果を独自ルールでスコアリングし、High / Medium / Low の優先度に分類
- その場で
nmap --script safeを単一ホストごとに叩ける診断ボタン付き - 結果は CSV / JSON / テキストレポートとしてエクスポート可能
商用スキャナに全部を任せるのではなく、その前段階として「どこにスキャナを当てるべきか」を整理するための前処理ツール、という位置づけです。
アーキテクチャ概要
中身は「ローカル GUI + マルチプロセス + nmap サブプロセス」というシンプルな構成です。
GUI (PySide6)
└─ ScanManager
└─ Worker (multiprocessing, ProcessPoolExecutor)
└─ nmap subprocess
├─ XML parser
└─ Rating engine
└─ Result table (GUI にバインド)
なぜ Nmap を「同梱」せず外部プロセスにしたか
- Nmap は NPSL ライセンスの都合もあり、アプリにバンドルせず外部コマンドとして扱う方が OSS として公開しやすい
- OS ごとに最適な Nmap の配布形態(公式インストーラ / Homebrew など)があるため、そこは各 OS のエコシステムに任せたい
という理由から、あくまで
- rogue-finder: Nmap のフロントエンド & スコアリングエンジン
- Nmap 本体: ユーザーが OS 標準の方法でインストールしたものを利用
という役割分担にしています。
スコアリング(怪しさレーティング)の考え方
ディスカバリで集めた情報をそのまま一覧で眺めても、結局「どこから見るか」で迷ってしまいます。
そこで rogue-finder では、以下のような要素をもとに 「怪しさスコア (0〜∞)」を付ける簡易ルールを定義しています:
- ICMP 応答の有無
- 開いているポートの種類
- OS 推定の結果
- 特定のポートの組み合わせ
- 高番ポートの開放状況
1. ICMP 応答
- ping に 応答があるホストは +2 点
→ 「ちゃんと動いている何かがある」ので監視対象。
2. ポート危険度
代表的にはこんなイメージで加点しています(ざっくり):
-
SMB / RDP / FTP など、攻撃対象になりやすいサービスが開いている: +2
- 例: 21, 445, 3389, 5985
-
Redis / Memcached / MQ / DB など、インターネット側に出ていると危ない系: +2
-
Web 系の高番ポート: +1
- 例: 3000, 8000, 8080, 8888 など
「開いていれば即アウト」という意味ではなく、優先的に調査対象にしたいサービスに点数を乗せていくイメージです。
3. OS 推定
nmap -O の結果から OS を大まかに分類し、以下のようなイメージで点数を足しています:
- Windows / SOHO ルータ / IoT 機器など → +3
- 古めの Linux → +2
- サーバ用途の Linux(ちゃんと管理されていそうなもの) → +1
- 不明だが何かしら動いている → +1
家庭用ルータや IoT デバイス、古い OS は、脆弱性や設定不備が残りやすいため高めに加点します。
4. ポートの組み合わせ
1ポートだけ見ても分からない「雰囲気」を、組み合わせルールで補正しています。
例:
-
22と3306/5432がセット → 「手元の管理用 Linux + DB かも」→ +2 -
3389と1433がセット → 「RDP + SQL Server」→ +2 -
8080+5672+15672→ 「Web 管理画面付き MQ」→ +3
など、「よくある怪しげな役割」をスコアに乗せています。
5. 高番ポート
-
50000など、特定の高番ポートが開いている場合に +1
→ 一部製品固有の管理ポートなどをターゲットにしています。
6. 優先度へのマッピング
最後に、合計スコアからシンプルに優先度を割り当てています:
| スコア | 優先度 | ざっくりした意味 |
|---|---|---|
| 8 以上 | High | 「真っ先に見るべき」 |
| 5〜7 | Medium | 「順番を付けて調べたい」 |
| 4 以下 | Low | 「今すぐでなくても良いが記録はする」 |
GUI 上では、この優先度に応じて 行の色を変えてハイライトしているので、High だけざっと目を通す、といった使い方ができます。
実際の使い方
1. インストール
前提
- Python 3.11+
- Nmap がインストール済みで
PATHに通っていること
Windows の例:
- 公式サイト から Nmap をインストール
- インストーラの指示に従って進め、インストール後にターミナルを再起動
macOS の例:
brew install nmap
rogue-finder のセットアップ
git clone https://github.com/unagi/rogue-finder.git
cd rogue-finder
pip install -r requirements.txt
2. 起動
python -m nmap_gui.main
# 詳細ログを見たいときは
python -m nmap_gui.main --debug
PyInstaller で固めたバイナリも GitHub Releases に置いているので、Python を意識したくない人はそちらを使ってもらうこともできます。
※ Windows 初回起動時は SmartScreen、macOS では Gatekeeper の警告が出るので、信頼する場合は明示的に許可してください。
3. スキャンの流れ
GUI 上での基本操作は次の通りです。
-
対象 IP / CIDR を入力
- 例:
192.168.0.0/24や10.0.0.1-10.0.0.50など、複数行やカンマ区切りもサポート
- 例:
-
実行したい スキャンフェーズを選択(ICMP / Ports / OS)
-
Start ボタンでスキャン開始
- 内部では
ProcessPoolExecutorで並列に nmap を回しています
- 内部では
-
結果テーブルにホスト一覧が表示され、スコアに応じて色分け
-
怪しそうなホストから順に、
-
Safe Scriptボタンでnmap --script safeを実行 - 診断結果をダイアログで確認しつつ、必要に応じて テキストレポートを保存
-
-
必要に応じて CSV / JSON にエクスポートし、他システムや Excel での分析に流す
Safe Script 診断の動き
Safe Script ボタンを押すと、そのホストに対して
nmap --script safe <target> ...
を実行します。
- 実行中は 他の Safe Script ボタンとディスカバリ Start/Stop を無効化し、常に単一ジョブに制限
- コマンド・開始/終了時刻・stdout/stderr などのログをダイアログで表示
- そのまま
safe-scan_<target>_<timestamp>.txtというファイル名で保存可能 - 実行時間は
-T4前提の 2 分を基準にした擬似プログレスバーで表示し、実測平均が長くなったら動的に基準を伸ばす
Nmap に不慣れなメンバーに「このボタン押すと安全系スクリプトだけ走るよ」と渡せるのが地味に便利です。
実装ハイライト
1. GUI: PySide6 ベース
src/nmap_gui/gui.py で PySide6 のウィジェットを構築し、以下を扱います:
- 入力フォーム(ターゲット IP / CIDR)
- スキャンフェーズのチェックボックス
- Start / Stop ボタン
- 結果テーブル(ソート / 色付け)
- Safe Script ボタンと診断ダイアログ
GUI スレッドとスキャン処理スレッドを切り離すことで、スキャン中でも UI が固まらないようにしています。
2. スキャンマネージャ: multiprocessing + ProcessPoolExecutor
src/nmap_gui/scan_manager.py は GUI とワーカープロセスの橋渡しを行い、以下を担当します:
- スキャンジョブのキュー管理
-
ProcessPoolExecutorによる並列実行 - 途中キャンセル時のプロセス終了処理
- 結果のマージと GUI への反映
CLI で nmap を単発実行するのと違い、GUI では「途中でやめたい」「今どこまで終わっているか知りたい」という要求があるため、ここをちゃんと整理するだけでも価値が出ます。
3. Nmap ラッパと XML パーサ
src/nmap_gui/nmap_runner.py では
-
subprocessでの nmap 実行 - XML 出力のパース
- エラー・タイムアウトハンドリング
をひとまとめにし、上位層は「ターゲット」「モード」を指定するだけで済むようにしています。
4. レーティングエンジン
src/nmap_gui/rating.py にスコアリングロジックを閉じ込めておくことで、
- ルールの追加・変更
- ポートや OS 分類の微調整
を、GUI やスキャン部分に手を入れずに行えるようにしています。
たとえば、擬似コード的にはこんな構造です:
def rate_host(host):
score = 0
if host.icmp_alive:
score += 2
score += score_open_ports(host.open_ports)
score += score_os(host.os_guess)
score += score_combinations(host.open_ports)
score += score_high_ports(host.open_ports)
priority = classify_priority(score)
return score, priority
こうしておくと、今後
- 特定ベンダ機器向けのルール追加
- 組織固有ポートの「要注意扱い」
なども比較的扱いやすくなります。
5. CI / リリースフロー
GitHub Actions で PyInstaller ビルドを回し、
-
mainブランチへの push で Windows 向けバイナリビルド - タグ(
v1.0.0など)を push すると Windows / macOS 向けバイナリを両方ビルド
というフローを組んでいます。
生成物は GitHub Actions のアーティファクトとしてアップロードされるので、そのまま Release に添付すれば配布形態として十分使える形になります。
今後の拡張アイディア
仕様書にも書いていますが、今後はこんな拡張を考えています:
-
SQLite への結果保存
- 定期スキャンを蓄積して、後から検索・分析できるように
-
差分検出
- 「前回スキャンから増えたホスト」「ポート構成が変わったホスト」のみを抽出
-
ダークテーマ対応
- 夜の監視室フレンドリーな UI に
-
CMDB / 資産管理との連携
- 既知ホスト群との照合により、本当の意味での「Rogue 端末」を炙り出す
まとめ
- rogue-finder は、Nmap の結果を GUI で扱いつつ「怪しさスコア」で並べてくれる軽量ツールです
- ICMP 応答、開いているポート、OS 推定、ポートの組み合わせ、高番ポートなどを元にスコアリングし、どこから見るべきかの優先度を自動で決めてくれます
- GUI ベースなので、コマンドラインに馴染みのないメンバーにも渡しやすく、
nmap --script safeのワンクリック診断など「現場で実際に使う」ことを意識して作っています - まだシンプルなツールですが、資産管理や商用スキャナの前処理として、ちょうど良い立ち位置を目指しています
もし興味があれば、ぜひ試してフィードバックをもらえると嬉しいです 🙏
- GitHub: unagi/rogue-finder