Use this checklist when a Linux host shows unexplained or suspicious behavior and you need to determine what was impacted. The goal is triage and evidence collection: identify active sessions, suspicious processes/connections, persistence, credential exposure, and the likely timeline.
Important: If compromise is plausible, avoid making unnecessary changes before collecting evidence. Commands can alter timestamps, logs, process state, or other evidence. For important systems, consider isolating the host at the network layer and preserving a disk/memory image before remediation.
Check before changing anything. An active intruder may be able to observe commands you run.
w
last -n 20
lastbWhat to review:
w— currently logged-in users, their source, and what they are running.last -n 20— recent successful login/session history and source addresses.lastb— recent failed login attempts, where supported and permitted.
Record unfamiliar usernames, source IPs, login times, terminals, and sessions that do not match expected administration activity.
Attackers may leave cryptominers, reverse shells, backdoors, or processes launched from unusual parent processes.
ps auxf
topLook for:
- Unknown or unexpected processes.
- Processes running as
rootwithout a clear reason. - High or unexplained CPU/memory use.
- Executables launched from
/tmp,/var/tmp,/dev/shm, user home directories, or other unusual locations. - Strange parent-child relationships or processes whose command line does not match their apparent purpose.
Do not kill a suspicious process until you have recorded enough information to investigate it, unless immediate containment requires it.
Unexpected outbound connections can indicate command-and-control, a reverse shell, scanning, or data exfiltration.
ss -tulpn
ss -antp | grep ESTABLISHEDReview:
- Unexpected listening ports.
- The process owning each listening socket.
- Established connections to unknown external addresses.
- Connections from services that normally should not initiate outbound traffic.
For each suspicious connection, record the local/remote address, port, owning PID/process, and time observed.
Common persistence locations include cron jobs and systemd services. The original reference also calls out UDEV rules; inspect those manually when relevant.
for u in $(cut -f1 -d: /etc/passwd); do
crontab -u "$u" -l 2>/dev/null
doneAlso inspect system-wide cron locations where present:
cat /etc/crontab
ls -la /etc/cron.d /etc/cron.hourly /etc/cron.daily /etc/cron.weekly /etc/cron.monthly 2>/dev/nullsystemctl list-units --type=service
systemctl list-unit-files --type=serviceLook for unfamiliar services, recently added unit files, unusual ExecStart paths, or services executing files from writable temporary/user locations.
ls -la /etc/udev/rules.d /usr/lib/udev/rules.d 2>/dev/nullInvestigate unfamiliar or recently modified rules rather than deleting them during evidence collection.
SSH private keys, cloud credentials, API tokens, certificates, and application secrets are high-value targets. A compromise can therefore extend beyond this host.
A broad filename-oriented search, adapted from the reference:
find / \( -name 'id_rsa' -o -name '*.pem' -o -name 'credentials' \) 2>/dev/nullFind regular files modified during the last 24 hours:
find / -mtime -1 -type f 2>/dev/nullTreat these commands as leads, not proof of theft. Review shell histories, application configuration, deployment secrets, SSH directories, cloud CLI credential stores, environment files, and service-account credentials relevant to the host.
If a secret was accessible to an attacker, plan to rotate/revoke it from a known-clean system after containment.
Attackers may clear shell history, but authentication, system, application, remote logging, or audit records can still reveal a timeline.
grep 'Accepted' /var/log/secure
grep 'Failed' /var/log/securegrep 'Accepted' /var/log/auth.log
grep 'Failed' /var/log/auth.logjournalctl --since today
journalctl -u ssh --since today 2>/dev/null
journalctl -u sshd --since today 2>/dev/nullausearch -m USER_CMD --start todayausearch only shows events that the audit subsystem was configured to capture; it should not be assumed to contain every command executed on the host.
Correlate successful logins, failures preceding a successful login, privilege changes, service starts/stops, package activity, file changes, and network events.
For each suspicious finding, record enough context to decide whether the system was merely probed or actually compromised.
| Area | Finding | Evidence / timestamp | Impact | Action |
|---|---|---|---|---|
| Accounts / logins | ||||
| Processes | ||||
| Network connections | ||||
| Persistence | ||||
| Files changed | ||||
| Credentials / secrets | ||||
| Logs / audit trail | ||||
| Other hosts/services |
- Which account was used, and was privilege escalation obtained?
- What processes or commands were executed?
- What files were created, modified, deleted, or read?
- Was persistence installed?
- Were credentials, SSH keys, tokens, certificates, or application secrets accessible?
- Were there unexpected outbound connections or evidence of exfiltration?
- Could stolen credentials provide access to other hosts, cloud accounts, CI/CD systems, databases, or third-party services?
- What is the earliest known suspicious event and the latest known attacker activity?
If compromise is confirmed or cannot be confidently ruled out, preserve evidence and contain the affected system. Rotate exposed credentials from a clean machine, investigate connected systems, and prefer rebuilding/redeploying the host from a known-good source rather than assuming that deleting visible malicious files fully restores trust.