SSH
AUTH.LOG
AUTHORIZED_KEYS
FAN-OUT
DetectionBlue TeamSOCOctober 12, 2026•9 min read

Detecting SSH Lateral Movement on Linux

On Linux, SSH is lateral movement. The logs tell you which key logged in, from which host, and how many hosts it reached.

Scroll

Linux estates lack the logon event taxonomy of Windows, but sshd logs are rich: the method, the account, the source and, for public key logins, the key fingerprint. Attackers add their own keys, reuse stolen ones and hijack forwarded agents. All of it is searchable if you ship auth logs centrally.

Signals at a Glance

SignalWhereATT&CK
Accepted publickey or password login from an internal source never seen for that accountauth.log, secureT1021.004
One source or key fingerprint reaching many hosts in a short windowauth.log, centralisedT1021.004
New entry written to authorized_keysauditd, FIM, osqueryT1098.004
Login by root or a service account over SSH from a user workstationauth.logT1078
Use of another user’s forwarded SSH agent socketauditd, process telemetryT1563.001

Reading Accepted Logins

A successful public key login logs a line of the form Accepted publickey for <user> from <ip> port <n> ssh2: RSA SHA256:<fingerprint>. Extracting user, source and fingerprint lets you detect fan-out and key reuse, which are the two strongest SSH lateral movement behaviours:

index=linux sourcetype=linux_secure "Accepted "
| rex "Accepted (?<method>\S+) for (?<user>\S+) from (?<src>\S+) port \d+ ssh2(?:: \S+ (?<fp>SHA256:\S+))?"
| where cidrmatch("10.0.0.0/8", src) OR cidrmatch("172.16.0.0/12", src) OR cidrmatch("192.168.0.0/16", src)
| bin _time span=1h
| stats dc(host) as dests values(host) as hosts dc(src) as sources by user, fp, _time
| where dests >= 5 OR sources >= 4
| sort - dests
# tune/validate: replace the RFC1918 ranges with your own; exclude configuration-management and
# bastion sources via a lookup before alerting.

A fingerprint accepted on many hosts from many sources is either a shared automation key or a stolen one. Inventory the former so the latter stands out. Equally, a first-time source for an account is a useful low-cost alert; keep a rolling 30-day baseline per user.

Keys, Agents and Persistence

Adding a public key to authorized_keys is quiet persistence and a favourite for lateral movement because it survives password changes. Audit writes to those files and to the SSH daemon configuration:

# /etc/audit/rules.d/ssh.rules  (starting point; validate paths for your distribution)
-w /root/.ssh/authorized_keys -p wa -k ssh_authkeys
-w /etc/ssh/sshd_config -p wa -k sshd_config
-w /etc/ssh/sshd_config.d/ -p wa -k sshd_config
# User home directories: add per-user watches or use file integrity monitoring / osquery,
# since auditd cannot wildcard /home/*/.ssh/authorized_keys.
# tune/validate: confirm rule syntax with auditctl -R on a test host before fleet rollout.
Vetted sources

Use the SigmaHQ Linux auth and SSH rules, Elastic and Splunk ESCU SSH content and MITRE CAR analytics for remote services. Auditd, osquery and Atomic Red Team (Linux SSH tests) cover the host side. Baseline your own environment: automation, backup and orchestration tooling log in over SSH constantly.

Build Detections That Fire

Mjolnir Security helps blue teams turn threat intelligence into high-fidelity detections across endpoint, network, identity and cloud telemetry.

Detection EngineeringManaged Detection & ResponseThreat HuntingIncident ResponsePurple Teaming
  • Detection Engineering We build and tune detections mapped to ATT&CK from your own telemetry.
  • Threat Hunting as a Service Hypothesis-driven hunts for the behaviours on this page.
  • 24/7 Incident Response Containment when a detection fires. Call +1 833 403 5875.
Written by: Mjolnir Threat Research (MTAC)  |  Published: October 12, 2026  |  Last reviewed: October 12, 2026