mirror of
https://github.com/j3ssie/osmedeus.git
synced 2026-08-25 09:02:29 +02:00
328 lines
12 KiB
YAML
328 lines
12 KiB
YAML
name: vulnscan
|
|
kind: module
|
|
description: Run vulnerability scan on all HTTP hosts using Jaeles and Nuclei scanners
|
|
|
|
params:
|
|
- name: target
|
|
required: true
|
|
- name: httpFile
|
|
default: "{{Output}}/probing/http-{{Workspace}}.txt"
|
|
- name: output_dir
|
|
default: "{{Output}}/vuln"
|
|
- name: sign
|
|
default: "~/.jaeles/base-signatures/cves/.*"
|
|
- name: sign2
|
|
default: "~/.jaeles/base-signatures/common/.*"
|
|
- name: sign3
|
|
default: "~/.jaeles/base-signatures/sensitive/.*"
|
|
- name: splitLines
|
|
default: "500"
|
|
- name: limit
|
|
default: "25000"
|
|
- name: extra
|
|
default: " "
|
|
- name: enableNuclei
|
|
default: "true"
|
|
- name: threads
|
|
default: "10"
|
|
- name: nucleiThreads
|
|
default: "{{threads * 10}}"
|
|
- name: jaelesThreads
|
|
default: "{{threads * 5}}"
|
|
- name: nucleiTimeout
|
|
default: "8h"
|
|
- name: jaelesTimeout
|
|
default: "3h"
|
|
- name: nucleiSeverity
|
|
default: "critical,high,medium,low,info"
|
|
- name: defaultUA
|
|
default: "User-Agent: Mozilla/5.0 (compatible; Osmedeus/v4; +https://github.com/j3ssie/osmedeus)"
|
|
|
|
steps:
|
|
# ============================================================
|
|
# Phase 1: Validate Dependencies
|
|
# ============================================================
|
|
- name: validate-dependencies
|
|
type: function
|
|
function: |
|
|
fileExists("{{Binaries}}/jaeles") &&
|
|
fileExists("{{Binaries}}/nuclei")
|
|
exports:
|
|
deps_valid: "output"
|
|
on_error:
|
|
- action: log
|
|
message: "Required binaries (jaeles, nuclei) not found"
|
|
- action: abort
|
|
|
|
# ============================================================
|
|
# Phase 2: Setup Output Directories
|
|
# ============================================================
|
|
- name: setup-directories
|
|
type: bash
|
|
commands:
|
|
- mkdir -p {{output_dir}}
|
|
- mkdir -p {{output_dir}}/raw
|
|
- mkdir -p {{output_dir}}/active
|
|
- mkdir -p {{output_dir}}/sensitive
|
|
- mkdir -p {{output_dir}}/nuclei
|
|
|
|
# ============================================================
|
|
# Phase 3: Validate Input File
|
|
# ============================================================
|
|
- name: check-input-exists
|
|
type: function
|
|
function: fileExists("{{httpFile}}")
|
|
exports:
|
|
input_exists: "output"
|
|
on_error:
|
|
- action: log
|
|
message: "Input file {{httpFile}} not found"
|
|
- action: abort
|
|
|
|
- name: count-input-lines
|
|
type: function
|
|
function: fileLength("{{httpFile}}")
|
|
exports:
|
|
input_count: "output"
|
|
|
|
# Decision: Abort if input file exceeds limit
|
|
- name: check-input-limit
|
|
type: function
|
|
function: |
|
|
var count = parseInt("{{input_count}}");
|
|
var limit = parseInt("{{limit}}");
|
|
if (count > limit) {
|
|
return "exceeds_limit";
|
|
}
|
|
return "valid";
|
|
exports:
|
|
input_valid: "{{Result}}"
|
|
decision:
|
|
switch: "{{input_valid}}"
|
|
cases:
|
|
"exceeds_limit":
|
|
goto: abort-large-input
|
|
default:
|
|
goto: split-input-file
|
|
|
|
- name: abort-large-input
|
|
type: function
|
|
function: printf("ERROR: Input file has {{input_count}} lines, exceeds limit of {{limit}}")
|
|
on_error:
|
|
- action: abort
|
|
|
|
# ============================================================
|
|
# Phase 4: Split Input for Parallel Processing
|
|
# ============================================================
|
|
- name: split-input-file
|
|
type: function
|
|
function: SplitFile("{{httpFile}}", "{{Workspace}}-index", {{splitLines}}, "{{output_dir}}/raw")
|
|
exports:
|
|
split_dir: "{{output_dir}}/raw"
|
|
|
|
- name: list-split-files
|
|
type: bash
|
|
command: "ls {{output_dir}}/raw/{{Workspace}}-index* 2>/dev/null | head -100 > {{output_dir}}/raw/split-files.txt || touch {{output_dir}}/raw/split-files.txt"
|
|
exports:
|
|
split_files: "{{output_dir}}/raw/split-files.txt"
|
|
|
|
- name: count-split-files
|
|
type: function
|
|
function: fileLength("{{output_dir}}/raw/split-files.txt")
|
|
exports:
|
|
split_count: "output"
|
|
|
|
# ============================================================
|
|
# Phase 5: Jaeles Vulnerability Scanning
|
|
# ============================================================
|
|
- name: jaeles-active-scan
|
|
type: foreach
|
|
pre_condition: 'parseInt("{{split_count}}") > 0'
|
|
input: "{{output_dir}}/raw/split-files.txt"
|
|
variable: splitfile
|
|
threads: 1
|
|
step:
|
|
name: run-jaeles-active
|
|
type: bash
|
|
command: |
|
|
echo "Running Jaeles active scan on [[splitfile]]..."
|
|
timeout -k 1m {{jaelesTimeout}} {{Binaries}}/jaeles scan -c {{jaelesThreads}} -s '{{sign}}' -s '{{sign2}}' -U [[splitfile]] -o {{output_dir}}/active/ {{extra}} 2>/dev/null || true
|
|
timeout: 14400
|
|
|
|
- name: jaeles-sensitive-scan
|
|
type: foreach
|
|
pre_condition: 'parseInt("{{split_count}}") > 0'
|
|
input: "{{output_dir}}/raw/split-files.txt"
|
|
variable: splitfile
|
|
threads: 1
|
|
step:
|
|
name: run-jaeles-sensitive
|
|
type: bash
|
|
command: |
|
|
echo "Running Jaeles sensitive scan on [[splitfile]]..."
|
|
timeout -k 1m {{jaelesTimeout}} {{Binaries}}/jaeles scan --fi -c {{jaelesThreads}} -s '{{sign3}}' -L 2 -U [[splitfile]] -o {{output_dir}}/sensitive/ {{extra}} 2>/dev/null || true
|
|
timeout: 14400
|
|
|
|
# ============================================================
|
|
# Phase 6: Generate Jaeles Reports
|
|
# ============================================================
|
|
- name: generate-jaeles-reports
|
|
type: parallel-steps
|
|
parallel_steps:
|
|
- name: generate-active-report
|
|
type: bash
|
|
command: "{{Binaries}}/jaeles report -o {{output_dir}}/active/ -R {{output_dir}}/active/{{Workspace}}-report.html 2>/dev/null || true"
|
|
on_error:
|
|
- action: continue
|
|
|
|
- name: generate-sensitive-report
|
|
type: bash
|
|
command: "{{Binaries}}/jaeles report -o {{output_dir}}/sensitive/ -R {{output_dir}}/sensitive/{{Workspace}}-sensitive.html 2>/dev/null || true"
|
|
on_error:
|
|
- action: continue
|
|
|
|
# ============================================================
|
|
# Phase 7: Process Jaeles Results
|
|
# ============================================================
|
|
- name: copy-active-summary
|
|
type: bash
|
|
pre_condition: 'fileExists("{{output_dir}}/active/jaeles-summary.txt")'
|
|
command: "cp {{output_dir}}/active/jaeles-summary.txt {{output_dir}}/active/activescan-{{Workspace}}-{{TS}}.txt"
|
|
exports:
|
|
active_summary: "{{output_dir}}/active/activescan-{{Workspace}}-{{TS}}.txt"
|
|
|
|
- name: notify-active-results
|
|
type: function
|
|
pre_condition: 'fileExists("{{output_dir}}/active/activescan-{{Workspace}}-{{TS}}.txt")'
|
|
parallel_functions:
|
|
- TeleMessByFile("#report", "{{output_dir}}/active/activescan-{{Workspace}}-{{TS}}.txt")
|
|
- Cat("{{output_dir}}/active/activescan-{{Workspace}}-{{TS}}.txt")
|
|
- TotalVulnerability("{{output_dir}}/active/activescan-{{Workspace}}-{{TS}}.txt")
|
|
on_error:
|
|
- action: log
|
|
message: "Failed to notify active scan results"
|
|
- action: continue
|
|
|
|
- name: copy-sensitive-summary
|
|
type: bash
|
|
pre_condition: 'fileExists("{{output_dir}}/sensitive/jaeles-summary.txt")'
|
|
command: "cp {{output_dir}}/sensitive/jaeles-summary.txt {{output_dir}}/sensitive/sensitivescan-{{Workspace}}-{{TS}}.txt"
|
|
exports:
|
|
sensitive_summary: "{{output_dir}}/sensitive/sensitivescan-{{Workspace}}-{{TS}}.txt"
|
|
|
|
- name: notify-sensitive-results
|
|
type: function
|
|
pre_condition: 'fileExists("{{output_dir}}/sensitive/sensitivescan-{{Workspace}}-{{TS}}.txt")'
|
|
parallel_functions:
|
|
- TeleMessByFile("#sensitive", "{{output_dir}}/sensitive/sensitivescan-{{Workspace}}-{{TS}}.txt")
|
|
- Cat("{{output_dir}}/sensitive/sensitivescan-{{Workspace}}-{{TS}}.txt")
|
|
- TotalVulnerability("{{output_dir}}/sensitive/sensitivescan-{{Workspace}}-{{TS}}.txt")
|
|
on_error:
|
|
- action: log
|
|
message: "Failed to notify sensitive scan results"
|
|
- action: continue
|
|
|
|
# ============================================================
|
|
# Phase 8: Nuclei Vulnerability Scanning
|
|
# ============================================================
|
|
- name: nuclei-scan
|
|
type: bash
|
|
pre_condition: '"{{enableNuclei}}" == "true" && fileExists("{{httpFile}}")'
|
|
command: |
|
|
timeout -k 1m {{nucleiTimeout}} {{Binaries}}/nuclei \
|
|
-H '{{defaultUA}}' \
|
|
-silent \
|
|
-c {{nucleiThreads}} \
|
|
-jsonl \
|
|
-severity '{{nucleiSeverity}}' \
|
|
-t ~/nuclei-templates/ \
|
|
-l {{httpFile}} \
|
|
-irr \
|
|
-o {{output_dir}}/nuclei/{{Workspace}}-nuclei-json.txt
|
|
timeout: 28800
|
|
exports:
|
|
nuclei_json: "{{output_dir}}/nuclei/{{Workspace}}-nuclei-json.txt"
|
|
on_error:
|
|
- action: log
|
|
message: "Nuclei scan failed or timed out"
|
|
- action: continue
|
|
|
|
- name: count-nuclei-results
|
|
type: function
|
|
pre_condition: 'fileExists("{{output_dir}}/nuclei/{{Workspace}}-nuclei-json.txt")'
|
|
function: fileLength("{{output_dir}}/nuclei/{{Workspace}}-nuclei-json.txt")
|
|
exports:
|
|
nuclei_count: "output"
|
|
|
|
# ============================================================
|
|
# Phase 9: Process Nuclei Results
|
|
# ============================================================
|
|
- name: generate-nuclei-report
|
|
type: function
|
|
pre_condition: 'parseInt("{{nuclei_count}}") > 0'
|
|
function: GenNucleiReport("{{output_dir}}/nuclei/{{Workspace}}-nuclei-json.txt", "{{output_dir}}/nuclei/{{Workspace}}-nuclei.html")
|
|
on_error:
|
|
- action: log
|
|
message: "Failed to generate Nuclei HTML report"
|
|
- action: continue
|
|
|
|
- name: parse-nuclei-json
|
|
type: bash
|
|
pre_condition: 'parseInt("{{nuclei_count}}") > 0'
|
|
command: |
|
|
cat {{output_dir}}/nuclei/{{Workspace}}-nuclei-json.txt | \
|
|
jq -r '[.info.severity,.\"template-id\",.\"matched-at\",.\"matched-name\"] | join(\" - \")' \
|
|
> {{output_dir}}/nuclei/{{Workspace}}-nuclei-scan.txt 2>/dev/null || true
|
|
exports:
|
|
nuclei_parsed: "{{output_dir}}/nuclei/{{Workspace}}-nuclei-scan.txt"
|
|
|
|
- name: sort-nuclei-results
|
|
type: function
|
|
pre_condition: 'fileExists("{{output_dir}}/nuclei/{{Workspace}}-nuclei-scan.txt")'
|
|
function: SortU("{{output_dir}}/nuclei/{{Workspace}}-nuclei-scan.txt")
|
|
|
|
- name: notify-nuclei-results
|
|
type: function
|
|
pre_condition: 'parseInt("{{nuclei_count}}") > 0'
|
|
parallel_functions:
|
|
- TeleMessByFile("#sensitive", "{{output_dir}}/nuclei/{{Workspace}}-nuclei-scan.txt")
|
|
- Cat("{{output_dir}}/nuclei/{{Workspace}}-nuclei-scan.txt")
|
|
on_error:
|
|
- action: log
|
|
message: "Failed to notify Nuclei results"
|
|
- action: continue
|
|
|
|
# ============================================================
|
|
# Phase 10: Generate Final Report
|
|
# ============================================================
|
|
- name: generate-final-report
|
|
type: function
|
|
pre_condition: 'fileExists("{{Data}}/markdown/general-template.md")'
|
|
function: GenMarkdownReport("{{Data}}/markdown/general-template.md", "{{Output}}/summary.html")
|
|
on_error:
|
|
- action: log
|
|
message: "Final report generation skipped - template not found"
|
|
- action: continue
|
|
|
|
- name: generate-vuln-summary
|
|
type: bash
|
|
commands:
|
|
- |
|
|
echo "=== Vulnerability Scan Report ===" > {{output_dir}}/final-report-{{Workspace}}.txt
|
|
echo "Target: {{Target}}" >> {{output_dir}}/final-report-{{Workspace}}.txt
|
|
echo "Workspace: {{Workspace}}" >> {{output_dir}}/final-report-{{Workspace}}.txt
|
|
echo "Date: $(date)" >> {{output_dir}}/final-report-{{Workspace}}.txt
|
|
echo "" >> {{output_dir}}/final-report-{{Workspace}}.txt
|
|
echo "=== Statistics ===" >> {{output_dir}}/final-report-{{Workspace}}.txt
|
|
echo "Input Hosts: {{input_count}}" >> {{output_dir}}/final-report-{{Workspace}}.txt
|
|
echo "Nuclei Findings: {{nuclei_count}}" >> {{output_dir}}/final-report-{{Workspace}}.txt
|
|
echo "" >> {{output_dir}}/final-report-{{Workspace}}.txt
|
|
echo "=== Reports Generated ===" >> {{output_dir}}/final-report-{{Workspace}}.txt
|
|
echo "- Active Scan: {{output_dir}}/active/{{Workspace}}-report.html" >> {{output_dir}}/final-report-{{Workspace}}.txt
|
|
echo "- Sensitive Scan: {{output_dir}}/sensitive/{{Workspace}}-sensitive.html" >> {{output_dir}}/final-report-{{Workspace}}.txt
|
|
echo "- Nuclei Scan: {{output_dir}}/nuclei/{{Workspace}}-nuclei.html" >> {{output_dir}}/final-report-{{Workspace}}.txt
|
|
|
|
- name: notify-completion
|
|
type: function
|
|
function: printf("Vulnerability scan complete: {{input_count}} hosts scanned, {{nuclei_count}} nuclei findings")
|