DIY Hacking Toolkit: What is a Shell?
There's no sense in re-inventing the wheel. By analyzing the work of the brilliant minds who came before, we can expand on their efforts to build something that meets our requirements.
Not everyone who calls themselves a hacker understands how the tools they use actually work. Even less of those folks are capable of building their own functional toolkit. This is a recipe for failure. While it's possible to get pretty far using other people's tools, using only tools made by other people ensures you'll never be as good as someone who can build their own. How much more so if you don't take the time to actually understand how those tools really work.
In the interest of helping script kiddies become actual hackers, let's begin the first part of my only actually planned series of blog posts: How to build your own shell.
What is a shell?
A shell is simply an interface between a user and a computer. The shell is what allows a user to execute programs and receive their output, as well as interacting with other system functionality. Typically, when someone says "shell," I think of a classic Unix-style command-line interface. However, the Windows GUI that you may be familiar with is also considered a shell. It's just a graphical shell.
When talking about shells in the context of information security, we're most often talking about a remote shell. A remote shell is simply an interface that allows a user to interact with a computer without actually physically interacting with that computer. Classic benign examples of a remote shell are:
While the most common malicious example of a remote shell is everyone's favorite meterpreter.
Common shell archetypes:
Remote shells all have 3 very important capabilities. These are:
- Receiving commands from a remote user
- Executing the commands on the system
- Sending the result of the command execution to the remote user
While they all have these capabilities, the exact implementation tends to vary. Shells tend to fall into a handful of common archetypes. Understanding these different types of shells ensures we'll always be able to use the right tool for the job in any given situation. While deviations from these archetypes are possible, a grand majority fall into 3 major categories. These are:
Bind shells adhere to a standard client-server model, and were the OG style of shell in a world before firewalls were prevalent. The classic backdoor so often romanticized in the media is often a type of bind shell. The vsFTPd 2.3.4 backdoor is a good example of this. Additionally, SSH, Telnet, and RDP are types of bind shells. The design pattern of a bind shell is distinct from the other primary shell archetypes in the following ways:
- Bind shells bind to a particular network interface and wait for a connection
- An attacker initiates a connection to the shell
- The shell receives the connection, which allows an attacker to execute arbitrary commands
The primary advantage of this style of shell is that it allows an attacker to connect at their leisure, whenever they want, without having to worry about the shell generating tons of network traffic by constantly polling for a connection.
The primary disadvantage of a bind shell is that we live in an age where everything is protected by firewalls. If you're able to load a bind shell onto a target, chances are a firewall or 5 will prevent you from connecting to your shell unless you plan around this.
While bind shells may not be as prevalent today as other types of shells, they're extremely useful under the right circumstances. For example, I recently used a TCP bind shell over TOR with great success during a pentest.
Reverse shells are the type of shell that budding young hackers most often think of when someone mentions a shell. This is because most Metasploit tutorials will have the aspiring script kiddie perform an exploit that leverages payload/linux/x86/meterpreter/reverse_tcp upon successful execution. And that's for a good reason. We'll get to that in a moment. First, let's take a look at how a reverse shell differentiates itself from the others. When using a reverse shell, an attacker will:
- Create a listener bound to an attacker-controlled system that's accessible from the victim machine's network.
- Execute the reverse shell, which will initiate a connection back from the victim machine to the attacker-controlled system.
- The listener receives the connection, which allows the attacker to execute arbitrary commands on the victim machine.
The reverse shell is called a reverse shell because the connection is formed by reversing the traditional client-server model. Instead of the client initiating the connection and the server receiving the connection, the server initiates the connection and the client receives it. This approach has a few advantages over the traditional model.
The single biggest advantage over the bind shell is firewall evasion. Most organizations, even major Fortune 100 companies, don't have proper egress rules set up in their firewalls. This means that most connections are allowed to form from within the organization to any arbitrary external host without much scrutiny. While firewall evasion is a major advantage, there are several disadvantages to using a reverse shell. These are:
- The attacker must first plan ahead and have a publicly accessible system under their control with the appropriate firewall rules in place to allow a compromised host to connect to a listener running on the system.
- The attacker must either sacrifice permanence or stealth to use a bind shell. Either the shell terminates after the connection dies, never to be seen again, or it constantly polls back to the listener trying to re-establish a connection once the initial connection is closed.
- The reverse shell is designed such that it leaks an attacker's information. It requires an address and port to connect to, which can be seen by defenders the network logs, and by any competent reverse engineer who is able to get a hold of the binary or configuration files. This can entirely compromise operational security if it's not accounted for.
Even considering those disadvantages, I most often find myself using a reverse shell after I've compromised a system. My personal preference is a reverse SSH shell that I've been working on, although I do frequently use netcat and bash reverse shells when I'm trying to be fast and sneaky.
While these could technically be considered a type of bind shell, web shells require unique enough circumstances that they deserve a separate mention. Once you've been able to gain arbitrary write access to a web server through any number of vulnerabilities or misconfigurations, the next step to code execution usually involves some form of web shell.
Web shells are:
- Uploaded to an accessible directory on a web server
- Connected to by an attacker
- Typically interacted with via a web browser
While I most often prefer a simple and tiny web stager (more on stagers later), I do have a preferred web shell. When necessary, I like to use p0wny, which is a really well designed single-file PHP web shell.
Now that you've familiarized yourself with what a shell is and how they're commonly designed, we can move on to practical applications of that knowledge. My next blog post will focus on dissecting and analyzing a real, functional shell. The following one will provide some guidance on building your own, with a follow-up series on preparing your shell for deployment and using it in a real-world scenario.