Access to Keychain Credentials Directories

Adversaries may collect the keychain storage data from a system to acquire credentials. Keychains are the built-in way for macOS to keep track of users' passwords and credentials for many services and features such as WiFi passwords, websites, secure notes and certificates.

Elastic rule (View on GitHub)

 1[metadata]
 2creation_date = "2020/08/14"
 3integration = ["endpoint"]
 4maturity = "production"
 5min_stack_comments = "New fields added: required_fields, related_integrations, setup"
 6min_stack_version = "8.3.0"
 7updated_date = "2023/02/22"
 8
 9[rule]
10author = ["Elastic"]
11description = """
12Adversaries may collect the keychain storage data from a system to acquire credentials. Keychains are the built-in way
13for macOS to keep track of users' passwords and credentials for many services and features such as WiFi passwords,
14websites, secure notes and certificates.
15"""
16from = "now-9m"
17index = ["auditbeat-*", "logs-endpoint.events.*"]
18language = "eql"
19license = "Elastic License v2"
20name = "Access to Keychain Credentials Directories"
21note = """## Setup
22
23If enabling an EQL rule on a non-elastic-agent index (such as beats) for versions <8.2, events will not define `event.ingested` and default fallback for EQL rules was not added until 8.2, so you will need to add a custom pipeline to populate `event.ingested` to @timestamp for this rule to work.
24"""
25references = [
26    "https://objective-see.com/blog/blog_0x25.html",
27    "https://securelist.com/calisto-trojan-for-macos/86543/",
28]
29risk_score = 73
30rule_id = "96e90768-c3b7-4df6-b5d9-6237f8bc36a8"
31severity = "high"
32tags = ["Elastic", "Host", "macOS", "Threat Detection", "Credential Access"]
33timestamp_override = "event.ingested"
34type = "eql"
35
36query = '''
37process where host.os.type == "macos" and event.type in ("start", "process_started") and
38  process.args :
39    (
40      "/Users/*/Library/Keychains/*",
41      "/Library/Keychains/*",
42      "/Network/Library/Keychains/*",
43      "System.keychain",
44      "login.keychain-db",
45      "login.keychain"
46    ) and
47    not process.args : ("find-certificate",
48                      "add-trusted-cert",
49                      "set-keychain-settings",
50                      "delete-certificate",
51                      "/Users/*/Library/Keychains/openvpn.keychain-db",
52                      "show-keychain-info",
53                      "lock-keychain",
54                      "set-key-partition-list",
55                      "import",
56                      "find-identity") and
57    not process.parent.executable :
58      (
59        "/Applications/OpenVPN Connect/OpenVPN Connect.app/Contents/MacOS/OpenVPN Connect",
60        "/Applications/Microsoft Defender.app/Contents/MacOS/wdavdaemon_enterprise.app/Contents/MacOS/wdavdaemon_enterprise",
61        "/opt/jc/bin/jumpcloud-agent"
62      ) and
63    not process.executable : "/opt/jc/bin/jumpcloud-agent"
64'''
65
66
67[[rule.threat]]
68framework = "MITRE ATT&CK"
69[[rule.threat.technique]]
70id = "T1555"
71name = "Credentials from Password Stores"
72reference = "https://attack.mitre.org/techniques/T1555/"
73[[rule.threat.technique.subtechnique]]
74id = "T1555.001"
75name = "Keychain"
76reference = "https://attack.mitre.org/techniques/T1555/001/"
77
78
79
80[rule.threat.tactic]
81id = "TA0006"
82name = "Credential Access"
83reference = "https://attack.mitre.org/tactics/TA0006/"

Setup

If enabling an EQL rule on a non-elastic-agent index (such as beats) for versions <8.2, events will not define event.ingested and default fallback for EQL rules was not added until 8.2, so you will need to add a custom pipeline to populate event.ingested to @timestamp for this rule to work.

to-top