[metadata] creation_date = "2024/08/29" integration = ["endpoint", "windows"] maturity = "production" updated_date = "2026/05/01" [rule] author = ["Elastic"] description = """ Identifies the load of a remote library by the WPS Office promecefpluginhost.exe executable. This may indicate the successful exploitation of CVE-2024-7262 or CVE-2024-7263 via DLL hijack abusing the ksoqing custom protocol handler. """ from = "now-9m" index = ["logs-endpoint.events.library-*", "logs-windows.sysmon_operational-*"] language = "eql" license = "Elastic License v2" name = "WPS Office Exploitation via DLL Hijack" references = [ "https://www.welivesecurity.com/en/eset-research/analysis-of-two-arbitrary-code-execution-vulnerabilities-affecting-wps-office/", "https://mp.weixin.qq.com/s/F8hNyESBdKhwXkQPgtGpew", ] risk_score = 73 rule_id = "ac6bc744-e82b-41ad-b58d-90654fa4ebfb" severity = "high" tags = [ "Domain: Endpoint", "OS: Windows", "Use Case: Threat Detection", "Tactic: Initial Access", "Tactic: Execution", "Data Source: Elastic Defend", "Data Source: Sysmon", "Resources: Investigation Guide", ] timestamp_override = "event.ingested" type = "eql" query = ''' any where host.os.type == "windows" and process.name : "promecefpluginhost.exe" and ( (event.category == "library" and ?dll.path : ("?:\\Users\\*\\AppData\\Local\\Temp\\wps\\INetCache\\*", "\\Device\\Mup\\**", "\\\\*")) or ((event.category == "process" and event.action : "Image loaded*") and ?file.path : ("?:\\Users\\*\\AppData\\Local\\Temp\\wps\\INetCache\\*", "\\Device\\Mup\\**", "\\\\*")) ) ''' note = """## Triage and analysis ### Investigating WPS Office Exploitation via DLL Hijack #### Possible investigation steps - What WPS library-load path did the alert capture? - Why: WPS loading from cache, device, or UNC paths defines the likely abuse route before identity checks. - Focus: `process.name`, `process.executable`, `process.command_line`, `dll.path`, and `dll.name`. - Implication: escalate when "promecefpluginhost.exe" loads from "Temp\\wps\\INetCache", "\\Device\\Mup\\", or a UNC path outside the WPS install tree; lower suspicion only when normalized `dll.path` resolves to the same Kingsoft-controlled component path as the loader and no protocol-abuse arguments appear. - Is the WPS loader the expected Kingsoft component? - Focus: `process.executable`, `process.pe.original_file_name`, `process.hash.sha256`, `process.code_signature.subject_name`, and `process.code_signature.trusted`. - Implication: escalate when the loader is unsigned, renamed, outside the installed WPS Office directory, or signed by an unexpected publisher; lower suspicion when identity matches a stable Kingsoft WPS component, but continue because a trusted loader can still load an attacker DLL. - Does the command line and parentage show "ksoqing" protocol abuse? - Focus: loader process events for `host.id` and `process.entity_id`, then `process.command_line`, `process.parent.executable`, and `process.parent.command_line`. $investigate_2 - Implication: escalate when "wps.exe" or "et.exe" opens user content with arguments exposing "ksoqing", plugin-service paths, encoded paths, or remote paths; lower suspicion only when parentage and arguments match a recognized controlled-share launch without document-driven protocol handling. - Does the loaded DLL identity fit a legitimate WPS dependency? - Focus: `dll.hash.sha256`, `dll.pe.original_file_name`, `dll.code_signature.subject_name`, `dll.code_signature.trusted`, and `dll.Ext.relative_file_creation_time`. - Hint: if endpoint file telemetry is available, use `host.id` and `dll.path` to identify the writer or rename event. Missing file telemetry is unresolved, not benign. $investigate_4 - Implication: escalate when the DLL is unsigned, non-Kingsoft, recently created, recently renamed in `dll.Ext.relative_file_name_modify_time`, or loaded as an unexpected WPS dependency from a remote share; if recency metadata is absent, rely on path, hash, signer, and parentage. - If local evidence is suspicious or incomplete, do related alerts show follow-on activity? - Focus: child process events from the WPS loader and related alerts for `user.id`, especially WPS document execution, additional library loads, downloader behavior, or child-process alerts from the same workstation. - $investigate_3 - $investigate_0 - Hint: if user context is missing or ambiguous, review same-host alerts for `host.id` across the last 48 hours. $investigate_1 - Implication: broaden scope when the same user or host shows repeated WPS-triggered loads, the same `dll.hash.sha256`, the same suspicious path pattern, or follow-on execution; lower urgency when isolated, but do not close if local path or DLL identity remains unresolved. - Escalate when load path, loader identity, protocol or parentage, DLL signer/hash/recency, or related-alert evidence supports attacker-controlled DLL loading from INetCache, a device path, or UNC path; close only when the same evidence binds to one authorized validation, sandbox, or controlled-share workflow with no contradictory artifacts; preserve artifacts and escalate if evidence is mixed or incomplete. ### False positive analysis - Authorized vulnerability validation or sandbox detonation can reproduce this load pattern. Confirm scope with outside records when available, and require telemetry alignment on `host.id`, `user.id`, `process.executable`, `process.command_line`, `dll.path`, `dll.hash.sha256`, and `dll.code_signature.subject_name`. If not a known test, default to suspicious. - Controlled software distribution or application virtualization can serve WPS components from a managed share. Confirm `dll.path` stays on that exact share, `dll.hash.sha256` and `dll.code_signature.subject_name` match the expected Kingsoft component, and parentage lacks document-driven protocol or plugin-path arguments. Without inventories, use recurrence only to validate the same stable share, hash, signer, `process.executable`, `host.id`, and `user.id` workflow before exceptioning. - Build exceptions only from the minimum confirmed workflow: stable `process.executable`, `process.code_signature.subject_name`, `dll.path`, `dll.hash.sha256`, `dll.code_signature.subject_name`, and bounded `host.id` or `user.id` scope. Avoid exceptions on `process.name` alone for "promecefpluginhost.exe", "Temp\\wps\\INetCache", or UNC prefixes. ### Response and remediation - If confirmed benign, record the exact workflow evidence first: loader identity, `process.command_line`, DLL path/hash/signer, and bounded `host.id` or `user.id` scope. Then reverse temporary containment and create an exception only for that bounded workflow. - If suspicious but unconfirmed, preserve the alert, host/user scope, `process.entity_id`, parent lineage, `dll.path`, `dll.hash.sha256`, and DLL signer/recency evidence before containment. Use reversible actions first, such as restricting a non-business remote share named in `dll.path`, quarantining a recovered lure document, or temporarily restricting WPS on the affected host; isolate only when follow-on execution or repeated malicious loads justify the interruption. - If confirmed malicious, isolate the host through endpoint response after evidence preservation, then terminate the WPS loader chain if it is still active and block confirmed malicious `dll.hash.sha256` values and remote shares from `dll.path`. If endpoint response is unavailable, hand off the preserved process, DLL, host, and user identifiers to the team that can contain the system or share. - Eradicate only artifacts tied to the investigation: remove the malicious DLL, recovered lure document, and staged WPS abuse files after scope review for the same `dll.hash.sha256`, `dll.path`, WPS parentage, `host.id`, and `user.id`. Upgrade WPS Office to a vendor-supported release that remediates both CVE-2024-7262 and CVE-2024-7263. - Post-incident hardening: restrict WPS Office library loads from user-writable and UNC paths where feasible, retain process and library-load telemetry, and document any adjacent variant observed during triage, such as alternate WPS protocol arguments or related "promecefpluginhost.exe" load paths. """ setup = """## Setup This rule is designed for data generated by [Elastic Defend](https://www.elastic.co/security/endpoint-security), which provides native endpoint detection and response, along with event enrichments designed to work with our detection rules. Setup instructions: https://ela.st/install-elastic-defend ### Additional data sources This rule also supports the following third-party data sources. For setup instructions, refer to the links below: - [Sysmon Event ID 7 - Image Loaded](https://ela.st/sysmon-event-7-setup) """ [rule.investigation_fields] field_names = [ "@timestamp", "host.name", "host.id", "user.id", "process.executable", "process.command_line", "process.entity_id", "process.code_signature.subject_name", "process.code_signature.trusted", "process.parent.executable", "process.parent.command_line", "dll.path", "dll.hash.sha256", "dll.code_signature.subject_name", "dll.code_signature.trusted", ] [transform] [[transform.investigate]] label = "Alerts associated with the user" description = "" providers = [ [ { excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" }, { excluded = false, field = "user.id", queryType = "phrase", value = "{{user.id}}", valueType = "string" } ] ] relativeFrom = "now-48h/h" relativeTo = "now" [[transform.investigate]] label = "Alerts associated with the host" description = "" providers = [ [ { excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" }, { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" } ] ] relativeFrom = "now-48h/h" relativeTo = "now" [[transform.investigate]] label = "Process events for the WPS loader" description = "" providers = [ [ { excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" }, { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }, { excluded = false, field = "process.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" } ] ] relativeFrom = "now-1h" relativeTo = "now" [[transform.investigate]] label = "Child process events from the WPS loader" description = "" providers = [ [ { excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" }, { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }, { excluded = false, field = "process.parent.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" } ] ] relativeFrom = "now-1h" relativeTo = "now" [[transform.investigate]] label = "File events for the loaded DLL path" description = "" providers = [ [ { excluded = false, field = "event.category", queryType = "phrase", value = "file", valueType = "string" }, { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }, { excluded = false, field = "file.path", queryType = "phrase", value = "{{dll.path}}", valueType = "string" } ] ] relativeFrom = "now-1h" relativeTo = "now" [[rule.threat]] framework = "MITRE ATT&CK" [[rule.threat.technique]] id = "T1129" name = "Shared Modules" reference = "https://attack.mitre.org/techniques/T1129/" [[rule.threat.technique]] id = "T1203" name = "Exploitation for Client Execution" reference = "https://attack.mitre.org/techniques/T1203/" [rule.threat.tactic] id = "TA0002" name = "Execution" reference = "https://attack.mitre.org/tactics/TA0002/" [[rule.threat]] framework = "MITRE ATT&CK" [[rule.threat.technique]] id = "T1189" name = "Drive-by Compromise" reference = "https://attack.mitre.org/techniques/T1189/" [rule.threat.tactic] id = "TA0001" name = "Initial Access" reference = "https://attack.mitre.org/tactics/TA0001/" [[rule.threat]] framework = "MITRE ATT&CK" [[rule.threat.technique]] id = "T1574" name = "Hijack Execution Flow" reference = "https://attack.mitre.org/techniques/T1574/" [[rule.threat.technique.subtechnique]] id = "T1574.001" name = "DLL" reference = "https://attack.mitre.org/techniques/T1574/001/" [rule.threat.tactic] id = "TA0005" name = "Defense Evasion" reference = "https://attack.mitre.org/tactics/TA0005/"