Skip to content

Shells

Most of the time when you are performing a security audit, you will be working with a remote machine. This means that you will need some method of connecting to this machine and issuing commands. Additionally, while you may be able to get an exploit with full GUI capabilities, many start with a simple remote shell (often a restricted one) before we can solidify the exploit.

This article introduces the concepts of shells, both local and remote. Here you will learn what they are and how they allow us to interact with the underlying operating system.

What is a Shell?

We usually interact with computers via the Operating System (OS), this is a collection of software that translates our actions into the machine code that the hardware understands. While the main players in the OS world have differing philosophy's in how to achieve this goal, the aim is sill to allow the user as painless interaction as possible.

The central part of an operating system is the Kernel, a set of software commands that interact with the various hardware components. This is an Application Programming Interface (API) that provides the core functionality of the system; for example, file handling, memory management, and Input/Output operations. To save us having to interact with the API, the shell then provides a set of utilities that call the kernel commands.

There are differing levels of shell, from the fully integrated GUI found on windows system, to the more layered approach taken by Linux, where the user has some control over what elements of the shell they want to use (which kernel, which supporting programs and even which GUI).

We are going to focus on Command Line Interface (CLI) shells (sometimes called terminal-based shells). The majority of exploits start with a shell environment. This provides the initial 'toehold' on a system that allows us to dig deeper, and strengthen our grip on the system. Being comfortable with the command line is vital for an ethical hacker.

Common Shells: Linux

As usual, Linux systems have a range of shells available. Each 'flavour' of shell offers broadly the same functionality, with changes centred around the ease of their use. However, to avoid surprises, it is worth checking the shells available on a system. You can also see the current shell by examining the environment variables, using the echo $SHELL command. For example, the output of the command below shows that I like to use z-shell:

$echo $SHELL
/usr/bin/zsh

Common shells include you will encounter on Linux systems include:

Bourne Shell (/bin/sh):
This is the POSIX (Portable Operating System Interface) standard shell, and should be available on all Linux systems. As such it is the shell you are most likely to be dropped into, following an exploit.
Bourne Again (Bash) Shell (/bin/bash)
A common shell found on Linux systems. It offers more functionality than the Bourne shell, including tab completion and other workflow optimisations.
Debian Almquist Shell (Dash)
This is a modern interpretation of the Bourne shell this is commonly found on Debian-based systems (where it replaces Bash).

A note on restricted shells

There are also restricted versions of bash and sh (rbash and rsh respectively) which provide an extra level of security to the system. Generally, restricted shells limit the commands that can be executed.

For example: stopping any command with a "/" at the start of it; not allowing the user to change directory; or providing a subset of the system commands that can be run.

Depending on how well the restricted shell is configured we may be able to 'break out' of the restricted version and gain a fully-featured shell. As usual with many hacking topics, reconnaissance is key here. Understanding the restrictions the shell places on us, and the programs available on the system is vitally important.

Shell escapes have a lot in common with privilege escalation, We will look at some techniques for this later in the module

Common shells: Windows

Windows has two common command line interfaces.

CMD.exe
the traditional command line
PowerShell
an improved version of the command line which offers more Linux-like features and gives us a lot of scope for scripting

Remote Shells

Shells allow us to interact with the operating system using the terminal. However, for remote systems, we will also need a method of connecting to the shell. There are many ways of getting a remote shell connection, such as Telnet or SSH (Secure Shell), which we will discuss more in a future article.

Connections over a remote shell generally act like those through a terminal window, with the same functionality implemented. However, there are exceptions. In many cases our exploit will give us a 'limited' remote shell with reduced functionality (including things like deleting characters). While limited, these shells give us the initial toehold on a system we need to get a fully functional shell working.

When it comes to remote shell connections, there are two methods of connecting that we need to be aware of; bind shells and reverse shells.

Bind Shells

Bind shells function in the same way as most traditional Client - Server programs. A service that offers the shell is started on the target machine that waits for an incoming connection. This is the approach that things like SSH take, where a daemon process listens for connections on a given port.

Bind Shell

The attacker then connects to the target using the service, and uses the shell.

Reverse Shells

A reverse shell works in the opposite way. The attacker starts a service on their computer which listens for a connection. They then start a shell process on the target machine that connects to them.

Reverse Shell

In Summary

In this article we have introduced the topic of remote shells, and discussed the most common types of shell you will encounter.

In the next set of articles we will examine some of these shells in detail, and discuss methods of getting a shell on a remote system.


Further reading

Back to top