Loading...
Home
Explore
Contact
Sign in
Emergency Fixes & Security

Trace and Remove Linux Malware Backdoors and Hidden Root Users

Find hidden cron loops, rogue accounts, and web-user backdoors on Ubuntu/Linux servers. Practical SSH diagnostics, cleanup steps, and when Australian site owners should book Fixwebnode remote support.

Fixwebnode Support
Fixwebnode Support
10 min read 23 views
Trace and Remove Linux Malware Backdoors and Hidden Root Users

If your Linux server keeps re-infecting after you delete suspicious files, you are usually fighting persistence—not a one-off script. This guide walks Australian small-business owners and self-managed VPS operators through tracing malware backdoors, hidden root-equivalent users, and cron loops that reinstall payloads under pressure. You will SSH in, inspect system accounts and schedulers (including sudo crontab -u www-data -l), remove unauthorized access, and verify the box stays clean.

Work assumes a typical Ubuntu or Debian-style VPS with SSH access and sudo. Take a snapshot or offline backup before you change accounts or delete files. For remote server support focused on this exact problem in Australia, Fixwebnode provides direct specialist help via Ubuntu Linux server support and bug fixing—not a freelance marketplace.

Why tracing backdoors and hidden root users matters

Malware on web servers rarely stops at a single PHP dropper. Attackers add unauthorized users, SSH keys, reverse shells, and cron or systemd timers that restore the payload after you clean the document root. If you only delete files under /var/www, the scheduler or a hidden account brings them back within minutes.

Under incident pressure the goal is ordered diagnosis: lock down new logins where safe, inventory users and privileged groups, list every cron source (root, www-data, system crontabs), find unexpected listeners and processes, then remove persistence and rotate credentials. Skipping the scheduler check is the most common reason “cleaned” Australian e-commerce and brochure sites light up again overnight.

How do I find a hidden cron that keeps re-infecting my Linux site in Australia?

SSH to the server as a sudo-capable user, then list crontabs for root and the web user—especially sudo crontab -u www-data -l—and read /etc/cron.* plus user crontabs under /var/spool/cron/crontabs. Suspicious curl/wget pipes, base64 one-liners, or scripts writing into the web root are classic re-infection loops; remove those entries, delete the payload files, and re-check after a few minutes.

SymptomQuick checkCall Fixwebnode when
Malware files return after deletecrontab -u www-data -l and system cron dirsEntries rewrite themselves or rootkit hides files
Unknown sudo/root-like userCompare /etc/passwd, shadow, group membershipYou cannot safely remove the account without lockout
Odd outbound SSH or high CPU at nightss, ps, auth logs, authorized_keysActive reverse shell or unknown kernel modules

Common issues when hunting Linux backdoors

1. Hidden cron persistence under www-data or root

Symptoms: cleaned PHP/JS files reappear; curl/wget spikes in logs; short-lived processes owned by www-data; site redirects return after cache purge.

2. Unauthorized system accounts or UID 0 clones

Symptoms: extra users in /etc/passwd, unexpected members of sudo or adm, login success lines for accounts you never created, or a second user with UID 0.

3. SSH authorized_keys and web-shell backdoors

Symptoms: logins from unfamiliar IPs without password prompts, new keys in ~/.ssh/authorized_keys for root or deploy users, or eval/base64 loaders in theme/plugin files that spawn shells.

4. Systemd timers or rc scripts reinstalling malware

Symptoms: cron looks clean but infection returns on reboot; unknown .service/.timer units; modified /etc/rc.local or profile scripts calling remote payloads.

Issue 1 — Diagnose and break hidden cron persistence loops

Attackers love the web user because it already writes to the site. Always inspect that crontab explicitly.

Step 1 — Get a shell and freeze reckless changes

Connect with your normal admin key (prefer key-only SSH). If the host is actively serving malware to visitors, put the site in maintenance or restrict HTTP at the firewall after you have console/SSH access secured.

ssh -i ~/.ssh/your_admin_key you@your-server-ip
sudo -id
whoami
hostnamectl

Step 2 — List every user and system crontab

sudo crontab -l
sudo crontab -u www-data -l
sudo crontab -u nginx -l 2>/dev/null
sudo crontab -u apache -l 2>/dev/null
ls -la /var/spool/cron/crontabs/
sudo ls -la /etc/cron.d/ /etc/cron.hourly/ /etc/cron.daily/ /etc/cron.weekly/
grep -RniE 'curl|wget|base64|python|perl|/dev/tcp|bash -i' /etc/cron.* /var/spool/cron/crontabs/ 2>/dev/null

Anything that downloads remote code, decodes blobs, or writes under /var/www, /tmp, or /dev/shm is suspect. Note the full command line before deleting.

Step 3 — Remove the bad schedule and the dropper file

sudo crontab -u www-data -e
# delete the malicious lines, save, then verify:
sudo crontab -u www-data -l
sudo rm -f /tmp/.x /var/tmp/.update /dev/shm/.cache 2>/dev/null
# replace paths with what you actually found
sudo find /var/www -type f \( -name '*.php' -o -name '*.phtml' \) -mtime -3 -ls

Step 4 — Watch for re-creation

sudo journalctl -u cron -f
# or on systems using cron logs:
sudo tail -f /var/log/syslog | grep -i cron
sleep 120
sudo crontab -u www-data -l

If the line returns without you editing it, another process (malware binary, systemd unit, or a second account) is rewriting crontab—continue to Issues 2–4 rather than looping file deletes.

When to call Fixwebnode: the crontab rewrites itself, you lack a clean backup of legitimate jobs, or the host shows signs of a rootkit hiding files. Remote incident cleanup is available through the same Linux server support path used across Australia.

Issue 2 — Find and remove unauthorized system accounts and hidden root users

Hidden “root” often means a second UID 0 account or a normal-looking user dropped into the sudo group.

Step 1 — Inventory accounts and privilege

getent passwd | awk -F: '$3==0 {print}'
getent passwd | awk -F: '$3>=1000 {print}'
getent group sudo wheel adm
sudo awk -F: '($2=="" || $2!~/^\$/){print $1" EMPTY_OR_SUSPECT_HASH"}' /etc/shadow
sudo lastlog | head -50
sudo grep -E 'Accepted|Invalid user|sudo:' /var/log/auth.log | tail -n 80

Expected: only root with UID 0 (unless you intentionally use a locked root and a single admin). Flag unknown human users, empty passwords, and sudden sudoers.

Step 2 — Inspect sudoers drop-ins

sudo ls -la /etc/sudoers.d/
sudo grep -RniE 'ALL|NOPASSWD' /etc/sudoers /etc/sudoers.d/
sudo visudo -c

Step 3 — Disable then remove the rogue account safely

# lock password and expire the account first
sudo usermod -L -e 1 baduser
sudo passwd -l baduser
sudo gpasswd -d baduser sudo 2>/dev/null
sudo rm -f /etc/sudoers.d/*baduser* 2>/dev/null
# kill lingering sessions
sudo pkill -u baduser
sudo deluser --remove-home baduser
# if UID 0 clone named oddly:
getent passwd | awk -F: '$3==0'

Do not delete your only working admin user. If the only SSH-capable account is compromised, use provider console/recovery mode before locking yourself out.

Step 4 — Verify

getent passwd | awk -F: '$3==0 {print}'
getent group sudo
sudo grep baduser /etc/passwd /etc/shadow /etc/group 2>/dev/null || echo "baduser gone"

When to call Fixwebnode: multiple UID 0 entries you did not create, broken sudoers syntax, or uncertainty which account is legitimate on a production host used by a team.

Issue 3 — Clear SSH key backdoors and web shells

Persistence often sits next to legitimate deploy keys.

Step 1 — Audit authorized_keys for root and service users

sudo find /root /home /var/www -name authorized_keys -type f 2>/dev/null -ls
for f in $(sudo find /root /home -name authorized_keys 2>/dev/null); do
 echo "==== $f"
 sudo cat "$f"
done

Remove unknown key lines; keep only keys you control. Rotate any key that may have leaked.

Step 2 — Harden sshd after cleanup

sudo grep -E '^(PermitRootLogin|PasswordAuthentication|PubkeyAuthentication)' /etc/ssh/sshd_config /etc/ssh/sshd_config.d/* 2>/dev/null
# typical hardened values after you confirm key login works:
# PermitRootLogin no
# PasswordAuthentication no
sudo sshd -t && sudo systemctl reload sshd || sudo systemctl reload ssh

Step 3 — Hunt common web shells while the cron loop is dead

sudo grep -RniE 'eval\s*\(|base64_decode\s*\(|gzinflate\s*\(|shell_exec\s*\(|passthru\s*\(|assert\s*\(' /var/www --include='*.php' 2>/dev/null | head -n 100
sudo find /var/www -type f -name '*.php' -perm -o+w -ls
sudo find /tmp /var/tmp /dev/shm -type f -ls

Compare hits against a known-good release or git checkout. Delete only confirmed foreign files; restore CMS core from vendor packages when unsure.

Step 4 — Restart PHP and web services cleanly

sudo systemctl restart php8.3-fpm 2>/dev/null || sudo systemctl restart php8.2-fpm 2>/dev/null || sudo systemctl restart php-fpm
sudo systemctl restart nginx 2>/dev/null || sudo systemctl restart apache2
sudo systemctl --failed

When to call Fixwebnode: shells are woven through custom application code, or you need a full credential rotation (DB, CMS salts, API tokens, panel passwords) coordinated without long downtime.

Issue 4 — Systemd timers, rc hooks, and leftover listeners

If cron is clean but infection returns on reboot, check unit files and listening sockets.

Step 1 — List non-default timers and services

systemctl list-timers --all
systemctl list-units --type=service --state=running
sudo find /etc/systemd/system /lib/systemd/system -name '*.timer' -o -name '*.service' | head
sudo grep -RniE 'curl|wget|base64|/tmp/|/dev/shm' /etc/systemd/system/ 2>/dev/null

Step 2 — Disable and mask malicious units

sudo systemctl stop evil.timer evil.service 2>/dev/null
sudo systemctl disable evil.timer evil.service 2>/dev/null
sudo systemctl mask evil.timer evil.service 2>/dev/null
sudo rm -f /etc/systemd/system/evil.service /etc/systemd/system/evil.timer
sudo systemctl daemon-reload

Replace evil with the real unit name you found.

Step 3 — Check listeners and suspicious processes

sudo ss -tulnp
sudo ps auxf
sudo ls -la /proc/*/exe 2>/dev/null | grep -E 'deleted|tmp|dev/shm'

Unexpected miners, reverse shells, or binaries marked (deleted) need the parent persistence removed, then process kill, then binary quarantine.

Step 4 — Profile and rc leftovers

sudo grep -RniE 'curl|wget|base64|/dev/tcp' /etc/profile /etc/profile.d/ /etc/bash.bashrc /root/.bashrc /home/*/.bashrc 2>/dev/null
sudo cat /etc/rc.local 2>/dev/null

When to call Fixwebnode: unknown kernel modules, binaries that respawn faster than you can kill them, or no trusted rebuild path from backups.

End-to-end verification checklist

After the four issue tracks, run a short proof pass so you know the loop is broken.

  1. Confirm only expected UID 0 and sudo members remain.
  2. Confirm root and www-data crontabs show only legitimate jobs: sudo crontab -l and sudo crontab -u www-data -l.
  3. Confirm no unknown systemd timers call network downloaders.
  4. Confirm authorized_keys only contain your keys; reload sshd successfully.
  5. Re-scan the web root and wait 10–15 minutes; malware files must not reappear.
  6. Rotate application secrets, database passwords, and CMS admin sessions after access is closed.
  7. Review /var/log/auth.log and web access logs for repeat probes.
sudo crontab -u www-data -l
getent passwd | awk -F: '$3==0 {print}'
sudo ss -tulnp
sudo find /var/www -mtime -1 -type f -ls | head

When DIY is enough vs when to book Fixwebnode

DIY is reasonable when you still have trusted SSH access, a recent snapshot, a single obvious cron dropper, one rogue user you can identify, and the site is not a regulated or high-traffic checkout system. Follow the numbered steps, document every file you delete, and keep the provider console handy.

Book a specialist when persistence returns after clean crontabs, UID 0 is duplicated, SSH locks you out, customers see injected spam/skimmers, or you need coordinated cleanup across app servers, databases, and DNS without guesswork. Fixwebnode works as a direct remote provider for Linux server incidents for clients across Australia—see coverage on all service areas. Soft scheduling only: urgent remote sessions are often available the same day when booked early, depending on workload.

Do not treat antivirus alone as proof of cleanliness on a server that had root-level persistence. Rebuild from known-good images when integrity of the OS is in doubt, then restore data carefully.

Talk to Fixwebnode about your compromised Linux server

If you are mid-incident—hidden schedulers under www-data, mystery sudo users, or a site that reinfects after every cleanup—get a direct specialist on the session rather than improvising destructive deletes. Start a conversation or book remote Linux malware and backdoor removal through Fixwebnode Ubuntu Linux server support in Australia. Bring SSH access details, approximate timeline of the first odd redirect or CPU spike, and whether you have a snapshot. We will focus on tracing persistence, removing unauthorized access, and leaving you with verifiable clean state—not marketplace bids or generic advice.

Share this article
Fixwebnode Support
Fixwebnode Support

Hey there!
I am your assistant for Fixwebnode. Ask about our services, quotes, packages, orders, or how to get support.
While you wait
What’s your name and best email? We’ll reply even if you leave.