dradis-coreimpact 4.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,19 @@
1
+ module Dradis
2
+ module Plugins
3
+ module Coreimpact
4
+ # Returns the version of the currently loaded Dradis as a <tt>Gem::Version</tt>
5
+ def self.gem_version
6
+ Gem::Version.new VERSION::STRING
7
+ end
8
+
9
+ module VERSION
10
+ MAJOR = 4
11
+ MINOR = 5
12
+ TINY = 0
13
+ PRE = nil
14
+
15
+ STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,112 @@
1
+ module Dradis::Plugins::Coreimpact
2
+ class Importer < Dradis::Plugins::Upload::Importer
3
+ # The framework will call this function if the user selects this plugin from
4
+ # the dropdown list and uploads a file.
5
+ # @returns true if the operation was successful, false otherwise
6
+ def import(params={})
7
+
8
+ file_content = File.read( params[:file] )
9
+
10
+ # Parse the uploaded file XML
11
+ logger.info { "Parsing CORE Impact output file... #{params[:file]}" }
12
+ @doc = Nokogiri::XML( file_content )
13
+ logger.info { 'Done.' }
14
+
15
+ if @doc.xpath('/entities').empty?
16
+ logger.error "ERROR: no '<entities>' root element present in the provided "\
17
+ "data. Are you sure you uploaded a CORE Impact file?"
18
+ return false
19
+ end
20
+
21
+ @doc.xpath('/entities/entity[@class="host"]').each do |xml_entity|
22
+ add_host(xml_entity)
23
+ end
24
+ end
25
+
26
+ private
27
+ def add_host(xml_entity)
28
+ label = xml_entity.at_xpath('./property[@key="display_name"]').text
29
+ node = content_service.create_node(label: label, type: :host)
30
+
31
+ logger.info{ "\tNew Host: #{label}" }
32
+
33
+ node.set_property(:ip, xml_entity.at_xpath('./property[@key="ip"]').text)
34
+ node.set_property(:os, xml_entity.at_xpath('./property[@type="os"]/property[@key="entity name"]').text)
35
+
36
+ # port and service info
37
+ add_ports(xml_entity, node)
38
+ add_services(xml_entity, node)
39
+
40
+ # vulns and exposures
41
+ xml_entity.xpath('.//property[@key="Vulnerabilities"]').each do |xml_container|
42
+ add_vulnerability(xml_container, node)
43
+ end
44
+ end
45
+
46
+ def add_ports(xml_entity, node)
47
+ xml_entity.xpath('./property[@type="ports"]').each do |xml_ports|
48
+ protocol = xml_ports['key'].split('_').first
49
+
50
+ xml_ports.xpath('./property[@type="port"]').each do |xml_port|
51
+
52
+ logger.info{ "\t\tNew Port: #{protocol}/#{xml_port['key']}"}
53
+
54
+ node.set_service(
55
+ port: xml_port['key'],
56
+ protocol: protocol,
57
+ source: :coreimpact,
58
+ state: (xml_port.text == 'listen') ? :open : xml_port.text
59
+ )
60
+ end
61
+ end
62
+
63
+ # Save node properties
64
+ node.save
65
+ end
66
+
67
+ def add_services(xml_entity, node)
68
+ xml_entity.xpath('./property[@key="services"]').each do |xml_services|
69
+
70
+ xml_services.xpath('./property').each do |xml_container|
71
+
72
+ name = xml_container['key']
73
+
74
+ # Each service container can have multiple ports/protocols.
75
+ xml_container.xpath('./property').each do |xml_service|
76
+
77
+ port, protocol = xml_service['key'].split('-')
78
+
79
+ logger.info{ "\t\tNew Service: #{protocol}/#{port} - #{name}"}
80
+
81
+ node.set_service(
82
+ name: name,
83
+ port: port,
84
+ protocol: protocol,
85
+ source: :coreimpact
86
+ )
87
+ end
88
+ end
89
+ end
90
+ # Save node properties
91
+ node.save
92
+ end
93
+
94
+ def add_vulnerability(xml_container, node)
95
+ plugin_id = xml_container.at_xpath('./property[@type="container"]')['key']
96
+
97
+ issue_text = template_service.process_template(data: xml_container, template: 'issue')
98
+ issue = content_service.create_issue(id: plugin_id, text: issue_text)
99
+ logger.info{ "\tCreating new issue (plugin_id: #{plugin_id})"}
100
+
101
+ evidence_content = template_service.process_template(
102
+ data: xml_container.at_xpath('./property[@type="container"]/property[@key="Modules"]'),
103
+ template: 'evidence'
104
+ )
105
+ content_service.create_evidence(content: evidence_content, issue: issue, node: node)
106
+ logger.info{ "\t\tAdding reference to this host"}
107
+
108
+
109
+
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,13 @@
1
+ require_relative 'gem_version'
2
+
3
+ module Dradis
4
+ module Plugins
5
+ module Coreimpact
6
+ # Returns the version of the currently loaded CORE Impact as a
7
+ # <tt>Gem::Version</tt>.
8
+ def self.version
9
+ gem_version
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,11 @@
1
+ module Dradis
2
+ module Plugins
3
+ module Coreimpact
4
+ end
5
+ end
6
+ end
7
+
8
+ require 'dradis/plugins/coreimpact/engine'
9
+ require 'dradis/plugins/coreimpact/field_processor'
10
+ require 'dradis/plugins/coreimpact/importer'
11
+ require 'dradis/plugins/coreimpact/version'
@@ -0,0 +1,9 @@
1
+ # Hook to the framework base clases
2
+ require 'dradis-plugins'
3
+
4
+ # Load this add-on's engine
5
+ require 'dradis/plugins/coreimpact'
6
+
7
+ # Require supporting CORE Impact library
8
+ require 'coreimpact/module'
9
+ require 'coreimpact/vulnerability'
@@ -0,0 +1,22 @@
1
+ class CoreimpactTasks < Thor
2
+ include Rails.application.config.dradis.thor_helper_module
3
+
4
+ namespace "dradis:plugins:coreimpact"
5
+
6
+ desc "upload FILE", "upload CORE Impact results in XML format"
7
+ long_desc "This plugin expect a XML file generated by CORE Impact"
8
+ def upload(file_path)
9
+ require 'config/environment'
10
+
11
+ unless File.exists?(file_path)
12
+ $stderr.puts "** the file [#{file_path}] does not exist"
13
+ exit(-1)
14
+ end
15
+
16
+ detect_and_set_project_scope
17
+
18
+ importer = Dradis::Plugins::Coreimpact::Importer.new(task_options)
19
+ importer.import(file: file_path)
20
+ end
21
+
22
+ end
@@ -0,0 +1,88 @@
1
+ require 'spec_helper'
2
+
3
+ module Dradis::Plugins
4
+ describe 'Qualys upload plugin' do
5
+ let(:xml) { 'spec/fixtures/files/example.xml' }
6
+
7
+ before(:each) do
8
+ # Stub template service
9
+ templates_dir = File.expand_path('../../../templates', __FILE__)
10
+ expect_any_instance_of(Dradis::Plugins::TemplateService)
11
+ .to receive(:default_templates_dir).and_return(templates_dir)
12
+
13
+ plugin = Dradis::Plugins::Coreimpact
14
+
15
+ @content_service = Dradis::Plugins::ContentService::Base.new(
16
+ logger: Logger.new(STDOUT),
17
+ plugin: plugin
18
+ )
19
+
20
+ @importer = Dradis::Plugins::Coreimpact::Importer.new(
21
+ content_service: @content_service
22
+ )
23
+
24
+ # Stub dradis-plugins methods
25
+ #
26
+ # They return their argument hashes as objects mimicking
27
+ # Nodes, Issues, etc
28
+ allow(@content_service).to receive(:create_node) do |args|
29
+ obj = OpenStruct.new(args)
30
+ obj.define_singleton_method(:set_property) { |*| }
31
+ obj.define_singleton_method(:set_service) { |*| }
32
+ obj
33
+ end
34
+ allow(@content_service).to receive(:create_issue) do |args|
35
+ OpenStruct.new(args)
36
+ end
37
+ allow(@content_service).to receive(:create_evidence) do |args|
38
+ OpenStruct.new(args)
39
+ end
40
+ end
41
+
42
+ it 'creates nodes' do
43
+ expect(@content_service).to receive(:create_node).with(
44
+ hash_including(label: '10.0.10.41')
45
+ ).once
46
+
47
+ expect(@content_service).to receive(:create_node).with(
48
+ hash_including(label: '10.0.10.53')
49
+ ).once
50
+
51
+ @importer.import(file: xml)
52
+ end
53
+
54
+ it 'creates issues' do
55
+ expect(@content_service).to receive(:create_issue) do |args|
56
+ expect(args[:text]).to include 'OpenSSL ChangeCipherSpec Message Vulnerability Checker'
57
+ expect(args[:text]).to include 'CVE-2014-0224'
58
+ expect(args[:text]).to include 'OpenSSL before 0.9.8za, 1.0.0 before 1.0.0m, and 1.0.1 before 1.0.1h does not properly restrict processing of ChangeCipherSpec messages'
59
+ OpenStruct.new(args)
60
+ end.once
61
+
62
+ expect(@content_service).to receive(:create_issue) do |args|
63
+ expect(args[:text]).to include 'SNMP Identity Verifier'
64
+ expect(args[:text]).to include 'CVE-1999-0516'
65
+ expect(args[:text]).to include 'An SNMP community name is guessable.'
66
+ OpenStruct.new(args)
67
+ end.once
68
+
69
+ @importer.import(file: xml)
70
+ end
71
+
72
+ it 'creates evidence' do
73
+ expect(@content_service).to receive(:create_evidence) do |args|
74
+ expect(args[:content]).to include "#[AgentDeployed]#\nfalse\n\n#[TriedToInstallAgent]#\nfalse\n\n#[Port]#\n443\n"
75
+ expect(args[:issue].text).to include 'OpenSSL ChangeCipherSpec Message Vulnerability Checker'
76
+ expect(args[:node].label).to eq '10.0.10.41'
77
+ end.once
78
+
79
+ expect(@content_service).to receive(:create_evidence) do |args|
80
+ expect(args[:content]).to include "#[AgentDeployed]#\nfalse\n\n#[TriedToInstallAgent]#\nfalse\n\n#[Port]#\n161\n"
81
+ expect(args[:issue].text).to include 'SNMP Identity Verifier'
82
+ expect(args[:node].label).to eq '10.0.10.53'
83
+ end.once
84
+
85
+ @importer.import(file: xml)
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Coreimpact plugin' do
4
+ pending 'describe the behaviour of the Coreimpact plugin'
5
+ end