Detection rules › Elastic
User Keychain DB Access by Self-Signed Binary
Detects when a self-signed binary (signed with native CodeSign tool) attempts to open the user's Keychain DB. This activity is not normal and should be considered suspicious. The macOS keychain is highly sought after and targeted by threat actors as it contains sensitive credential data that can be used to further compromise a user or environment.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Credential Access |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| macOS | ESF event open (NOTIFY): Fires after the kernel grants a process access to open a file. |
Rule body
[rule]
description = """
Detects when a self-signed binary (signed with native CodeSign tool) attempts to open the user's Keychain DB. This
activity is not normal and should be considered suspicious. The macOS keychain is highly sought after and targeted by
threat actors as it contains sensitive credential data that can be used to further compromise a user or environment.
"""
id = "af71383d-f843-468a-b365-c202a547bc65"
license = "Elastic License v2"
name = "User Keychain DB Access by Self-Signed Binary"
os_list = ["macos"]
reference = ["https://attack.mitre.org/techniques/T1555/001/", "https://github.com/MythicAgents/poseidon"]
version = "1.0.14"
query = '''
file where event.action == "open" and file.name like "login.keychain-db" and
process.code_signature.trusted == false and
process.code_signature.signing_id regex~ """[A-Za-z0-9\_\s]{2,}\-[a-z0-9]{40}""" and
not process.executable like ("/opt/homebrew/*", "/usr/local/Cellar/*") and
not process.code_signature.signing_id like~ ("python-*",
"python3-*",
"apphost-*",
"laclient-*",
"emulator-*",
"eclipse-*",
"mksdcard-*",
"MicrosoftSqlToolsServiceLayer-*",
"binary-*",
"ruby-*",
"rg-*",
"jspawnhelper-*",
"dotnet-*") and
not Effective_process.executable like ("/Users/*/Library/Application Support/Claude/claude-code/*/claude.app/Contents/MacOS/claude", "/Applications/Claude.app/Contents/MacOS/Claude") and
not process.executable == "/usr/local/bin/symfony"
'''
min_endpoint_version = "8.11.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1555"
name = "Credentials from Password Stores"
reference = "https://attack.mitre.org/techniques/T1555/"
[[threat.technique.subtechnique]]
id = "T1555.001"
name = "Keychain"
reference = "https://attack.mitre.org/techniques/T1555/001/"
[threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"
[internal]
min_endpoint_version = "8.11.0"
Stages and Predicates
Stage 1: file
file where event.action == "open" and file.name like "login.keychain-db" and
process.code_signature.trusted == false and
process.code_signature.signing_id regex~ """[A-Za-z0-9\_\s]{2,}\-[a-z0-9]{40}""" and
not process.executable like ("/opt/homebrew/*", "/usr/local/Cellar/*") and
not process.code_signature.signing_id like~ ("python-*",
"python3-*",
"apphost-*",
"laclient-*",
"emulator-*",
"eclipse-*",
"mksdcard-*",
"MicrosoftSqlToolsServiceLayer-*",
"binary-*",
"ruby-*",
"rg-*",
"jspawnhelper-*",
"dotnet-*") and
not Effective_process.executable like ("/Users/*/Library/Application Support/Claude/claude-code/*/claude.app/Contents/MacOS/claude", "/Applications/Claude.app/Contents/MacOS/Claude") and
not process.executable == "/usr/local/bin/symfony"
Exclusions
The rule actively suppresses these predicates.
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"open" |
file.name | wildcard |
| field:"file.name" kind:wildcard value:"login.keychain-db" |
process.code_signature.signing_id | regex_match |
| field:"process.code_signature.signing_id" kind:regex_match value:"[A-Za-z0-9\_\s]{2,}\-[a-z0-9]{40}" |
process.code_signature.trusted | eq |
| field:"process.code_signature.trusted" kind:eq value:"false" |