WPS Office Exploitation via DLL Hijack

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.

Elastic rule (View on GitHub)

  1[metadata]
  2creation_date = "2024/08/29"
  3integration = ["endpoint", "windows"]
  4maturity = "production"
  5updated_date = "2026/05/01"
  6
  7[rule]
  8author = ["Elastic"]
  9description = """
 10Identifies the load of a remote library by the WPS Office promecefpluginhost.exe executable. This may indicate the
 11successful exploitation of CVE-2024-7262 or CVE-2024-7263 via DLL hijack abusing the ksoqing custom protocol handler.
 12"""
 13from = "now-9m"
 14index = ["logs-endpoint.events.library-*", "logs-windows.sysmon_operational-*"]
 15language = "eql"
 16license = "Elastic License v2"
 17name = "WPS Office Exploitation via DLL Hijack"
 18references = [
 19    "https://www.welivesecurity.com/en/eset-research/analysis-of-two-arbitrary-code-execution-vulnerabilities-affecting-wps-office/",
 20    "https://mp.weixin.qq.com/s/F8hNyESBdKhwXkQPgtGpew",
 21]
 22risk_score = 73
 23rule_id = "ac6bc744-e82b-41ad-b58d-90654fa4ebfb"
 24severity = "high"
 25tags = [
 26    "Domain: Endpoint",
 27    "OS: Windows",
 28    "Use Case: Threat Detection",
 29    "Tactic: Initial Access",
 30    "Tactic: Execution",
 31    "Data Source: Elastic Defend",
 32    "Data Source: Sysmon",
 33    "Resources: Investigation Guide",
 34]
 35timestamp_override = "event.ingested"
 36type = "eql"
 37
 38query = '''
 39any where host.os.type == "windows" and process.name : "promecefpluginhost.exe" and
 40(
 41 (event.category == "library" and
 42  ?dll.path :
 43     ("?:\\Users\\*\\AppData\\Local\\Temp\\wps\\INetCache\\*",
 44      "\\Device\\Mup\\**", "\\\\*")) or
 45
 46  ((event.category == "process" and event.action : "Image loaded*") and
 47  ?file.path :
 48     ("?:\\Users\\*\\AppData\\Local\\Temp\\wps\\INetCache\\*",
 49      "\\Device\\Mup\\**", "\\\\*"))
 50)
 51'''
 52
 53note = """## Triage and analysis
 54
 55### Investigating WPS Office Exploitation via DLL Hijack
 56
 57#### Possible investigation steps
 58
 59- What WPS library-load path did the alert capture?
 60  - Why: WPS loading from cache, device, or UNC paths defines the likely abuse route before identity checks.
 61  - Focus: `process.name`, `process.executable`, `process.command_line`, `dll.path`, and `dll.name`.
 62  - 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.
 63
 64- Is the WPS loader the expected Kingsoft component?
 65  - Focus: `process.executable`, `process.pe.original_file_name`, `process.hash.sha256`, `process.code_signature.subject_name`, and `process.code_signature.trusted`.
 66  - 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.
 67
 68- Does the command line and parentage show "ksoqing" protocol abuse?
 69  - 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
 70  - 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.
 71
 72- Does the loaded DLL identity fit a legitimate WPS dependency?
 73  - 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`.
 74  - 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
 75  - 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.
 76
 77- If local evidence is suspicious or incomplete, do related alerts show follow-on activity?
 78  - 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.
 79    - $investigate_3
 80    - $investigate_0
 81  - Hint: if user context is missing or ambiguous, review same-host alerts for `host.id` across the last 48 hours. $investigate_1
 82  - 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.
 83
 84- 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.
 85
 86### False positive analysis
 87
 88- 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.
 89- 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.
 90- 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.
 91
 92### Response and remediation
 93
 94- 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.
 95- 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.
 96- 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.
 97- 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.
 98- 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.
 99"""
100
101setup = """## Setup
102
103This 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.
104
105Setup instructions: https://ela.st/install-elastic-defend
106
107### Additional data sources
108
109This rule also supports the following third-party data sources. For setup instructions, refer to the links below:
110
111- [Sysmon Event ID 7 - Image Loaded](https://ela.st/sysmon-event-7-setup)
112"""
113
114[rule.investigation_fields]
115field_names = [
116    "@timestamp",
117    "host.name",
118    "host.id",
119    "user.id",
120    "process.executable",
121    "process.command_line",
122    "process.entity_id",
123    "process.code_signature.subject_name",
124    "process.code_signature.trusted",
125    "process.parent.executable",
126    "process.parent.command_line",
127    "dll.path",
128    "dll.hash.sha256",
129    "dll.code_signature.subject_name",
130    "dll.code_signature.trusted",
131]
132
133[transform]
134
135[[transform.investigate]]
136label = "Alerts associated with the user"
137description = ""
138providers = [
139  [
140    { excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
141    { excluded = false, field = "user.id", queryType = "phrase", value = "{{user.id}}", valueType = "string" }
142  ]
143]
144relativeFrom = "now-48h/h"
145relativeTo = "now"
146
147[[transform.investigate]]
148label = "Alerts associated with the host"
149description = ""
150providers = [
151  [
152    { excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
153    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }
154  ]
155]
156relativeFrom = "now-48h/h"
157relativeTo = "now"
158
159[[transform.investigate]]
160label = "Process events for the WPS loader"
161description = ""
162providers = [
163  [
164    { excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" },
165    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
166    { excluded = false, field = "process.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" }
167  ]
168]
169relativeFrom = "now-1h"
170relativeTo = "now"
171
172[[transform.investigate]]
173label = "Child process events from the WPS loader"
174description = ""
175providers = [
176  [
177    { excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" },
178    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
179    { excluded = false, field = "process.parent.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" }
180  ]
181]
182relativeFrom = "now-1h"
183relativeTo = "now"
184
185[[transform.investigate]]
186label = "File events for the loaded DLL path"
187description = ""
188providers = [
189  [
190    { excluded = false, field = "event.category", queryType = "phrase", value = "file", valueType = "string" },
191    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
192    { excluded = false, field = "file.path", queryType = "phrase", value = "{{dll.path}}", valueType = "string" }
193  ]
194]
195relativeFrom = "now-1h"
196relativeTo = "now"
197
198[[rule.threat]]
199framework = "MITRE ATT&CK"
200
201[[rule.threat.technique]]
202id = "T1129"
203name = "Shared Modules"
204reference = "https://attack.mitre.org/techniques/T1129/"
205
206[[rule.threat.technique]]
207id = "T1203"
208name = "Exploitation for Client Execution"
209reference = "https://attack.mitre.org/techniques/T1203/"
210
211[rule.threat.tactic]
212id = "TA0002"
213name = "Execution"
214reference = "https://attack.mitre.org/tactics/TA0002/"
215
216[[rule.threat]]
217framework = "MITRE ATT&CK"
218
219[[rule.threat.technique]]
220id = "T1189"
221name = "Drive-by Compromise"
222reference = "https://attack.mitre.org/techniques/T1189/"
223
224[rule.threat.tactic]
225id = "TA0001"
226name = "Initial Access"
227reference = "https://attack.mitre.org/tactics/TA0001/"
228
229[[rule.threat]]
230framework = "MITRE ATT&CK"
231
232[[rule.threat.technique]]
233id = "T1574"
234name = "Hijack Execution Flow"
235reference = "https://attack.mitre.org/techniques/T1574/"
236
237[[rule.threat.technique.subtechnique]]
238id = "T1574.001"
239name = "DLL"
240reference = "https://attack.mitre.org/techniques/T1574/001/"
241
242[rule.threat.tactic]
243id = "TA0005"
244name = "Defense Evasion"
245reference = "https://attack.mitre.org/tactics/TA0005/"

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.

References

Related rules

to-top