How to Know If a Threat Actor Has Accessed Your Server This article explains that every internet-connected server is a target for unauthorized access, and it provides a guide for detecting a compromise. It details common indicators of a breach, such as brute-force login attempts, creation of backdoor accounts, unexpected processes, and data exfiltration patterns. The guide also offers specific commands for examining system logs on both Linux and Windows servers to identify suspicious activity. A practical detection, investigation, and response guide for DevOps engineers, backend developers, security engineers, and startup CTOs. Sobering reality:IBM's 2023 Cost of a Data Breach Report found that the average breach goesundetected for 204 days— nearly 7 months. By the time most teams notice something is wrong, the attacker has already been living in their infrastructure long enough to map every service, exfiltrate sensitive data, and install multiple persistence mechanisms. The detection gap, not the initial intrusion, is what turns an incident into a catastrophe.This guide closes that gap. Table of Contents Introduction 1-introduction Common Signs a Threat Actor Accessed a Server 2-common-signs-a-threat-actor-accessed-a-server Where to Check — Logs & Evidence Sources 3-where-to-check--logs--evidence-sources Network-Based Detection 4-network-based-detection Step-by-Step Investigation Playbook 5-step-by-step-investigation-playbook Useful Commands & Tools 6-useful-commands--tools MITRE ATT&CK Technique Mapping 7-mitre-attck-technique-mapping Indicators of Compromise IoC Checklist 8-indicators-of-compromise-ioc-checklist Immediate Response Actions 9-immediate-response-actions Legal, Compliance & Regulatory Obligations 10-legal-compliance--regulatory-obligations Prevention Best Practices 11-prevention-best-practices Windows Server Incident Response 12-windows-server-incident-response Real-World Example 13-real-world-example-detecting-a-compromised-linux-server Conclusion — The DICRP Framework 14-conclusion--the-dicrp-framework Quick Reference 15-quick-reference 1. Introduction Every server connected to the internet is a target. It is not a question of if someone will attempt to access it without authorisation — it is a question of when , and whether you will detect it in time. A server compromise occurs when an unauthorised party gains access to a system in a way that was not intended, permitted, or expected. This could range from a low-privilege attacker who merely explored your file system to a sophisticated threat actor who has maintained persistent access for months, exfiltrated data, and planted backdoors before you noticed anything unusual. Normal vs. Suspicious vs. Confirmed Compromise Understanding the difference between these three states is the foundation of any incident investigation. | State | Description | Example | |---|---|---| Normal access | Expected behaviour from known users, services, or automated systems | Your deployment pipeline SSH-ing in as deploy at 2:00 AM | Suspicious access | Anomalous activity that may or may not be malicious — requires investigation | A root login from an unrecognised IP at 3:47 AM | Confirmed compromise | Evidence of unauthorised access, malicious activity, or data breach | A reverse shell process running as www-data ; unknown SSH keys added | The critical skill is recognising the gap between "something looks off" and "we have been breached." Many teams either dismiss suspicious signals too quickly or panic at false positives. This guide will help you tell the difference — and act accordingly. 2. Common Signs a Threat Actor Accessed a Server Before diving into log analysis, you need to know what you are looking for. The following indicators are the most common signals that something is wrong. 2.1 Unusual Login Attempts SSH / RDP / API MITRE ATT&CK: T1110 — Brute Force, T1078 — Valid Accounts Brute-force attempts are often a precursor to or evidence of access. A high volume of failed logins followed by a single successful one is a textbook sign of a successful brute-force attack. What to look for: - Multiple failed SSH attempts from the same or rotating IP addresses - Successful logins from geographic locations inconsistent with your team - Logins at unusual hours 3:00 AM when your team is in Lagos / London / NYC - Logins from IPs flagged in threat intelligence databases Shodan, AbuseIPDB - API authentication tokens used from unexpected IP ranges 2.2 Unknown Users or Privilege Escalation MITRE ATT&CK: T1136 — Create Account, T1548 — Abuse Elevation Control Mechanism Attackers often create backdoor accounts or escalate privileges to maintain access. What to look for: - New user accounts in /etc/passwd you did not create - Users added to sudo or the wheel group without authorisation - Changes to /etc/sudoers or /etc/sudoers.d/ - A non-root user suddenly running processes as root - SUID/SGID binaries that were not there before 2.3 Unexpected Running Processes / Services MITRE ATT&CK: T1059 — Command and Scripting Interpreter, T1543 — Create or Modify System Process Malicious actors install tools — cryptominers, reverse shells, data exfiltration agents. These show up as unexpected processes. What to look for: - Processes with random or disguised names e.g., kworkerds , sysupdate , .init - Processes listening on unusual ports - Unknown services registered with systemd or init.d - Processes consuming excessive CPU often cryptominers - Processes running as www-data , nginx , or other service accounts but performing non-service tasks 2.4 Modified System Files / Configurations MITRE ATT&CK: T1565 — Data Manipulation, T1601 — Modify System Image Attackers modify system files to maintain persistence or disable defences. What to look for: - Changes to /etc/hosts redirecting DNS - Modified shell profiles: .bashrc , .bash profile , .profile , /etc/profile.d/ - Altered PAM configuration files /etc/pam.d/ - Modified SSH server config /etc/ssh/sshd config — e.g., PermitRootLogin yes added - Timestamp discrepancies on critical binaries ls , ps , netstat , find - Changes to web application files index.php , config.js — webshells 2.5 Unusual Outbound / Inbound Network Traffic MITRE ATT&CK: T1071 — Application Layer Protocol, T1041 — Exfiltration Over C2 Channel Data exfiltration and command-and-control C2 communication create distinctive network patterns. What to look for: - Large outbound data transfers to unknown IPs, especially at odd hours - Connections to known malicious IP ranges or Tor exit nodes - Unusual protocols or ports IRC on port 6667, DNS tunnelling, ICMP data transfer - New persistent connections to external IPs from service accounts - DNS queries to domains with high entropy DGA — Domain Generation Algorithm 2.6 High CPU, RAM, or Disk Usage Anomalies MITRE ATT&CK: T1496 — Resource Hijacking Resource abuse is one of the most visible and often first noticed signs of compromise. What to look for: - CPU usage consistently above 80–90% with no corresponding application load - Disk I/O spikes with no scheduled jobs running - Disk filling up rapidly with unexpected files - Memory exhaustion tied to an unknown process - Cryptomining malware is the most common cause — it is immediately visible in resource graphs 2.7 Disabled Security Tools or Logs MITRE ATT&CK: T1562 — Impair Defenses, T1070 — Indicator Removal A sophisticated attacker's first action is often to blind your monitoring. What to look for: - auditd , fail2ban , iptables , or ufw suddenly stopped or disabled - Log files that are empty, truncated, or have suspicious gaps - cron entries that pipe logs to /dev/null - Security agent CrowdStrike, Wazuh, OSSEC reporting offline - syslog daemon stopped or replaced 2.8 Unexpected Cron Jobs / Scheduled Tasks MITRE ATT&CK: T1053 — Scheduled Task/Job Cron is a favourite persistence mechanism for attackers. What to look for: - Entries in /var/spool/cron/crontabs/ you do not recognise - New files in /etc/cron.d/ , /etc/cron.hourly/ , /etc/cron.daily/ - Cron jobs that download and execute scripts from external URLs - Windows: Scheduled Tasks created under \Microsoft\Windows\ in Task Scheduler - Systemd timers systemctl list-timers that are unexpected 2.9 New SSH Keys or Changed Credentials MITRE ATT&CK: T1098 — Account Manipulation, T1556 — Modify Authentication Process Attackers plant SSH keys to ensure persistent re-entry even after passwords are changed. What to look for: - New entries in ~/.ssh/authorized keys for root or any user - New keys in /etc/ssh/authorized keys if configured globally - SSH host keys regenerated check /etc/ssh/ssh host - Changed /etc/passwd or /etc/shadow entries password hash changes - Cloud metadata service SSH key updates AWS EC2 Instance Connect, GCP OS Login 3. Where to Check — Logs & Evidence Sources Once you suspect compromise, you need to know exactly where to look. Here is a comprehensive map of log locations and what each reveals. 3.1 Linux System Logs | Log File | Location | What It Contains | |---|---|---| auth.log | /var/log/auth.log Debian/Ubuntu | SSH logins, sudo usage, PAM events | secure | /var/log/secure RHEL/CentOS/Amazon Linux | Same as auth.log for RPM-based distros | syslog | /var/log/syslog | General system messages, daemon activity | kern.log | /var/log/kern.log | Kernel events, unusual driver/module loads | wtmp | /var/log/wtmp | Binary log of all logins/logouts read with last | btmp | /var/log/btmp | Binary log of failed logins read with lastb | lastlog | /var/log/lastlog | Most recent login per user read with lastlog | audit.log | /var/log/audit/audit.log | System call auditing if auditd is enabled | Using journalctl systemd-based systems : Show all logs from the past 24 hours journalctl --since "24 hours ago" Show SSH service logs within a date range journalctl -u ssh --since "2024-01-01" --until "2024-01-07" Show logs for a specific process ID journalctl PID=1234 Show kernel messages only journalctl -k Follow logs in real time journalctl -f Show logs at warning priority or higher journalctl -p warning 3.2 Web Server Logs Web servers are frequent entry points via exploited applications, LFI, RFI, SQL injection, or webshells. Nginx: Default access log tail -f /var/log/nginx/access.log Look for POST requests to unusual paths webshell access grep "POST" /var/log/nginx/access.log | grep -v "api\|login\|upload" Look for scanning patterns many 404s from one IP awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20 Look for unusual user agents grep -i "sqlmap\|nikto\|nmap\|masscan\|python-requests\|zgrab" /var/log/nginx/access.log Apache: Apache access log tail -f /var/log/apache2/access.log HTTP status code distribution — many 200s on unusual paths = webshell hits cat /var/log/apache2/access.log | awk '{print $9}' | sort | uniq -c | sort -rn 3.3 Cloud Audit Logs AWS CloudTrail: Find console login events aws cloudtrail lookup-events \ --lookup-attributes AttributeKey=EventName,AttributeValue=ConsoleLogin \ --start-time 2024-01-01T00:00:00Z --end-time 2024-01-07T00:00:00Z Look for root account usage always suspicious aws cloudtrail lookup-events \ --lookup-attributes AttributeKey=Username,AttributeValue=root Look for IAM user creation aws cloudtrail lookup-events \ --lookup-attributes AttributeKey=EventName,AttributeValue=CreateUser Look for security group rule additions attacker opening ports aws cloudtrail lookup-events \ --lookup-attributes AttributeKey=EventName,AttributeValue=AuthorizeSecurityGroupIngress GCP Audit Logs: View admin activity logs gcloud logging read \ "logName=projects/YOUR PROJECT/logs/cloudaudit.googleapis.com%2Factivity" \ --limit 100 --format json Filter for IAM policy changes gcloud logging read 'protoPayload.methodName="SetIamPolicy"' --limit 50 Azure Monitor: Query for role assignment changes az monitor activity-log list \ --start-time 2024-01-01T00:00:00Z \ --end-time 2024-01-07T00:00:00Z \ --query " ?authorization.action=='Microsoft.Authorization/roleAssignments/write' " 3.4 Firewall and WAF Logs iptables — view current rules with byte counts iptables -L -n -v View recent iptables drops if DROP logging is enabled grep "iptables" /var/log/syslog | tail -50 UFW logs grep "UFW" /var/log/ufw.log | grep "BLOCK" | tail -50 fail2ban — view currently banned IPs fail2ban-client status sshd See all bans across all jails fail2ban-client status 3.5 Container and Kubernetes Logs MITRE ATT&CK: T1610 — Deploy Container, T1613 — Container and Resource Discovery Docker — view container logs docker logs