metasploit-runner 0.2.3 → 0.2.4

Sign up to get free protection for your applications and to get access to all the features.
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