Last active
December 8, 2025 22:31
-
-
Save pleaz/0e2e27494976ed2a481a61de08fd51e2 to your computer and use it in GitHub Desktop.
linux malware removal
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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