SiamCafe.net Blog
Technology

Nuclei Scanner Automation Script

nuclei scanner automation script
Nuclei Scanner Automation Script | SiamCafe Blog
2025-06-25· อ. บอม — SiamCafe.net· 8,216 คำ

Nuclei Scanner Automation

Nuclei Open Source Vulnerability Scanner ProjectDiscovery Template-based HTTP DNS TCP SSL CVE Misconfiguration Automation CI/CD Pipeline Security Testing

Scannerประเภทจุดเด่นใช้เมื่อ
NucleiVulnerabilityTemplate-based เร็วWeb App Scanning
NmapNetworkPort/Service DiscoveryNetwork Recon
NiktoWeb ServerServer MisconfigurationWeb Server Scan
OWASP ZAPDASTActive/Passive ScanFull Web App Test
TrivyContainerImage VulnerabilityDocker/K8s Scan

Nuclei Installation และ Basic Scan

# === Nuclei Installation & Basic Usage ===

# Install Nuclei
# go install -v github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest
# หรือ
# brew install nuclei
# หรือ
# docker pull projectdiscovery/nuclei:latest

# Update Templates
# nuclei -update-templates

# Basic Scan
# nuclei -u https://example.com
# nuclei -u https://example.com -t cves/
# nuclei -u https://example.com -t misconfiguration/
# nuclei -u https://example.com -severity critical, high
# nuclei -u https://example.com -tags xss, sqli, rce

# Scan Multiple Targets
# nuclei -l targets.txt -t cves/ -severity critical, high
# nuclei -l targets.txt -t exposures/ -o results.txt
# nuclei -l targets.txt -t technologies/ -json -o results.json

# Advanced Options
# nuclei -u https://example.com \
#   -t cves/ -t misconfiguration/ -t exposures/ \
#   -severity critical, high, medium \
#   -rate-limit 150 \
#   -bulk-size 25 \
#   -concurrency 25 \
#   -timeout 10 \
#   -retries 2 \
#   -header "Authorization: Bearer TOKEN" \
#   -json -o scan_results.json

# Python Automation Script
import subprocess
import json
from dataclasses import dataclass, field
from typing import List, Dict
from datetime import datetime

@dataclass
class ScanTarget:
    url: str
    name: str
    environment: str  # production, staging, dev

@dataclass
class ScanResult:
    target: str
    template_id: str
    severity: str
    name: str
    matched_at: str
    timestamp: str

@dataclass
class NucleiScanner:
    targets: List[ScanTarget] = field(default_factory=list)
    results: List[ScanResult] = field(default_factory=list)
    severity_filter: str = "critical, high, medium"
    rate_limit: int = 150
    templates: List[str] = field(default_factory=lambda: ["cves/", "misconfiguration/"])

    def add_target(self, url: str, name: str, env: str):
        self.targets.append(ScanTarget(url, name, env))

    def build_command(self, target_file: str) -> List[str]:
        cmd = ["nuclei", "-l", target_file,
               "-severity", self.severity_filter,
               "-rate-limit", str(self.rate_limit),
               "-json", "-silent"]
        for t in self.templates:
            cmd.extend(["-t", t])
        return cmd

    def parse_results(self, output: str) -> List[ScanResult]:
        results = []
        for line in output.strip().split("\n"):
            if not line:
                continue
            try:
                data = json.loads(line)
                results.append(ScanResult(
                    target=data.get("host", ""),
                    template_id=data.get("template-id", ""),
                    severity=data.get("info", {}).get("severity", ""),
                    name=data.get("info", {}).get("name", ""),
                    matched_at=data.get("matched-at", ""),
                    timestamp=data.get("timestamp", ""),
                ))
            except json.JSONDecodeError:
                pass
        return results

    def summary(self) -> Dict:
        counts = {"critical": 0, "high": 0, "medium": 0, "low": 0, "info": 0}
        for r in self.results:
            sev = r.severity.lower()
            if sev in counts:
                counts[sev] += 1
        return counts

# Demo
scanner = NucleiScanner()
scanner.add_target("https://app.example.com", "Main App", "production")
scanner.add_target("https://api.example.com", "API Server", "production")
scanner.add_target("https://staging.example.com", "Staging", "staging")

print("=== Nuclei Scanner Config ===")
print(f"  Targets: {len(scanner.targets)}")
print(f"  Severity: {scanner.severity_filter}")
print(f"  Templates: {scanner.templates}")
print(f"  Rate Limit: {scanner.rate_limit} req/s")

for t in scanner.targets:
    print(f"  [{t.environment}] {t.name}: {t.url}")

Custom Template

# === Nuclei Custom Template ===

# custom-admin-panel.yaml
# id: custom-admin-panel
# info:
#   name: Custom Admin Panel Detection
#   author: security-team
#   severity: medium
#   description: Detects exposed admin panels
#   tags: admin, panel, exposure
#
# http:
#   - method: GET
#     path:
#       - "{{BaseURL}}/admin"
#       - "{{BaseURL}}/admin/login"
#       - "{{BaseURL}}/wp-admin"
#       - "{{BaseURL}}/administrator"
#       - "{{BaseURL}}/manage"
#       - "{{BaseURL}}/dashboard"
#     matchers-condition: or
#     matchers:
#       - type: status
#         status:
#           - 200
#           - 302
#       - type: word
#         words:
#           - "admin"
#           - "login"
#           - "dashboard"
#         condition: or

# custom-api-key-exposure.yaml
# id: custom-api-key-exposure
# info:
#   name: API Key Exposure in Response
#   author: security-team
#   severity: high
#   tags: exposure, apikey, secret
#
# http:
#   - method: GET
#     path:
#       - "{{BaseURL}}"
#       - "{{BaseURL}}/api/config"
#       - "{{BaseURL}}/env"
#       - "{{BaseURL}}/.env"
#     matchers:
#       - type: regex
#         regex:
#           - "(?i)(api[_-]?key|api[_-]?secret|access[_-]?token)\\s*[=:]\\s*['\"][a-zA-Z0-9]{20,}"
#           - "(?i)(aws[_-]?access[_-]?key|aws[_-]?secret)\\s*[=:]\\s*['\"][A-Z0-9]{20,}"
#           - "(?i)(sk-[a-zA-Z0-9]{48})"  # OpenAI API Key
#     extractors:
#       - type: regex
#         regex:
#           - "(?i)(api[_-]?key|api[_-]?secret)\\s*[=:]\\s*['\"][a-zA-Z0-9]{20,}['\"]"

template_categories = {
    "CVEs": {"count": 2500, "desc": "Known Vulnerabilities (CVE-2024-xxxx)"},
    "Misconfiguration": {"count": 800, "desc": "Server/App Misconfigurations"},
    "Exposures": {"count": 600, "desc": "Sensitive Files, Panels, APIs"},
    "Technologies": {"count": 500, "desc": "Technology Detection (Fingerprint)"},
    "Default Logins": {"count": 200, "desc": "Default Credentials Check"},
    "Takeovers": {"count": 100, "desc": "Subdomain Takeover"},
    "Fuzzing": {"count": 150, "desc": "Parameter Fuzzing, XSS, SQLi"},
}

print("Nuclei Template Categories:")
total = 0
for cat, info in template_categories.items():
    total += info["count"]
    print(f"  [{cat}] {info['count']} templates — {info['desc']}")
print(f"\n  Total: {total}+ templates")

CI/CD Integration

# === CI/CD Integration ===

# GitHub Actions
# .github/workflows/security-scan.yml
# name: Security Scan
# on:
#   push:
#     branches: [main]
#   schedule:
#     - cron: '0 2 * * 1'  # Weekly Monday 2AM
#
# jobs:
#   nuclei-scan:
#     runs-on: ubuntu-latest
#     steps:
#     - uses: actions/checkout@v4
#     - name: Install Nuclei
#       run: |
#         go install github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest
#         nuclei -update-templates
#     - name: Run Scan
#       run: |
#         nuclei -u } \
#           -severity critical, high \
#           -t cves/ -t misconfiguration/ \
#           -json -o results.json
#     - name: Check Results
#       run: |
#         CRITICAL=$(cat results.json | jq '[.[] | select(.info.severity=="critical")] | length')
#         HIGH=$(cat results.json | jq '[.[] | select(.info.severity=="high")] | length')
#         echo "Critical: $CRITICAL, High: $HIGH"
#         if [ "$CRITICAL" -gt 0 ]; then
#           echo "CRITICAL vulnerabilities found!"
#           exit 1
#         fi
#     - name: Notify Slack
#       if: failure()
#       uses: 8398a7/action-slack@v3
#       with:
#         status: failure
#         text: "Security scan found critical vulnerabilities!"

# Automation Script
scan_schedule = {
    "Daily": {"templates": ["cves/2024/"], "severity": "critical", "targets": "production"},
    "Weekly": {"templates": ["cves/", "misconfiguration/"], "severity": "critical, high", "targets": "all"},
    "Monthly": {"templates": ["all"], "severity": "all", "targets": "all + external"},
    "On Deploy": {"templates": ["cves/", "exposures/"], "severity": "critical, high", "targets": "deployed app"},
}

print("Scan Schedule:")
for freq, config in scan_schedule.items():
    print(f"\n  [{freq}]")
    for k, v in config.items():
        print(f"    {k}: {v}")

# Report Format
report_fields = [
    "Vulnerability Name และ CVE ID",
    "Severity (Critical/High/Medium/Low)",
    "Affected URL และ Endpoint",
    "Evidence (Response snippet)",
    "Remediation Steps",
    "CVSS Score",
    "Reference Links",
]

print(f"\n\nScan Report Fields:")
for i, f in enumerate(report_fields, 1):
    print(f"  {i}. {f}")

เคล็ดลับ

Nuclei Scanner คืออะไร

Open Source Vulnerability Scanner ProjectDiscovery Template-based HTTP DNS TCP CVE Misconfiguration 7000+ Templates Custom YAML

Nuclei ต่างจาก Nmap อย่างไร

Nmap Network Scanner Port Service OS Detection Nuclei Vulnerability Scanner Web App CVE Misconfig Templates ใช้ร่วมกัน

Nuclei Template เขียนอย่างไร

YAML Format id info requests method path matchers status word regex extractors variables conditions Custom Application

ใช้ Nuclei ใน CI/CD ได้ไหม

ได้ GitHub Actions GitLab CI Jenkins Severity Threshold Critical High หยุด Pipeline Report Slack Email JIRA ทุก Deploy

สรุป

Nuclei Scanner Vulnerability Scanning Template-based CVE Misconfiguration Custom Template YAML CI/CD Integration GitHub Actions Rate Limit Automation Script Security Testing Report

📖 บทความที่เกี่ยวข้อง

Nuclei Scanner Monitoring และ Alertingอ่านบทความ → Nuclei Scanner Database Migrationอ่านบทความ → Nuclei Scanner Hybrid Cloud Setupอ่านบทความ → Nuclei Scanner Hexagonal Architectureอ่านบทความ →

📚 ดูบทความทั้งหมด →