Execution (TA0002)(external, opens in a new tab or window)
Initial Access (TA0001)(external, opens in a new tab or window)
Defense Evasion (TA0005)(external, opens in a new tab or window)
Command and Control (TA0011)(external, opens in a new tab or window)
text code block:FROM logs-endpoint.events.process-* METADATA _id, _version, _index | EVAL is_pkg_install = CASE( // npm process.parent.name == "node.exe" AND ( process.parent.command_line LIKE "*npx-cli.js*" OR process.parent.command_line LIKE "*npm-cli.js*" OR process.parent.command_line LIKE """*\\npm-cache\\_npx\\*""" ), true, false ) | EVAL cmdline_lower = TO_LOWER(process.command_line) | EVAL is_encoded_powershell = CASE( TO_LOWER(process.name) == "powershell.exe" AND ( cmdline_lower LIKE "* -enc*" OR cmdline_lower LIKE "* -en *" OR cmdline_lower LIKE "* -ec *" OR cmdline_lower LIKE "* -ec:*" OR cmdline_lower LIKE "*frombase64*" ), true, false ) // plain -Command / dot-sourced / no-flag download cradles that skip -EncodedCommand entirely | EVAL is_download_cradle = CASE( process.name == "powershell.exe" AND ( cmdline_lower LIKE "*downloadstring*" OR cmdline_lower LIKE "*downloadfile*" OR cmdline_lower LIKE "*downloaddata*" OR cmdline_lower LIKE "*net.webclient*" OR cmdline_lower LIKE "*new-object*webclient*" OR cmdline_lower LIKE "*invoke-webrequest*" OR cmdline_lower LIKE "* iwr *" OR cmdline_lower LIKE "* iwr(*" OR cmdline_lower LIKE "*invoke-restmethod*" OR cmdline_lower LIKE "* irm *" OR cmdline_lower LIKE "* irm(*" OR cmdline_lower LIKE "*invoke-expression*" OR cmdline_lower LIKE "* iex *" OR cmdline_lower LIKE "* iex(*" OR cmdline_lower LIKE "*start-bitstransfer*" OR cmdline_lower LIKE "*bitstransfer*" ), true, false ) | EVAL is_susp_powershell = CASE(is_encoded_powershell OR is_download_cradle, true, false) | WHERE process.Ext.ancestry IS NOT NULL AND (is_susp_powershell OR is_pkg_install) // Capture entity_ids for package install parent processes | EVAL all_entity_id = CASE(is_pkg_install, process.parent.entity_id, "null") // Collect all package install entity_ids globally | INLINE STATS all_pkg_entity_ids = VALUES(all_entity_id), all_pkg_cmdline = VALUES(process.parent.command_line) WHERE all_entity_id != "null" by host.id // Find which package install entity_ids appear in this process's ancestry | EVAL Esql.pkg_ancestor_ids = MV_INTERSECTION(all_pkg_entity_ids, process.Ext.ancestry) // susp powershell (encoded or download cradle) and descended from an npm package install process | WHERE Esql.pkg_ancestor_ids IS NOT NULL AND is_susp_powershell | KEEP _id, _version, _index, data_stream.namespace, host.id, host.name, user.name, process.entity_id, process.executable, process.command_line, process.parent.executable, all_pkg_cmdline, is_encoded_powershell, is_download_cradle
Install detection rules in Elastic Security
Detect Suspicious PowerShell from npm Package Install 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).