T1098.004 Google Chronicle · YARA-L

Detect SSH Authorized Keys in Google Chronicle

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.

MITRE ATT&CK

Tactic
Persistence Privilege Escalation
Technique
T1098 Account Manipulation
Sub-technique
T1098.004 SSH Authorized Keys
Canonical reference
https://attack.mitre.org/techniques/T1098/004/

YARA-L Detection Query

Google Chronicle (YARA-L)
yaral
rule t1098_004_ssh_authorized_keys_file_write {
  meta:
    author = "Argus Detection Engineering"
    description = "Detects file creation or modification events targeting SSH authorized_keys paths, indicating potential SSH key persistence. MITRE ATT&CK T1098.004 - Account Manipulation: SSH Authorized Keys."
    mitre_attack_tactic = "Persistence"
    mitre_attack_technique = "T1098.004"
    reference = "https://attack.mitre.org/techniques/T1098/004/"
    severity = "HIGH"
    confidence = "HIGH"
    platform = "linux"
    data_source = "EDR, auditd, syslog"
    false_positives = "Configuration management automation, authorized IT admin key deployment, cloud-init provisioning"
    created = "2026-04-13"
    version = "1.0"

  events:
    ($e.metadata.event_type = "FILE_MODIFICATION" or
     $e.metadata.event_type = "FILE_CREATION")
    (re.regex($e.target.file.full_path, `\.ssh/authorized_keys2?$`) or
     re.regex($e.target.file.full_path, `/etc/ssh/keys-`) or
     $e.target.file.name = "authorized_keys" or
     $e.target.file.name = "authorized_keys2")

  condition:
    $e
}

rule t1098_004_ssh_authorized_keys_process_write {
  meta:
    author = "Argus Detection Engineering"
    description = "Detects process launch events where shell utilities (echo, tee, ssh-keygen) or network downloaders (curl, wget) write to authorized_keys paths. Flags suspicious parent processes. MITRE ATT&CK T1098.004."
    mitre_attack_tactic = "Persistence"
    mitre_attack_technique = "T1098.004"
    reference = "https://attack.mitre.org/techniques/T1098/004/"
    severity = "HIGH"
    confidence = "HIGH"
    platform = "linux"
    data_source = "EDR process telemetry"
    false_positives = "Ansible ssh key deployment, CI/CD key rotation pipelines"
    created = "2026-04-13"
    version = "1.0"

  events:
    $e.metadata.event_type = "PROCESS_LAUNCH"
    re.regex($e.target.process.command_line, `authorized_keys`)
    (re.regex($e.target.process.command_line, `(echo|printf|tee|ssh-keygen|>>|curl|wget|cp |mv |dd |install )`) or
     re.regex($e.principal.process.file.full_path, `/(curl|wget|python[23]?|perl|ruby|nc|ncat|netcat|bash|sh|dash|zsh)$`))

  condition:
    $e
}
high severity high confidence

Two Chronicle YARA-L 2.0 rules for detecting SSH authorized_keys modification (T1098.004) in Google SecOps SIEM. Rule 1 matches UDM FILE_MODIFICATION and FILE_CREATION events targeting authorized_keys paths using regex on target.file.full_path and target.file.name. Rule 2 matches UDM PROCESS_LAUNCH events where command lines reference authorized_keys alongside write utilities or suspicious parent executables. Both rules use Chronicle's UDM normalized field model and are deployable directly in Google SecOps detection engine.

Data Sources

Google Chronicle with CrowdStrike Falcon EDR (UDM normalized process and file events)Chronicle with Carbon Black, SentinelOne, or Microsoft Defender for Endpoint via Chronicle ingestionChronicle Linux host forwarder with auditd (FILE_MODIFICATION, PROCESS_LAUNCH UDM events)Google Chronicle via Google Cloud Security Command Center integration

Required Tables

UDM Events with event_type FILE_MODIFICATIONUDM Events with event_type FILE_CREATIONUDM Events with event_type PROCESS_LAUNCH

False Positives & Tuning

  • Ansible ad-hoc commands or playbooks using the authorized_key module to deploy legitimate SSH public keys, which generates both PROCESS_LAUNCH (python/ansible) and FILE_MODIFICATION (authorized_keys) UDM events in rapid succession
  • Cloud-init and instance initialization scripts on AWS EC2 or GCP Compute Engine that inject SSH keys from instance metadata into authorized_keys at first boot, generating FILE_CREATION events from the cloud-init process
  • Security audit scripts that use cat or grep to read (not write) authorized_keys for compliance verification, which may trigger process-based detection if the command_line pattern match is too broad
Download portable Sigma rule (.yml)

Other platforms for T1098.004


Testing Methodology

Validate this detection against 5 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.

  1. Test 1Append Adversary SSH Key to Root authorized_keys

    Expected signal: auditd SYSCALL records for open()/write() on /root/.ssh/authorized_keys if auditd watch is configured. syslog entries from auditd. DeviceFileEvents (if MDE for Linux deployed): FileCreated or FileModified event for FileName=authorized_keys with FolderPath=/root/.ssh. DeviceProcessEvents: Process Create for ssh-keygen and echo/bash with ProcessCommandLine containing 'authorized_keys'. Shell history entry in /root/.bash_history.

  2. Test 2Add SSH Key via curl Download

    Expected signal: DeviceProcessEvents: Process Create for curl with ProcessCommandLine containing 'authorized_keys'. DeviceNetworkEvents: Network connection from curl to 127.0.0.1:18080 (Sysmon Event ID 3 if Sysmon for Linux). DeviceFileEvents: FileModified on authorized_keys with InitiatingProcessFileName=bash or sh. Shell history entries for curl and python3 commands.

  3. Test 3Modify SSH Config to Enable Root Login and Key Auth

    Expected signal: auditd SYSCALL records for open()/write() on /etc/ssh/sshd_config if auditd watch is configured. DeviceFileEvents (if MDE for Linux): FileModified for FileName=sshd_config in FolderPath=/etc/ssh. DeviceProcessEvents: Process Create for sed with ProcessCommandLine containing 'sshd_config' and 'PermitRootLogin'. Shell history entries for sed and grep commands.

  4. Test 4Add SSH Key to Non-Root User Account

    Expected signal: DeviceFileEvents: FileCreated or FileModified for FileName=authorized_keys under /home/<user>/.ssh/. DeviceProcessEvents: Process Create for useradd, ssh-keygen, cat with relevant command lines. auditd records for file operations on the authorized_keys path. Shell history for all commands executed.

  5. Test 5Simulate ESXi authorized_keys Modification

    Expected signal: DeviceFileEvents: FileCreated for FileName=authorized_keys with FolderPath containing /etc/ssh/keys-. DeviceProcessEvents: Process Create for ssh-keygen and cat with ProcessCommandLine containing the ESXi key path. On actual ESXi systems, ESXCLI audit logs and /var/log/auth.log entries would also be generated.

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

Related Detections