Recently a friend of mine asked me “what is a shell access?”. And because the answer is not simple and because a well-versed computer user should understand how things work, I decided to write
it down in this article.
I’m a firm believer that people should understand how the things that they use work, so before explaining what is a shell I first have to explain what is a
program and what is a
When you open want to play some music on your computer (or smartphone) you need to first get the program that can play the music (or the computer comes with the program pre-installed).
The program is basically just a bunch of files. At least one of them has to be executable. In the world of MS Windows, the executable has the file extension .exe. The executable contains the instructions on how to perform some actions, such as opening a song or displaying the text. Because some actions are common for various programs, the particular code for those common functions is often moved into a separate file – a library. In the world of MS Windows, the library has file extension .dll. In the world of Linux and various Unix-like systems, it has the name starting with
lib and ending with .so. So the program is in fact usually made of one executable and several libraries. And very likely some other program uses some of those libraries that are used also by the first program. There can be also some other files used by the program but they are not relevant at this moment.
When you start the program, the operating system (OS) creates a process. That means that it loads the content of the executable and the corresponding libraries into the memory. Current operating systems are multiprocessing and that means that there can be multiple programs loaded in the memory at the same time. In order to keep track of them, the OS maintains a process table. So when you start the program and create a new process, the OS also creates a new entry in the process table and writes down some information about the process in that entry. And next time someone the CPU gets bored because no other program needs to do something, it looks at our process and lets it execute a few instructions. Or many. That depends on the system load and nature of the program and the problem of which process gets to do something is a science of itself. The important thing is that when I start the same program again (while the first process runs) then a new process is created. So I can have one program but it can be loaded in the memory multiple times and each instance is a process that runs independently of the rest.
Before the programs became the thing that you see most these days, they very often just accepted some text as input and produced some text as output. This paradigm was not replaced with GUI. GUI was added as a cream on the top, but many programs still use the basic text as input and output. Even if the user often does not see that. The programmers have a special name for that – the feature that allows the program to accept input is called
stdin – standard input, and conversely the feature that allows the program to write the text out is called
stdout – standard output.
The information where the text comes from into the stdin and where it goes out of stdout is part of the process entry in the process table.
So what about shell?
Well, the shell is a program with the purpose of starting other programs. In traditional Unix world, it was indeed called
shell or (because IT guys are lazy)
sh. In fact, there are multiple programs with the same purpose such as bash, csh, tcsh, KSH, etc. etc.
In MS Windows, it is usually not called a shell, but a
Command Prompt and the program that implements it is called
cmd.exe. It is rather limited compared to Unix/Linux shells and somewhere around Windows 7 Microsoft saw the light and created
PowerShell. Based on the definition that shall is intended to start other programs, we can also the Windows Start menu and icons on the desktop consider being a shell, although this one tells the started processes that their stdin and stdout are null.
Hm, okay, so what’s interesting about shell?
Well, we can meet the shell at various places. If you are logging in into the computer, you provide your username and password to a login program. The login program, after verifying your credentials, starts a shell and connects it to your keyboard and display. And shell allows you to start other programs – for browsing web, reading mail, writing documents, playing music, … . It can also be configured to automatically start a desktop environment. On Linux, that would be probably Gnome, or KDE or one of many other options.
If you ssh into another system over the network, we, in fact, run a program that creates a connection to the remote system, the sshd on the remote system starts a shell and connects its stdin/stdout to the network connection. So whatever we write into the network connection (such as
please start program XY) receives the shell on the remote system on stdin and whatever the remote shell writes to stdout (such as
do you want to start anything? will be sent over the network connection back to you. Since shell can start other programs, it can also tell them to sort of connect the stdin/stdout of the started program to the network connection to. The end effect is that you interacting with remote system is no different to interacting with local system – as long as we deal only with programs processing stdin/stdout (with graphical programs it’s a bit more complex)
Another thing interesting about shell is that it may not get the commands to run only from stdin. It can get them from a file too. In such case, the file is called a
If you are on Windows and you never heard about ssh before, then you may try Putty. If you are patient you can wait until Microsoft indeed implements ssh functionality in PowerShell as promised in summer of 2015. And if you are still in last millennium or you are not concerned about security then you can replace ssh with Telnet.
But we are on a security focused site, so what it has to do with security
Well, do you remember as I said that some common functionality is often moved into a library? What you can find in the most common library is also a function for starting other programs (btw, that is the same function that the shell uses too) or writing and reading files. And the very same library is used also by other programs – for example, a web server. Or any other kind of network service for that matter. So if you grok the paragraph about processes, then you understand that the code loaded into the memory of the web server process contains also code for starting other processes and code for manipulating files. That code may never be actually used by that process, but nevertheless, it is loaded in memory. And the thing where the security aspect comes is: what happens when the network service contains a bug and the attacker can exploit the bug and convince the network service process to execute the function for starting other processes and ask it to start the shell? That’s the attacker’s wet dream because if he can do that, he gets
shell access – it is almost the same as if he connected to the system over ssh.
Note that a network service is just an example. A similar situation can happen if the attacker already has local access (perhaps he has a normal user account) but exploits a bug in some other program that is running on the system.
So how bad is it, if the attacker gets a shell?
As usual, the answer is: that depends on. On one hand, if the network service runs as user Alice, then the shell started as a sub-process of the network service will also be able to do anything the Alice can with a shell. That is because one of the main roles of the operating system is to handle separation of users and processes so that processes from user Alice do not step on toes of processes of user Bob. So the privileges of Alice’s processes are limited to resources that Alice can access. Each operating system has an account with high privileges. In Unix/Linux that is root. In windows,
it is Administrator and/or SYSTEM. A good practice is that the services run under their own account and, in the case of breach, the attacker gains only the rights of the user running the service – which can be severely limited.But once you get a shell access – what can you do? Apart from starting other processes shell can also do many other things. Especially if we talk about Linux/Unix systems or PowerShell on Windows. The shell recognizes a number of internal commands. On Windows the command
del can delete a file and is an internal command of the shell – the shell does not start a
del process to delete the file. In Unix/Linux to delete a file, you need to call an external command
rm. In fact in the Unix/The world , it is very common that many actions are implemented as external commands that can be combined in various ways. It also contains tons of internal commands which form a fully functional programming language with variables, arithmetic, conditionals, loops, functions and in some cases even networking functionality. All that makes it a very powerful tool.
How does the shell work
The documentation for a shell can be quite big – have a look at the bash for example. But there are some generic principles that I can cram into this space. The shell maintains a list of variables.
Each variable holds a value and each process gets a list of variables from its parent process. So if a process is started from a shell, then it inherits these so-called environment variables from the shell.
The bash can start:
- internal commands
- external commands – programs specified with a path to the executable. The path can be absolute or relative to current directory
- programs that can be found in a directory listed in the environment variable PATH
- on Windows, the rules are a bit more
After starting the process, the shell usually waits until the process exits and then it can run another command. The shell can also arrange a
pipeline – a sequence of programs where stdout of the first process is connected (piped) to stdin of next process. This construct can be repeated multiple times and allows to perform a number of operations on the output of the first process. This philosophy dates back to first Unix systems and the power of this is multiplied by the number of programs available on the Unix-like systems. There are programs to find text in files, filter the text, edit it and manipulate in various ways … you can find files, copy them to another place or over the network, compress them, delete, compute checksums, compare files, encrypt them, … . There are programs to verify and manipulate system configuration, network settings, security settings and access controls, programs to examine hardware, … programs to play music, display and manipulate images, PDF files, development tools such as compilers, debuggers, source control systems and database tools … Depending on the system there can be hundreds of programs that are at your disposal.
So hopefully I managed to explain at least partially why the shell is interesting and why it is so powerful. While the possibilities are enormous, you don’t have to master them all. But the more you know, the more power it gives you. So I encourage you to learn powers of your shell because it will make empower you.