Skip to content

Instantly share code, notes, and snippets.

@pleaz
Last active December 8, 2025 22:31
Show Gist options
  • Select an option

  • Save pleaz/0e2e27494976ed2a481a61de08fd51e2 to your computer and use it in GitHub Desktop.

Select an option

Save pleaz/0e2e27494976ed2a481a61de08fd51e2 to your computer and use it in GitHub Desktop.
linux malware removal
#!/bin/sh
# Linux Server Malware Removal Script
# =============================================================================
# Based on real incident response to cryptominer infection via Next.js exploit
# SPECIFICALLY: CVE-2025-66478 / CVE-2025-55182 (RCE in React Server Components)
# Use at your own risk. Always backup data before running.
# Ideally, rebuild the server from scratch after compromise.
# =============================================================================
#
# USAGE GUIDE:
# 1. Download:
# curl -sSL https://gist.githubusercontent.com/pleaz/0e2e27494976ed2a481a61de08fd51e2/raw/d5e915ccc166de6b6af173d5f7af616190cf7a3a/linux-malware-removal-v2.sh -o linux-malware-removal-v2.sh
# 2. Make executable:
# chmod +x linux-malware-removal-v2.sh
# 3. Run:
# ./linux-malware-removal-v2.sh
#
# =============================================================================
set -e
echo "=========================================="
echo "Linux Malware Removal Script"
echo "=========================================="
echo ""
echo "WARNING: This script will kill processes and delete files."
echo "Make sure you have backups before proceeding."
echo ""
printf "Continue? (y/N): "
read confirm
if [ "$confirm" != "y" ] && [ "$confirm" != "Y" ]; then
echo "Aborted."
exit 1
fi
# =============================================================================
# STEP 0: CHECK FOR VULNERABLE NEXT.JS INSTALLATIONS (CVE-2025-66478)
# =============================================================================
echo ""
echo "[STEP 0] Checking for potential vulnerable Next.js installations..."
echo "Target: CVE-2025-66478 (RCE in React Server Components)"
echo "Affected: Next.js 15.x, 16.x, and 14.3.0-canary.77+"
echo ""
echo "--- Searching for package.json files with 'next' dependency ---"
# Find package.json files (excluding node_modules to reduce noise, though malware might hide there)
# We look for "next" version definitions.
found_next=0
# Use a temporary file to store results to avoid subshell variable scope issues
tmp_next_found=$(mktemp)
find / -name "package.json" -not -path "*/node_modules/*" -type f 2>/dev/null | head -50 | while IFS= read -r file; do
if grep -q '"next":' "$file"; then
echo "FOUND Next.js in: $file"
grep '"next":' "$file"
echo "1" > "$tmp_next_found"
fi
done
if [ -s "$tmp_next_found" ]; then
found_next=1
fi
rm -f "$tmp_next_found"
if [ "$found_next" -eq 1 ]; then
echo ""
echo "WARNING: Next.js installations found."
echo "Please verify they are patched to at least:"
echo " - 15.0.5, 15.1.9, 15.2.6, 15.3.6, 15.4.8, 15.5.7"
echo " - 16.0.7"
echo " - 15.6.0-canary.58, 16.1.0-canary.12"
echo "Run 'npx fix-react2shell-next' in the project directories to fix."
else
echo "No obvious Next.js installations found in common paths."
fi
# =============================================================================
# STEP 1: DIAGNOSTICS - Find what's running
# =============================================================================
echo ""
echo "[STEP 1] Running diagnostics..."
# If top/htop are being killed, malware is actively hiding
# Use /proc directly to see processes
echo ""
echo "--- Listing all processes via /proc (bypasses compromised ps/top) ---"
for pid in /proc/[0-9]*; do
if [ -d "$pid" ]; then
if [ -f "$pid/cmdline" ]; then
cmdline=$(cat "$pid/cmdline" 2>/dev/null | tr '\0' ' ')
if [ -n "$cmdline" ]; then
echo "$(basename "$pid"): $cmdline"
fi
fi
fi
done | head -100
echo ""
echo "--- Checking for deleted executables (common malware sign) ---"
# Use ls -la and grep, but handle empty results gracefully
if ls -la /proc/*/exe 2>/dev/null | grep -q deleted; then
ls -la /proc/*/exe 2>/dev/null | grep deleted
else
echo "None found"
fi
# =============================================================================
# STEP 2: FIND MALICIOUS SYSTEMD SERVICES
# =============================================================================
echo ""
echo "[STEP 2] Checking for suspicious systemd services..."
# Common fake service names used by cryptominers
# POSIX sh doesn't support arrays easily, so we iterate a string list
SUSPICIOUS_SERVICES="linux.service system_os.service systemd-utils.service lived.service log.service networkerd.service nginxd.service bot.service"
echo ""
echo "--- Recently modified service files (last 7 days) ---"
find /etc/systemd/system -name "*.service" -mtime -7 2>/dev/null
echo ""
echo "--- Checking for known malicious service names ---"
for svc in $SUSPICIOUS_SERVICES; do
if systemctl list-units --all 2>/dev/null | grep -q "$svc"; then
echo "FOUND SUSPICIOUS: $svc"
fi
done
echo ""
echo "--- All running services (review manually) ---"
systemctl list-units --type=service --state=running 2>/dev/null || echo "systemctl not available or failed"
# =============================================================================
# STEP 3: CHECK PERSISTENCE MECHANISMS
# =============================================================================
echo ""
echo "[STEP 3] Checking persistence mechanisms..."
echo ""
echo "--- Root crontab ---"
crontab -l 2>/dev/null || echo "No crontab for root"
echo ""
echo "--- System crontab ---"
if [ -f /etc/crontab ]; then
cat /etc/crontab
else
echo "/etc/crontab not found"
fi
echo ""
echo "--- Cron.d directory ---"
if [ -d /etc/cron.d/ ]; then
ls -la /etc/cron.d/
else
echo "/etc/cron.d/ not found"
fi
echo ""
echo "--- rc.local (legacy startup) ---"
if [ -f /etc/rc.local ]; then
cat /etc/rc.local
else
echo "No rc.local"
fi
echo ""
echo "--- Checking for LD_PRELOAD rootkit ---"
if [ -f /etc/ld.so.preload ]; then
cat /etc/ld.so.preload
else
echo "Empty or not found (good)"
fi
echo "LD_PRELOAD env: $LD_PRELOAD"
# =============================================================================
# STEP 4: FIND SUSPICIOUS FILES
# =============================================================================
echo ""
echo "[STEP 4] Finding suspicious files..."
echo ""
echo "--- Executables in /usr modified in last 7 days ---"
find /usr -type f -executable -mtime -7 2>/dev/null | head -30
echo ""
echo "--- Hidden directories in common locations ---"
ls -la /root/.*/ 2>/dev/null | head -20
ls -la /tmp/.*/ 2>/dev/null | head -20
echo ""
echo "--- Suspicious paths to check manually ---"
SUSPICIOUS_PATHS="/root/.systemd-utils /etc/rondo /usr/infju /.img /etc/32678"
for path in $SUSPICIOUS_PATHS; do
if [ -e "$path" ]; then
echo "FOUND: $path"
ls -la "$path"
fi
done
# =============================================================================
# STEP 5: CLEANUP (UNCOMMENT TO EXECUTE)
# =============================================================================
echo ""
echo "[STEP 5] Cleanup commands (review and run manually)"
echo ""
echo "# --- Stop and disable malicious services ---"
echo "# systemctl stop linux.service system_os.service systemd-utils.service lived.service log.service networkerd.service nginxd.service bot.service 2>/dev/null"
echo "# systemctl disable linux.service system_os.service systemd-utils.service lived.service log.service networkerd.service nginxd.service bot.service 2>/dev/null"
echo ""
echo "# --- Remove service files ---"
echo "# rm -f /etc/systemd/system/{linux,system_os,systemd-utils,lived,log,networkerd,nginxd,bot}.service"
echo "# rm -f /etc/systemd/system/multi-user.target.wants/{systemd-utils,bot,lived,networkerd,nginxd}.service"
echo ""
echo "# --- Remove malware binaries ---"
echo "# rm -f /usr/bin/{softirq,nginxd,system_os}"
echo "# rm -f /usr/local/bin/{curl,systemhelper} # Note: only if these are fake!"
echo "# rm -rf /root/.systemd-utils"
echo "# rm -rf /etc/rondo"
echo "# rm -rf /usr/infju"
echo "# rm -f /.img"
echo "# rm -f /etc/32678"
echo ""
echo "# --- Clean crontabs ---"
echo "# crontab -r # Remove root crontab"
echo "# rm -f /etc/cron.d/{rondo,syshelper,systemhelper}"
echo ""
echo "# --- Reset rc.local ---"
echo "# echo '#!/bin/sh' > /etc/rc.local"
echo "# echo 'exit 0' >> /etc/rc.local"
echo ""
echo "# --- Kill malware processes (find PIDs first) ---"
echo "# pkill -9 -f ntpclient"
echo "# pkill -9 -f softirq"
echo "# pkill -9 -f cryptominer_name"
echo ""
echo "# --- Reload systemd ---"
echo "# systemctl daemon-reload"
echo ""
echo "# --- Reinstall potentially compromised tools ---"
echo "# apt update && apt install --reinstall procps htop coreutils"
# =============================================================================
# STEP 6: POST-CLEANUP VERIFICATION
# =============================================================================
echo ""
echo "[STEP 6] Verification commands (run after cleanup)"
echo ""
echo "# Check if top/htop work now:"
echo "# top -b -n 1 | head -20"
echo ""
echo "# Check for remaining suspicious processes:"
echo "# ps aux | grep -E 'miner|crypto|xmr|softirq'"
echo ""
echo "# Check listening ports:"
echo "# ss -tulpn"
echo ""
echo "# Check outbound connections:"
echo "# ss -tupn | grep ESTAB"
# =============================================================================
# ADDITIONAL NOTES
# =============================================================================
echo ""
echo "=========================================="
echo "IMPORTANT NOTES"
echo "=========================================="
echo ""
echo "1. If top/htop get 'Killed' immediately, malware is actively blocking them"
echo " Use: for pid in /proc/[0-9]*; do cat \$pid/cmdline 2>/dev/null; done"
echo ""
echo "2. Common cryptominer indicators:"
echo " - High CPU usage"
echo " - Processes with random names (gqxbdrzuk, fbfKMUPZ)"
echo " - Fake system names (ntpclient, softirq, kworker with weird suffixes)"
echo " - Connections to port 443 with mining pool IPs"
echo ""
echo "3. Common persistence locations:"
echo " - /etc/systemd/system/*.service"
echo " - /etc/cron.d/*"
echo " - /etc/crontab"
echo " - /etc/rc.local"
echo " - ~/.ssh/authorized_keys (check for added keys!)"
echo ""
echo "4. After cleanup, ALWAYS:"
echo " - Change all passwords"
echo " - Rotate SSH keys"
echo " - Check ~/.ssh/authorized_keys for unauthorized keys"
echo " - Update vulnerable software (Next.js CVE-2025-66478, etc.)"
echo " - Review and harden your application"
echo ""
echo "5. BEST PRACTICE: Rebuild server from scratch if possible"
echo " This script is for emergency situations only."
echo ""
echo "=========================================="
echo "Script completed. Review output above."
echo "=========================================="
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment