Credential Access (TA0006)(external, opens in a new tab or window)
Persistence (TA0003)(external, opens in a new tab or window)
text code block:FROM logs-endpoint.events.process-*, logs-endpoint.events.file-* METADATA _id, _index, _version // Normalize sensitive filenames for case-insensitive matching. | EVAL sensitive_name = TO_LOWER(file.name) // Identify processes launched by VS Code or Cursor. | EVAL is_editor_spawn = event.dataset == "endpoint.events.process" AND process.parent.name IN ( "Code", "Code.exe", "Code Helper", "Code Helper (Plugin)", "code", "Cursor", "Cursor.exe", "Cursor Helper", "Cursor Helper (Plugin)", "cursor" ) // Identify sensitive file-open events. | EVAL is_sensitive_read = event.dataset == "endpoint.events.file" AND MV_CONTAINS(event.action, "open") AND sensitive_name IN ( "logins.json", "login data", "local state", "signons.sqlite", "cookies", "cookies.sqlite", "cookies.binarycookies", "token", "credentials.db", "credentials", "credentials.toml", "access_tokens.db", "accesstokens.json", "azureprofile.json", "rdcman.settings", "keepass.config.xml", ".npmrc", "auth.json", ".vault-token", "application_default_credentials.json" ) // Retain editor-associated process events and sensitive file opens. | WHERE host.id IS NOT NULL AND (is_editor_spawn OR is_sensitive_read) // Capture editor parent entity IDs as ancestry anchors. | EVAL editor_anchor_id = CASE( is_editor_spawn, process.parent.entity_id, NULL ) // Share editor ancestor IDs within each host. | INLINE STATS editor_anchor_ids = VALUES(editor_anchor_id) BY host.id // Retain sensitive file opens with valid process identity and ancestry. | WHERE is_sensitive_read AND process.Ext.ancestry IS NOT NULL AND process.entity_id IS NOT NULL // Match file-opening processes to VS Code or Cursor ancestors. | EVAL editor_ancestor_ids = MV_INTERSECTION( editor_anchor_ids, process.Ext.ancestry ) | WHERE editor_ancestor_ids IS NOT NULL // Require at least 2 distinct sensitive filenames per process. | INLINE STATS unique_sensitive_files = COUNT_DISTINCT(sensitive_name), Esql.file_names = VALUES(sensitive_name) BY host.id, process.entity_id | WHERE unique_sensitive_files >= 2 // Preserve event-level investigation context. | KEEP @timestamp, host.id, host.name, host.os.type, user.name, event.action, event.outcome, file.name, Esql.file_names, file.path, unique_sensitive_files, process.entity_id, process.name, process.executable, editor_ancestor_ids, _id, _index, _version
Install detection rules in Elastic Security
Detect Multiple Credential Access by VS Code or Cursor IDE Descendant in the Elastic Security detection engine by installing this rule into your Elastic Stack.
To setup this rule, check out the installation guide for Prebuilt Security Detection Rules(external, opens in a new tab or window).