Module: PWN::Plugins::Nuclei
- Defined in:
- lib/pwn/plugins/nuclei.rb
Overview
nuclei wrapper: template/severity, JSONL findings.
Class Method Summary collapse
- .authors ⇒ Object
- .help ⇒ Object
- .required_bins ⇒ Object
- .scan(opts = {}) ⇒ Object
- .to_defectdojo(opts = {}) ⇒ Object
- .to_findings(opts = {}) ⇒ Object
Class Method Details
.authors ⇒ Object
53 54 55 |
# File 'lib/pwn/plugins/nuclei.rb', line 53 public_class_method def self. "AUTHOR(S):\n 0day Inc. <[email protected]>\n" end |
.help ⇒ Object
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/pwn/plugins/nuclei.rb', line 57 public_class_method def self.help puts "USAGE: # List host binaries this module expects to be installed. #{self}.required_bins # Run scan and return its result #{self}.scan( target: 'required - hostname, IP, or CIDR to scan (defaults to opts[:url])', url: 'optional - HTTP(S) URL', severity: 'optional - severity value consumed by #scan', templates: 'optional - templates value consumed by #scan', rate_limit: 'optional - requests per second passed to nuclei -rate-limit' ) # Map nuclei JSONL rows into report-shaped finding hashes. #{self}.to_findings( rows: 'optional - Array of parsed nuclei JSONL objects', findings: 'optional - alias for rows' ) # Shape findings for a DefectDojo import payload. #{self}.to_defectdojo( rows: 'optional - Array of parsed nuclei JSONL objects', findings: 'optional - alias for rows' ) # Print the AUTHOR(S) string for this module. #{self}.authors " constants.sort end |
.required_bins ⇒ Object
10 11 12 |
# File 'lib/pwn/plugins/nuclei.rb', line 10 public_class_method def self.required_bins %w[nuclei] end |
.scan(opts = {}) ⇒ Object
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/pwn/plugins/nuclei.rb', line 14 public_class_method def self.scan(opts = {}) PWN::Plugins::PreflightChecker.require_bin!(name: 'nuclei') target = opts[:target] || opts[:url] raise 'ERROR: target is required' if target.to_s.empty? cmd = ['nuclei', '-u', target.to_s, '-jsonl', '-silent'] cmd += ['-severity', opts[:severity].to_s] if opts[:severity] cmd += ['-t', opts[:templates].to_s] if opts[:templates] cmd += ['-rate-limit', opts[:rate_limit].to_s] if opts[:rate_limit] stdout, stderr, status = Open3.capture3(*cmd) findings = stdout.each_line.filter_map do |ln| JSON.parse(ln) rescue JSON::ParserError nil end { findings: to_findings(rows: findings), raw: findings, stderr: stderr, exit: status.exitstatus } end |
.to_defectdojo(opts = {}) ⇒ Object
47 48 49 50 51 |
# File 'lib/pwn/plugins/nuclei.rb', line 47 public_class_method def self.to_defectdojo(opts = {}) to_findings(opts).map do |f| { title: f[:title], severity: f[:severity], description: "#{f[:url]} #{f[:template]}".strip } end end |
.to_findings(opts = {}) ⇒ Object
32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/pwn/plugins/nuclei.rb', line 32 public_class_method def self.to_findings(opts = {}) Array(opts[:rows] || opts[:findings]).map do |r| r = r.transform_keys(&:to_s) if r.is_a?(Hash) info = r['info'] || {} info = info.transform_keys(&:to_s) if info.is_a?(Hash) { title: info['name'] || r['template-id'] || 'nuclei finding', severity: (info['severity'] || 'info').to_s, url: r['matched-at'] || r['host'], template: r['template-id'], description: info['description'] } end end |