T1098.004
SSH Authorized Keys
Adversaries may modify the SSH authorized_keys file to maintain persistence on a victim host. The authorized_keys file specifies SSH keys permitted for logging into a user account, typically found at <user-home>/.ssh/authorized_keys. Adversaries add their own public keys to this file, enabling passwordless SSH access using the corresponding private key. This technique is used by multiple threat actors including Earth Lusca, TeamTNT, and Salt Typhoon, as well as malware families like Skidmap, XCSSET, and Bundlore.
Microsoft Sentinel / Defender
kusto
let AuthorizedKeysPaths = dynamic([
".ssh/authorized_keys",
".ssh/authorized_keys2",
"/etc/ssh/keys-",
"authorized_keys"
]);
let SuspiciousParents = dynamic([
"curl", "wget", "python", "python3", "perl", "ruby",
"nc", "ncat", "netcat", "bash", "sh", "dash", "zsh"
]);
// File write events to authorized_keys
let FileWriteEvents = DeviceFileEvents
| where TimeGenerated > ago(24h)
| where ActionType in ("FileCreated", "FileModified")
| where FolderPath has_any (AuthorizedKeysPaths) or FileName =~ "authorized_keys" or FileName =~ "authorized_keys2"
| extend EventType = "FileWrite"
| project TimeGenerated, DeviceName, AccountName, ActionType, FolderPath, FileName,
InitiatingProcessFileName, InitiatingProcessCommandLine, InitiatingProcessParentFileName,
SHA256, EventType;
// Process events writing to authorized_keys via shell commands
let ProcessWriteEvents = DeviceProcessEvents
| where TimeGenerated > ago(24h)
| where ProcessCommandLine has_any (AuthorizedKeysPaths)
| where ProcessCommandLine has_any ("echo", "tee", "cat", "cp", "mv", "printf", "ssh-keygen", "dd", ">", ">>", "write", "install")
| extend EventType = "ProcessWrite"
| project TimeGenerated, DeviceName, AccountName, ActionType = ActionType,
FolderPath = "", FileName = FileName,
InitiatingProcessFileName, InitiatingProcessCommandLine = InitiatingProcessCommandLine,
InitiatingProcessParentFileName,
SHA256 = SHA256, EventType;
union FileWriteEvents, ProcessWriteEvents
| extend IsRootSSHDir = FolderPath has "/root/.ssh" or ProcessCommandLine has "/root/.ssh"
| extend IsEtcSSHKeys = FolderPath has "/etc/ssh/keys" or ProcessCommandLine has "/etc/ssh/keys"
| extend IsRedirectAppend = ProcessCommandLine has ">>" or ProcessCommandLine has "tee -a" or ProcessCommandLine has "tee --append"
| extend IsSshKeygen = ProcessCommandLine has "ssh-keygen" or InitiatingProcessFileName has "ssh-keygen"
| extend IsCurlWget = InitiatingProcessFileName has_any ("curl", "wget") or ProcessCommandLine has_any ("curl", "wget")
| extend SuspicionScore = toint(IsRootSSHDir) + toint(IsEtcSSHKeys) + toint(IsRedirectAppend) + toint(IsSshKeygen) + toint(IsCurlWget)
| project TimeGenerated, DeviceName, AccountName, EventType, ActionType,
FolderPath, FileName, InitiatingProcessFileName, InitiatingProcessCommandLine,
InitiatingProcessParentFileName, SHA256,
IsRootSSHDir, IsEtcSSHKeys, IsRedirectAppend, IsSshKeygen, IsCurlWget, SuspicionScore
| sort by TimeGenerated desc high severity
high confidence
Data Sources
File: File Modification File: File Creation Process: Process Creation Command: Command Execution Microsoft Defender for Endpoint
Required Tables
DeviceFileEvents DeviceProcessEvents
False Positives
- Legitimate system administrators adding their own SSH public keys to authorized remote servers during provisioning or key rotation
- Configuration management tools (Ansible, Chef, Puppet, Terraform) that deploy authorized_keys as part of infrastructure-as-code workflows
- Automated CI/CD pipelines that configure SSH keys for deployment accounts on build or staging servers
- Cloud-init or user-data scripts that populate authorized_keys during virtual machine boot and initial provisioning
Last updated: 2026-04-13 Research depth: deep
References (13)
- https://attack.mitre.org/techniques/T1098/004/
- https://www.ssh.com/ssh/authorized_keys/
- https://www.venafi.com/blog/growing-abuse-ssh-keys-commodity-malware-campaigns-now-equipped-ssh-capabilities
- https://www.cybereason.com/blog/new-pervasive-worm-exploiting-linux-exim-server-vulnerability
- https://cloud.google.com/sdk/gcloud/reference/compute/instances/add-metadata
- https://about.gitlab.com/blog/2020/02/12/plundering-gcp-escalating-privileges-in-google-cloud-platform/
- https://docs.microsoft.com/en-us/rest/api/compute/virtual-machines/update
- https://knowledge.broadcom.com/external/article/313767/allowing-ssh-access-to-vmware-vsphere-es.html
- https://www.trendmicro.com/en_us/research/22/a/earth-lusca-employs-sophisticated-infrastructure-varied-tools-and-techniques.html
- https://www.trendmicro.com/en_us/research/19/f/skidmap-linux-malware-uses-rootkit-capabilities-to-hide-cryptocurrency-mining-payload.html
- https://blog.aquasec.com/teamtnt-activities-summary-and-a-deep-dive-into-a-recent-campaign
- https://www.cisco.com/c/en/us/td/docs/ios-xml/ios/security/d1/sec-d1-cr-book/sec-cr-i3.html#wp1254331478
- https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1098.004/T1098.004.md
Unlock Pro Content
Get the full detection package for T1098.004 including response playbook, investigation guide, and atomic red team tests.
Response PlaybookInvestigation GuideHunting QueriesAtomic Red Team TestsTuning Guidance