odle 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/bin/odle +31 -0
- data/lib/model/data.rb +18 -0
- data/lib/odle.rb +11 -0
- data/lib/parsers/burp.rb +54 -0
- data/lib/parsers/msfv5.rb +30 -0
- data/lib/parsers/nessus.rb +48 -0
- metadata +53 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d1872753a818f50f6e296e552c725cbb501d6d8f
|
4
|
+
data.tar.gz: f0f76bb273a5a1e3c08d2ac28d3c0a4c5f4e5f18
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3883cb8a3cad9fc64f347e3a90ce95bbcf4ff587cf78a2e9fa7557cc96402dcc3448c4cdf5d83b40a278f85c23b188a28d472f045abc862827dcf22b925e2006
|
7
|
+
data.tar.gz: 818aeceb1ad25ca6ae1f5e274389414f9b68d14e5f1807c27f4c21bc7efc889109d89773136ca2ebe26d5f4d05136411407b4481de00b377b1024c2e96cb1cd2
|
data/bin/odle
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'odle'
|
4
|
+
|
5
|
+
# data flags are required
|
6
|
+
flags = ARGV.shift
|
7
|
+
|
8
|
+
unless flags
|
9
|
+
puts "[!] A data type is required e.g.\n odle --burp \n\n Available types:"#+list_types()
|
10
|
+
exit(0)
|
11
|
+
end
|
12
|
+
|
13
|
+
# flags come in the form --type or --type,arg1=val1,arg2=val2
|
14
|
+
if flags =~ /,/
|
15
|
+
# complicated flags, not implemented yet
|
16
|
+
all = flags.gsub("--","").split(",")
|
17
|
+
|
18
|
+
type = all[0]
|
19
|
+
else
|
20
|
+
type = flags.gsub("--","")
|
21
|
+
end
|
22
|
+
|
23
|
+
if type.downcase == "burp"
|
24
|
+
puts Burp.new().parse(ARGF.read,"0")
|
25
|
+
elsif type.downcase == "nessus"
|
26
|
+
puts Nessus.new().parse(ARGF.read,"0")
|
27
|
+
elsif type.downcase == "msf"
|
28
|
+
puts Metasploit.new().parse(ARGF.read,"0")
|
29
|
+
else
|
30
|
+
puts "[!] Unknown data type \n\n Available types:"#+list_types()
|
31
|
+
end
|
data/lib/model/data.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
class Host
|
4
|
+
attr_accessor :ip, :port
|
5
|
+
end
|
6
|
+
|
7
|
+
class Finding
|
8
|
+
attr_accessor :title,:id,:effort,:type,:dread_total,:overview,:poc,:remediation,:notes,:assessment_type,:references,:risk,:damage,:reproducability,:exploitability,:affected_users,:discoverability,:av,:ac,:au,:c,:i,:a,:e,:rl,:rc,:cdp,:td,:cr,:ir,:ar,:cvss_base,:cvss_impact,:cvss_exploitability,:cvss_temporal,:cvss_environmental,:cvss_modified_impact,:cvss_total,:ease,:c2_vs,:attack_vector,:attack_complexity,:privileges_required,:user_interaction,:scope_cvss,:confidentiality,:integrity,:availability,:exploit_maturity,:remeditation_level,:report_confidence,:confidentiality_requirement,:integrity_requirement,:availability_requirement,:mod_attack_vector,:mod_attack_complexity,:mod_privileges_required,:mod_user_interaction,:mod_scope,:mod_confidentiality,:mod_integrity,:mod_availability,:cvss_base_score,:cvss_impact_score,:cvss_mod_impact_score,:c3_vs,:severity,:likelihood,:severity_rationale,:likelihood_rationale,:affected_hosts
|
9
|
+
|
10
|
+
def to_hash
|
11
|
+
hash = {}
|
12
|
+
self.instance_variables.each do |var|
|
13
|
+
#p var.to_s.gsub("@","")
|
14
|
+
hash[var.to_s.gsub("@","").gsub("\"","")] = self.instance_variable_get var
|
15
|
+
end
|
16
|
+
return hash
|
17
|
+
end
|
18
|
+
end
|
data/lib/odle.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module Odle
|
5
|
+
# load the parsers
|
6
|
+
Dir[File.join(File.dirname(__FILE__), "parsers", "*.rb")].each { |lib| require lib }
|
7
|
+
|
8
|
+
# load the data model
|
9
|
+
Dir[File.join(File.dirname(__FILE__), "model", "*.rb")].each { |lib| require lib }
|
10
|
+
|
11
|
+
end
|
data/lib/parsers/burp.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
class Burp
|
4
|
+
|
5
|
+
def parse(xml,threshold)
|
6
|
+
vulns = Hash.new
|
7
|
+
findings = Array.new
|
8
|
+
vulns["findings"] = []
|
9
|
+
|
10
|
+
doc = Nokogiri::XML(xml)
|
11
|
+
doc.css('//issues/issue').each do |issue|
|
12
|
+
if issue.css('severity').text
|
13
|
+
# create a temporary finding object
|
14
|
+
finding = Finding.new()
|
15
|
+
finding.title = issue.css('name').text.to_s()
|
16
|
+
finding.overview = issue.css('issueBackground').text.to_s()+issue.css('issueDetail').text.to_s()
|
17
|
+
finding.remediation = issue.css('remediationBackground').text.to_s()
|
18
|
+
|
19
|
+
if issue.css('severity').text == 'Low'
|
20
|
+
finding.risk = 1
|
21
|
+
elsif issue.css('severity').text == 'Medium'
|
22
|
+
finding.risk = 2
|
23
|
+
elsif issue.css('severity').text =='High'
|
24
|
+
finding.risk = 3
|
25
|
+
else
|
26
|
+
finding.risk = 1
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
finding.type = "Web Application"
|
31
|
+
|
32
|
+
findings << finding
|
33
|
+
|
34
|
+
host = issue.css('host').text
|
35
|
+
ip = issue.css('host').attr('ip')
|
36
|
+
id = issue.css('type').text
|
37
|
+
hostname = "#{ip} #{host}"
|
38
|
+
|
39
|
+
finding.affected_hosts = "#{host} (#{ip})"
|
40
|
+
|
41
|
+
finding.id = id
|
42
|
+
if vulns[hostname]
|
43
|
+
vulns[hostname] << finding.to_hash
|
44
|
+
else
|
45
|
+
vulns[hostname] = []
|
46
|
+
vulns[hostname] << finding.to_hash
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
#vulns["findings"] = uniq_findings(findings)
|
52
|
+
return vulns.to_json
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
class Metasploit
|
4
|
+
|
5
|
+
def parse(xml,threshold)
|
6
|
+
vulns = Hash.new
|
7
|
+
vulns["findings"] = []
|
8
|
+
|
9
|
+
doc = Nokogiri::XML(xml)
|
10
|
+
doc.css('//hosts/host').each do |hostnode|
|
11
|
+
findings = Array.new
|
12
|
+
|
13
|
+
host = hostnode.css("/name").text.to_s
|
14
|
+
|
15
|
+
hostnode.css("/vulns/vuln").each do |issue|
|
16
|
+
# create a temporary finding object
|
17
|
+
finding = Finding.new()
|
18
|
+
finding.title = issue.css('name').text.to_s()
|
19
|
+
finding.overview = issue.css('info').text.to_s()
|
20
|
+
findings << finding.to_hash
|
21
|
+
end
|
22
|
+
vulns[host] = findings
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
#vulns["findings"] = uniq_findings(findings)
|
27
|
+
return vulns.to_json
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
class Nessus
|
4
|
+
|
5
|
+
def parse(xml,threshold)
|
6
|
+
vulns = Hash.new
|
7
|
+
findings = Array.new
|
8
|
+
items = Array.new
|
9
|
+
|
10
|
+
doc = Nokogiri::XML(xml)
|
11
|
+
|
12
|
+
doc.css("//ReportHost").each do |hostnode|
|
13
|
+
if (hostnode["name"] != nil)
|
14
|
+
host = hostnode["name"]
|
15
|
+
end
|
16
|
+
hostnode.css("ReportItem").each do |itemnode|
|
17
|
+
if (itemnode["port"].to_s != "0" && itemnode["severity"] >= threshold)
|
18
|
+
|
19
|
+
# create a temporary finding object
|
20
|
+
finding = Finding.new()
|
21
|
+
finding.title = itemnode['pluginName'].to_s()
|
22
|
+
finding.overview = itemnode.css("description").to_s()
|
23
|
+
finding.remediation = itemnode.css("solution").to_s()
|
24
|
+
|
25
|
+
# can this be inherited from an import properly?
|
26
|
+
finding.type = "Imported"
|
27
|
+
finding.risk = itemnode["severity"]
|
28
|
+
finding.affected_hosts = hostnode["name"]
|
29
|
+
if itemnode.css("plugin_output")
|
30
|
+
finding.notes = hostnode["name"]+" ("+itemnode["protocol"]+ " port " + itemnode["port"]+"):"+itemnode.css("plugin_output").to_s()
|
31
|
+
end
|
32
|
+
|
33
|
+
finding.references = itemnode.css("see_also").to_s
|
34
|
+
finding.id = itemnode['pluginID'].to_s()
|
35
|
+
|
36
|
+
vulns[hostname] << finding.to_hash
|
37
|
+
items << itemnode['pluginID'].to_s()
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# vulns[host] = findings
|
42
|
+
items = []
|
43
|
+
end
|
44
|
+
|
45
|
+
return vulns.to_json
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
metadata
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: odle
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Will Vandevanter
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-04-24 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: An easy to use security data parsing tool. Takes in data from different
|
14
|
+
tools and outputs standardized JSON.
|
15
|
+
email: will@silentrobots.com
|
16
|
+
executables:
|
17
|
+
- odle
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- bin/odle
|
22
|
+
- lib/model/data.rb
|
23
|
+
- lib/odle.rb
|
24
|
+
- lib/parsers/burp.rb
|
25
|
+
- lib/parsers/msfv5.rb
|
26
|
+
- lib/parsers/nessus.rb
|
27
|
+
homepage: http://rubygems.org/gems/odle
|
28
|
+
licenses:
|
29
|
+
- BSD-3-Clause-Attribution
|
30
|
+
metadata: {}
|
31
|
+
post_install_message:
|
32
|
+
rdoc_options: []
|
33
|
+
require_paths:
|
34
|
+
- lib
|
35
|
+
- lib/parsers
|
36
|
+
- lib/model
|
37
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
requirements: []
|
48
|
+
rubyforge_project:
|
49
|
+
rubygems_version: 2.6.12
|
50
|
+
signing_key:
|
51
|
+
specification_version: 4
|
52
|
+
summary: odle
|
53
|
+
test_files: []
|