metasploit-runner 0.2.3 → 0.2.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e7e2d2dec14bd740b81ca421a7a055a7532c52dc
4
- data.tar.gz: 82b61166b05fac46c87965cc3bf479305d45e0c7
3
+ metadata.gz: 7c64681c2203eed651d897863f6acd420abed4d9
4
+ data.tar.gz: 68228e2fe22e7bea7358d0a25bfb03aa85bbdf28
5
5
  SHA512:
6
- metadata.gz: aa4689843ef2cd354dd0c735c0ddcf44f4ab2c9e8b249c14e90c0c08f74263dfeb6f821f17be7152138637ed4a6963c238f4b6f6a909c7b02e5e1780718a0ff6
7
- data.tar.gz: e4cd97fa3a0bfcbf178e8c7e4a4e02b2361c54dc5db4359f29d214340bc9b6062a3895f9af29c6c2a8bbab72423ce64cc98f611ba7ba70b785bfb9482ca237c0
6
+ metadata.gz: 773aa5020c5fd2b2b930e42a89df9b633bbed3d908c76510e5bb31f9719c221129bd6d2a3c4af724a29626b8ffcb462045f86babef3c776f02c90cfd300fa214
7
+ data.tar.gz: b5f95158a6bd8a2a7cfed821ce152819b0c788318ce41e26e900d8b8e8432e815e29ece8f75f4fffdf1f582eb5094eb692bb94fff04dafcbcd00e69d0fe8e55e
data/.gitignore CHANGED
@@ -21,5 +21,6 @@ tmp
21
21
  *.a
22
22
  mkmf.log
23
23
  .idea/
24
+ *.iml
24
25
  config/exploit.yml
25
26
  config/explout.yml.bak
data/.travis.yml CHANGED
@@ -1,6 +1,15 @@
1
1
  language: ruby
2
+
2
3
  rvm:
3
4
  - 2.1.2
5
+ - 2.1.5
6
+ - 2.2.0
7
+
8
+ before_install:
9
+ # TODO: Newer versions of rubygems on Travis CI fail on RSpec (see http://stackoverflow.com/a/33800008/4630536). Remove the forced rubygems version when this is fixed.
10
+ - gem update --system 2.4.8
11
+ - gem --version
12
+
4
13
  deploy:
5
14
  provider: rubygems
6
15
  api_key:
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  spec.add_dependency 'msfrpc-client', '1.0.2'
22
22
 
23
- spec.add_development_dependency 'bundler', '~> 1.6'
23
+ spec.add_development_dependency 'bundler'
24
24
  spec.add_development_dependency 'rake'
25
- spec.add_development_dependency 'rspec', '3.0.0'
25
+ spec.add_development_dependency 'rspec'
26
26
  end
data/bin/exploit CHANGED
@@ -3,17 +3,22 @@
3
3
  require 'metasploit/exploit'
4
4
 
5
5
  $stdout.sync = true
6
- Metasploit::Exploit.start({
7
- 'connection_url' => ARGV[0],
8
- 'port' => ARGV[1],
9
- 'uri' => ARGV[2],
10
- 'use_ssl' => ARGV[3],
11
- 'token' => ARGV[4],
12
- 'workspace_name' => ARGV[5],
13
- 'nexpose_console_name' => ARGV[6],
14
- 'device_ip_to_scan' => ARGV[7],
15
- 'use_os_filter' => ARGV[8],
16
- 'module_filter' => ARGV[9],
17
- 'report_type' => ARGV[10],
18
- 'whitelist_hosts' => ARGV[11]
19
- })
6
+
7
+ if ARGV.grep(/^--/).empty?
8
+ Metasploit::Exploit.start({
9
+ 'connection_url' => ARGV[0],
10
+ 'port' => ARGV[1],
11
+ 'uri' => ARGV[2],
12
+ 'use_ssl' => ARGV[3],
13
+ 'token' => ARGV[4],
14
+ 'workspace_name' => ARGV[5],
15
+ 'nexpose_console_name' => ARGV[6],
16
+ 'device_ip_to_scan' => ARGV[7],
17
+ 'use_os_filter' => ARGV[8],
18
+ 'module_filter' => ARGV[9],
19
+ 'report_type' => ARGV[10],
20
+ 'whitelist_hosts' => ARGV[11]
21
+ })
22
+ else
23
+ Metasploit::Exploit.start(ARGV)
24
+ end
@@ -1,3 +1,3 @@
1
1
  module MetasploitPenTestScript
2
- VERSION = "0.2.3"
2
+ VERSION = "0.2.4"
3
3
  end
@@ -0,0 +1,75 @@
1
+ require 'optparse'
2
+
3
+ class CommandLineArgumentParser
4
+ def self.parse(args)
5
+ options = {}
6
+ options['use_ssl'] = false
7
+ options['use_os_filter'] = false
8
+ options['exploit_speed'] = 5
9
+ options['limit_sessions'] = false
10
+ options['port'] = ''
11
+ options['uri'] = ''
12
+
13
+ opt_parser = OptionParser.new do |opts|
14
+ opts.banner = 'Usage: exploit [options]'
15
+
16
+ opts.separator ''
17
+ opts.separator 'Specific options:'
18
+
19
+ opts.on('--port PORT', 'Metasploit port') do |port|
20
+ options['port'] = port
21
+ end
22
+
23
+ opts.on('--connection-url URL', 'Metasploit URL') do |url|
24
+ options['connection_url'] = url
25
+ end
26
+
27
+ opts.on('--use-ssl', 'Use SSL when scanning') do
28
+ options['use_ssl'] = true
29
+ end
30
+
31
+ opts.on('--token TOKEN', 'Access token for Metasploit') do |token|
32
+ options['token'] = token
33
+ end
34
+
35
+ opts.on('--workspace-name NAME', 'Name of workspace') do |workspace|
36
+ options['workspace_name'] = workspace
37
+ end
38
+
39
+ opts.on('--nexpose-console-name NAME', 'Name of Nexpose console') do |console|
40
+ options['nexpose_console_name'] = console
41
+ end
42
+
43
+ opts.on('--device-ip-to-scan IP-ADDRESS', 'IP address of device to scan') do |ip|
44
+ options['device_ip_to_scan'] = ip
45
+ end
46
+
47
+ opts.on('--use-os-filter', 'Use OS filter') do
48
+ options['use_os_filter'] = true
49
+ end
50
+
51
+ opts.on('--module-filter MODULES', 'Comma-separated list of modules to use in scan') do |modules|
52
+ options['module_filter'] = modules
53
+ end
54
+
55
+ opts.on('--report-type TYPE', 'Type of report to generate') do |type|
56
+ options['report_type'] = type.to_sym
57
+ end
58
+
59
+ opts.on('--whitelist-hosts HOSTS', 'IP addresses or CIDR blocks to scan') do |whitelist|
60
+ options['whitelist_hosts'] = whitelist
61
+ end
62
+
63
+ opts.on('--exploit-speed SPEED', 'Exploit speed') do |speed|
64
+ options['exploit_speed'] = speed
65
+ end
66
+
67
+ opts.on('--limit-sessions', 'Limit sessions') do
68
+ options['limit_sessions'] = true
69
+ end
70
+ end
71
+
72
+ opt_parser.parse!(args)
73
+ options
74
+ end
75
+ end
@@ -78,14 +78,15 @@ module Metasploit
78
78
  end
79
79
 
80
80
  def self.do_metasploit_report(rpc_client, run_details)
81
- if run_details.report_type.length > 0
82
- puts "Generating a #{run_details.report_type} Report"
81
+ report_type = run_details.report_type
82
+ if report_type.nil? || report_type.empty?
83
+ puts CONSTANTS::NO_REPORT_TYPE_MESSAGE
84
+ else
85
+ puts "Generating a #{report_type} Report"
83
86
 
84
87
  report = rpc_client.call('pro.start_report', run_details.get_report_options)
85
88
 
86
89
  self.write_report_after_generation(rpc_client, run_details, report['report_id'])
87
- else
88
- puts CONSTANTS::NO_REPORT_TYPE_MESSAGE
89
90
  end
90
91
  end
91
92
 
@@ -1,4 +1,5 @@
1
1
  require 'yaml'
2
+ require 'metasploit/command_line_argument_parser'
2
3
 
3
4
  class ExploitRunDescription
4
5
  attr_accessor :connection_url,
@@ -12,7 +13,9 @@ class ExploitRunDescription
12
13
  :use_os_filter,
13
14
  :module_filter,
14
15
  :report_type,
15
- :whitelist_hosts
16
+ :whitelist_hosts,
17
+ :exploit_speed,
18
+ :limit_sessions
16
19
 
17
20
  @@port_value = ''
18
21
  @@uri_value = ''
@@ -23,7 +26,10 @@ class ExploitRunDescription
23
26
  def initialize(options)
24
27
  if File.file?('config/exploit.yml')
25
28
  options = YAML.load_file('config/exploit.yml')
29
+ elsif options.instance_of? Array
30
+ options = CommandLineArgumentParser.parse(options)
26
31
  end
32
+
27
33
  self.connection_url = options['connection_url']
28
34
  @@port_value = options['port']
29
35
  @@uri_value = options['uri']
@@ -36,6 +42,8 @@ class ExploitRunDescription
36
42
  self.module_filter = options['module_filter']
37
43
  self.report_type = options['report_type']
38
44
  self.whitelist_hosts = options['whitelist_hosts']
45
+ self.exploit_speed = options['exploit_speed'] || 5
46
+ self.limit_sessions = options['limit_sessions'].nil? ? true : options['limit_sessions']
39
47
  end
40
48
 
41
49
  def verify
@@ -74,9 +82,9 @@ class ExploitRunDescription
74
82
  { "workspace" => self.workspace_name,
75
83
  "DS_WHITELIST_HOSTS" => self.whitelist_hosts,
76
84
  "DS_MinimumRank" => "great",
77
- "DS_EXPLOIT_SPEED" => 5,
85
+ "DS_EXPLOIT_SPEED" => self.exploit_speed,
78
86
  "DS_EXPLOIT_TIMEOUT" => 2,
79
- "DS_LimitSessions" => true,
87
+ "DS_LimitSessions" => self.limit_sessions,
80
88
  "DS_MATCH_VULNS" => true,
81
89
  "DS_MATCH_PORTS" => true,
82
90
  "DS_FilterByOS" => self.use_os_filter,
@@ -147,7 +155,7 @@ class ExploitRunDescription
147
155
  end
148
156
 
149
157
  def to_bool(str)
150
- str == 'true'
158
+ str == true || str == 'true'
151
159
  end
152
160
 
153
161
  end
@@ -0,0 +1,106 @@
1
+ require 'metasploit/command_line_argument_parser'
2
+
3
+ describe 'command_line_argument_parser' do
4
+ describe 'parse' do
5
+ before(:each) do
6
+ # noinspection RubyStringKeysInHashInspection
7
+ @expected_arguments = {
8
+ '--connection-url' => 'http://test.connection',
9
+ '--port' => '1234',
10
+ '--token' => 'testtoken',
11
+ '--use-ssl' => nil,
12
+ '--use-os-filter' => nil,
13
+ '--module-filter' => 'exploit/blah1,exploit/blah2',
14
+ '--report-type' => 'fisma',
15
+ '--workspace-name' => 'some-workspace',
16
+ '--nexpose-console-name' => 'some-console',
17
+ '--device-ip-to-scan' => '1.2.3.4',
18
+ '--whitelist-hosts' => '1.2.3.0/24',
19
+ '--exploit-speed' => '200',
20
+ '--limit-sessions' => nil,
21
+ }
22
+
23
+ @command_line_argument_parser = CommandLineArgumentParser.parse(hash_to_array(@expected_arguments))
24
+ end
25
+
26
+ it 'should parse --connection-url' do
27
+ expect(@command_line_argument_parser['connection_url']).to eq(@expected_arguments['--connection-url'])
28
+ end
29
+
30
+ it 'should parse --port' do
31
+ expect(@command_line_argument_parser['port']).to eq(@expected_arguments['--port'])
32
+ end
33
+
34
+ it 'should parse --token' do
35
+ expect(@command_line_argument_parser['token']).to eq(@expected_arguments['--token'])
36
+ end
37
+
38
+ it 'should parse --use-ssl' do
39
+ expect(@command_line_argument_parser['use_ssl']).to eq(true)
40
+ end
41
+
42
+ it 'should pick appropriate default when --use-ssl not present' do
43
+ @expected_arguments.delete '--use-ssl'
44
+ @command_line_argument_parser = CommandLineArgumentParser.parse(hash_to_array(@expected_arguments))
45
+ expect(@command_line_argument_parser['use_ssl']).to eq(false)
46
+ end
47
+
48
+ it 'should parse --use-os-filter' do
49
+ expect(@command_line_argument_parser['use_os_filter']).to eq(true)
50
+ end
51
+
52
+ it 'should pick appropriate default when --use-os-filter not present' do
53
+ @expected_arguments.delete '--use-os-filter'
54
+ @command_line_argument_parser = CommandLineArgumentParser.parse(hash_to_array(@expected_arguments))
55
+ expect(@command_line_argument_parser['use_os_filter']).to eq(false)
56
+ end
57
+
58
+ it 'should parse --module-filter' do
59
+ expect(@command_line_argument_parser['module_filter']).to eq(@expected_arguments['--module-filter'])
60
+ end
61
+
62
+ it 'should parse --report-type' do
63
+ expect(@command_line_argument_parser['report_type']).to eq(@expected_arguments['--report-type'].to_sym)
64
+ end
65
+
66
+ it 'should parse --workspace-name' do
67
+ expect(@command_line_argument_parser['workspace_name']).to eq(@expected_arguments['--workspace-name'])
68
+ end
69
+
70
+ it 'should parse --nexpose-console-name' do
71
+ expect(@command_line_argument_parser['nexpose_console_name']).to eq(@expected_arguments['--nexpose-console-name'])
72
+ end
73
+
74
+ it 'should parse --device-ip-to-scan' do
75
+ expect(@command_line_argument_parser['device_ip_to_scan']).to eq(@expected_arguments['--device-ip-to-scan'])
76
+ end
77
+
78
+ it 'should parse --whitelist-hosts' do
79
+ expect(@command_line_argument_parser['whitelist_hosts']).to eq(@expected_arguments['--whitelist-hosts'])
80
+ end
81
+
82
+ it 'should parse --exploit-speed' do
83
+ expect(@command_line_argument_parser['exploit_speed']).to eq(@expected_arguments['--exploit-speed'])
84
+ end
85
+
86
+ it 'should pick appropriate default when --exploit-speed not present' do
87
+ @expected_arguments.delete '--exploit-speed'
88
+ @command_line_argument_parser = CommandLineArgumentParser.parse(hash_to_array(@expected_arguments))
89
+ expect(@command_line_argument_parser['exploit_speed']).to eq(5)
90
+ end
91
+
92
+ it 'should parse --limit-sessions' do
93
+ expect(@command_line_argument_parser['limit_sessions']).to eq(true)
94
+ end
95
+
96
+ it 'should pick appropriate default when --limit-sessions not present' do
97
+ @expected_arguments.delete '--limit-sessions'
98
+ @command_line_argument_parser = CommandLineArgumentParser.parse(hash_to_array(@expected_arguments))
99
+ expect(@command_line_argument_parser['limit_sessions']).to eq(false)
100
+ end
101
+ end
102
+
103
+ def hash_to_array(hash)
104
+ hash.map { |key, value| [key, value] }.flatten.select { |val| !val.nil? }
105
+ end
106
+ end
@@ -178,6 +178,11 @@ describe 'exploit_run_description' do
178
178
  @exploit_run_description.workspace_name = nil
179
179
  expect { @exploit_run_description.verify }.to raise_error(StandardError, CONSTANTS::REQUIRED_WORKSPACE_MESSAGE)
180
180
  end
181
+
182
+ it 'should handle Array of command-line options' do
183
+ @exploit_run_description = ExploitRunDescription.new %w(--port 12345)
184
+ expect(@exploit_run_description.port).to eq('12345')
185
+ end
181
186
  end
182
187
  end
183
188
 
data/spec/exploit_spec.rb CHANGED
@@ -53,6 +53,22 @@ describe 'exploit' do
53
53
  'report_type' => @expected_report_type,
54
54
  'whitelist_hosts' => @mock_whitelist_hosts
55
55
  }
56
+
57
+ # noinspection RubyStringKeysInHashInspection
58
+ @command_line_arguments = {
59
+ '--connection-url' => 'http://test.connection',
60
+ '--port' => '1234',
61
+ '--token' => 'testtoken',
62
+ '--use-ssl' => nil,
63
+ '--use-os-filter' => nil,
64
+ '--module-filter' => 'exploit/blah1,exploit/blah2',
65
+ '--report-type' => 'fisma',
66
+ '--workspace-name' => 'some-workspace',
67
+ '--nexpose-console-name' => 'some-console',
68
+ '--device-ip-to-scan' => '1.2.3.4',
69
+ '--whitelist-hosts' => '1.2.3.0/24',
70
+ '--exploit-speed' => '200',
71
+ }
56
72
  end
57
73
 
58
74
  describe 'get connection' do
@@ -329,6 +345,17 @@ describe 'exploit' do
329
345
 
330
346
  Metasploit::Exploit.start(@options)
331
347
  end
348
+
349
+ it 'should skip report if report_type not specified' do
350
+ expect(@mock_rpc_client).to_not receive(:call).with('pro.start_report', anything)
351
+
352
+ @options['report_type'] = ''
353
+ @options['report_type'] = nil
354
+ Metasploit::Exploit.start(@options)
355
+
356
+ @command_line_arguments.delete '--report-type'
357
+ Metasploit::Exploit.start(hash_to_array(@command_line_arguments))
358
+ end
332
359
  end
333
360
 
334
361
  describe 'start an audit' do
@@ -530,6 +557,24 @@ describe 'exploit' do
530
557
  Metasploit::Exploit.start(options)
531
558
  end
532
559
 
560
+ it 'should set configuration properties based on command-line arguments' do
561
+ expect(@mock_rpc_client).to receive(:call)
562
+ .with('pro.start_exploit', {
563
+ "workspace" => @command_line_arguments['--workspace-name'],
564
+ "DS_WHITELIST_HOSTS" => @command_line_arguments['--whitelist-hosts'],
565
+ "DS_MinimumRank" => 'great',
566
+ "DS_EXPLOIT_SPEED" => @command_line_arguments['--exploit-speed'],
567
+ "DS_EXPLOIT_TIMEOUT" => 2,
568
+ "DS_LimitSessions" => false,
569
+ "DS_MATCH_VULNS" => true,
570
+ "DS_MATCH_PORTS" => true,
571
+ "DS_FilterByOS" => true,
572
+ "DS_ModuleFilter" => @command_line_arguments['--module-filter']
573
+ })
574
+
575
+ Metasploit::Exploit.start(hash_to_array(@command_line_arguments))
576
+ end
577
+
533
578
  describe 'wait for exploit to be over' do
534
579
  before(:each) do
535
580
 
@@ -647,3 +692,7 @@ def get_mock_rpc_client
647
692
 
648
693
  mock_rpc_client
649
694
  end
695
+
696
+ def hash_to_array(hash)
697
+ hash.map { |key, value| [key, value] }.flatten.select { |val| !val.nil? }
698
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metasploit-runner
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathan Gibson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-04 00:00:00.000000000 Z
11
+ date: 2016-01-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: msfrpc-client
@@ -28,16 +28,16 @@ dependencies:
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '1.6'
33
+ version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '1.6'
40
+ version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -56,16 +56,16 @@ dependencies:
56
56
  name: rspec
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - '='
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: 3.0.0
61
+ version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - '='
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: 3.0.0
68
+ version: '0'
69
69
  description: ''
70
70
  email:
71
71
  - amngibson@gmail.com
@@ -86,9 +86,11 @@ files:
86
86
  - config/exploit.yml.example
87
87
  - lib/MetasploitPenTestScript.rb
88
88
  - lib/MetasploitPenTestScript/version.rb
89
+ - lib/metasploit/command_line_argument_parser.rb
89
90
  - lib/metasploit/constants.rb
90
91
  - lib/metasploit/exploit.rb
91
92
  - lib/metasploit/exploit_run_description.rb
93
+ - spec/command_line_argument_parser_spec.rb
92
94
  - spec/exploit_config_spec.rb
93
95
  - spec/exploit_run_description_spec.rb
94
96
  - spec/exploit_spec.rb
@@ -118,6 +120,7 @@ signing_key:
118
120
  specification_version: 4
119
121
  summary: Script to run automated Metaspolit Penetration Tests.
120
122
  test_files:
123
+ - spec/command_line_argument_parser_spec.rb
121
124
  - spec/exploit_config_spec.rb
122
125
  - spec/exploit_run_description_spec.rb
123
126
  - spec/exploit_spec.rb