SiamCafe · Blog
Nuclei Scanner Automation Script — สร้าง Script
บทความ

Nuclei Scanner Automation Script — สร้าง Script

เผยแพร่ 28 พฤษภาคม 2569

Nuclei Scanner Automation

Nuclei Scanner Automation Script — สร้าง Script

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:

Nuclei Scanner Automation Script — สร้าง Script
  • "(?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}")

เคล็ดลับ

  • Rate Limit: ตั้ง rate-limit ให้เหมาะสม ไม่ให้ DDoS ตัวเอง
  • Templates: อัปเดต Templates ทุกสัปดาห์ nuclei -update-templates
  • Custom: เขียน Custom Template สำหรับ Application เฉพาะ
  • CI/CD: สแกนทุก Deploy หยุด Pipeline ถ้าพบ Critical
  • Scope: กำหนด Scope ชัดเจน สแกนเฉพาะ Targets ที่ได้รับอนุญาต

Nuclei Scanner คืออะไร

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