Skip to content

Commit e9400d9

Browse files
PTC Windchill (#4124)
* add windchill analytics * indent --------- Co-authored-by: Bhavin Patel <bhavin.j.patel91@gmail.com>
1 parent 7870ff5 commit e9400d9

5 files changed

Lines changed: 261 additions & 0 deletions

File tree

data_sources/windchill_log4j.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
name: Windchill Log4j
2+
id: f33af1fb-df5c-45c5-b8fd-20b0bbfb5415
3+
version: 1
4+
creation_date: '2026-06-14'
5+
modification_date: '2026-06-14'
6+
author: Nasreddine Bencherchali, Splunk
7+
description: PTC Windchill MethodServer log4j logs containing servlet request and method context activity from Windchill application components.
8+
mitre_components:
9+
- Application Log Content
10+
- Network Traffic Content
11+
- Response Metadata
12+
source: not_applicable
13+
sourcetype: log4j
14+
supported_TA: []
15+
fields:
16+
- _time
17+
- _raw
18+
- log_level
19+
- thread
20+
- logger
21+
- src_ip
22+
- uri_path
23+
- query_string
24+
- http_method
25+
- status
26+
example_log: '2026-03-26 19:12:00,053 ERROR [ajp-nio-127.0.0.1-10660-exec-2] wt.servlet.ServletRequestMonitor.request - 2026-03-26 19:12:00.049 +0530, q4io1jf;mn7i98pd;62288;2anc4x;4122, -, 10.10.2.3, /Windchill/servlet/WindchillGW/GW/run, c=whoami, GET, 500, 0.0037325, 0.004020767'
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
name: PTC Windchill Gateway Command Execution
2+
id: d725b390-fe86-47df-b9a1-57497915403e
3+
version: 1
4+
creation_date: '2026-06-14'
5+
modification_date: '2026-06-14'
6+
author: Nasreddine Bencherchali, Splunk
7+
status: production
8+
type: Anomaly
9+
description: |
10+
This analytic detects Windchill MethodServer log4j events showing suspicious `c=` command execution or `p=` file read parameters sent to Windchill gateway paths associated with CVE-2026-4681 exploitation.
11+
PTC identifies `run?c=`, `run?p=`, `.jsp?c=`, and `.jsp?p=` request patterns as indicators to monitor during Windchill and FlexPLM exploitation response.
12+
Successful activity may allow an unauthenticated attacker to execute operating system commands or read files through a weaponized gateway or JSP component.
13+
data_source:
14+
- Windchill Log4j
15+
search: |-
16+
`windchill_log4j`
17+
("WindchillGW/GW/run" OR "WindchillAuthGW/GW/run" OR "/GW/run?" OR "run?c=" OR "run?p=" OR ".jsp?c=" OR ".jsp?p=" OR "dpr_")
18+
| rex field=_raw "^(?:[^:\r\n]+:)?(?<log_ts>\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2},\d{3})\s+(?<log_level>\w+)\s+\[(?<thread>[^\]]+)\]\s+(?<logger>\S+)\s+-\s+(?<payload>.*)$"
19+
| search logger IN ("wt.servlet.ServletRequestMonitor.request", "wt.method.MethodContextMonitor.contexts.servletRequest")
20+
| rex field=payload "^(?<event_ts>\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2}\.\d{3})\s+(?<event_tz>[+\-]\d{4}),\s+(?<rest>.*)$"
21+
| eval parts=split(rest,", ")
22+
| eval event_type=case(logger="wt.servlet.ServletRequestMonitor.request","servlet_request",logger="wt.method.MethodContextMonitor.contexts.servletRequest","method_context_servlet_request",true(),"other")
23+
| eval src_ip=case(event_type="servlet_request",mvindex(parts,2),event_type="method_context_servlet_request",mvindex(parts,5))
24+
| eval uri_path=case(event_type="servlet_request",mvindex(parts,3),event_type="method_context_servlet_request",mvindex(parts,8))
25+
| eval query_string=if(event_type="servlet_request",mvindex(parts,4),null())
26+
| eval http_method=if(event_type="servlet_request",mvindex(parts,5),null())
27+
| eval status=if(event_type="servlet_request",tonumber(mvindex(parts,6)),null())
28+
| rex field=uri_path "^(?<uri_only>[^\?]+)(?:\?(?<uri_query>.*))?$"
29+
| eval query_string=if(query_string="-",null(),query_string)
30+
| eval query_string=coalesce(query_string,uri_query)
31+
| rex field=query_string "(?i)(?:^|&)(?<query_param>[cp])=(?<query_value>[^&]*)"
32+
| eval query_param=lower(query_param), query_value=urldecode(replace(query_value,"\+","%20"))
33+
| where isnotnull(uri_only) AND isnotnull(query_param)
34+
| where (match(uri_only,"(?i)(^|/)GW/run$") OR match(uri_only,"(?i)/servlet/(WindchillGW|WindchillAuthGW)/GW/run$") OR match(uri_only,"(?i)(^|/)dpr_[0-9a-f]{8}\.jsp$")) AND (query_param="c" OR query_param="p")
35+
| where NOT (query_param="c" AND match(query_value,"(?i)^echo(\s|20)+GW_READY_OK$"))
36+
| eval activity=case(query_param="c","command_execution_parameter",query_param="p","file_read_parameter",true(),"unknown")
37+
| eval src=src_ip
38+
39+
| stats count min(_time) as firstTime
40+
max(_time) as lastTime
41+
values(log_level) as log_level
42+
values(logger) as logger
43+
values(http_method) as http_method
44+
values(status) as status
45+
values(uri_only) as uri_path
46+
values(query_string) as query_string
47+
by src activity query_param query_value
48+
49+
| `security_content_ctime(firstTime)`
50+
| `security_content_ctime(lastTime)`
51+
| `ptc_windchill_gateway_command_execution_filter`
52+
how_to_implement: |
53+
To implement this analytic, ingest PTC Windchill MethodServer log4j logs into Splunk with sourcetype `log4j`.
54+
Update the `windchill_log4j` macro to include the appropriate index constraints for your environment.
55+
The analytic expects log entries from the `wt.servlet.ServletRequestMonitor.request` and `wt.method.MethodContextMonitor.contexts.servletRequest` loggers and parses embedded servlet URI, query parameter, source IP, HTTP method, and status fields.
56+
known_false_positives: |
57+
Requests to `GW/run` or randomly named `dpr_<8 hex>.jsp` files with `c=` or `p=` parameters should not be expected during normal Windchill operation.
58+
Validate whether red-team testing, vulnerability scanning, or incident response replay generated the activity before closing as benign.
59+
references:
60+
- https://www.ptc.com/en/about/trust-center/advisory-center/active-advisories/windchill-flexplm-critical-vulnerability
61+
- https://nvd.nist.gov/vuln/detail/CVE-2026-4681
62+
- https://www.cisa.gov/news-events/ics-advisories/icsa-26-085-03
63+
drilldown_searches:
64+
- name: View the detection results for - "$src$"
65+
search: '%original_detection_search% | search src = "$src$"'
66+
earliest_offset: $info_min_time$
67+
latest_offset: $info_max_time$
68+
- name: View risk events for the last 7 days for - "$src$"
69+
search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$src$") | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`'
70+
earliest_offset: 7d
71+
latest_offset: "0"
72+
intermediate_findings:
73+
entities:
74+
- field: src
75+
type: system
76+
score: 20
77+
message: Potential PTC Windchill gateway command or file read activity detected from $src$.
78+
threat_objects:
79+
- field: src
80+
type: ip_address
81+
analytic_story:
82+
- PTC Windchill Exploitation
83+
asset_type: Web Application
84+
cve:
85+
- CVE-2026-4681
86+
mitre_attack_id:
87+
- T1190
88+
- T1059
89+
- T1005
90+
product:
91+
- Splunk Enterprise
92+
- Splunk Enterprise Security
93+
- Splunk Cloud
94+
category: application
95+
security_domain: network
96+
tests:
97+
- name: True Positive Test
98+
attack_data:
99+
- data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/emerging_threats/windchill/windchill_exploitation.log
100+
source: not_applicable
101+
sourcetype: log4j
102+
test_type: unit
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
name: PTC Windchill GW READY OK Probe
2+
id: 2f37ab99-5eae-44c4-a6bc-15b6d9787a3d
3+
version: 1
4+
creation_date: '2026-06-14'
5+
modification_date: '2026-06-14'
6+
author: Nasreddine Bencherchali, Splunk
7+
status: production
8+
type: Anomaly
9+
description: |
10+
This analytic detects Windchill MethodServer log4j events that contain the CVE-2026-4681 exploitation probe `run?c=echo%20GW_READY_OK`.
11+
PTC identifies `GW_READY_OK` and related `run?c=` activity as log indicators associated with Windchill and FlexPLM exploitation.
12+
This behavior is significant because attackers use the probe to confirm that a staged gateway component is reachable before sending operating system commands through the same `c=` parameter.
13+
data_source:
14+
- Windchill Log4j
15+
search: |-
16+
`windchill_log4j`
17+
("GW_READY_OK" OR "run?c=echo%20GW_READY_OK" OR "c=echo%20GW_READY_OK")
18+
| rex field=_raw "^(?:[^:\r\n]+:)?(?<log_ts>\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2},\d{3})\s+(?<log_level>\w+)\s+\[(?<thread>[^\]]+)\]\s+(?<logger>\S+)\s+-\s+(?<payload>.*)$"
19+
| search logger IN ("wt.servlet.ServletRequestMonitor.request", "wt.method.MethodContextMonitor.contexts.servletRequest")
20+
| rex field=payload "^(?<event_ts>\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2}\.\d{3})\s+(?<event_tz>[+\-]\d{4}),\s+(?<rest>.*)$"
21+
| eval parts=split(rest,", ")
22+
| eval event_type=case(logger="wt.servlet.ServletRequestMonitor.request","servlet_request",logger="wt.method.MethodContextMonitor.contexts.servletRequest","method_context_servlet_request",true(),"other")
23+
| eval src_ip=case(event_type="servlet_request",mvindex(parts,2),event_type="method_context_servlet_request",mvindex(parts,5))
24+
| eval uri_path=case(event_type="servlet_request",mvindex(parts,3),event_type="method_context_servlet_request",mvindex(parts,8))
25+
| eval query_string=if(event_type="servlet_request",mvindex(parts,4),null())
26+
| eval http_method=if(event_type="servlet_request",mvindex(parts,5),null())
27+
| eval status=if(event_type="servlet_request",tonumber(mvindex(parts,6)),null())
28+
| rex field=uri_path "^(?<uri_only>[^\?]+)(?:\?(?<uri_query>.*))?$"
29+
| eval query_string=if(query_string="-",null(),query_string)
30+
| eval query_string=coalesce(query_string,uri_query)
31+
| rex field=query_string "(?i)(?:^|&)(?<query_param>[cp])=(?<query_value>[^&]*)"
32+
| eval query_param=lower(query_param), query_value=urldecode(replace(query_value,"\+","%20"))
33+
| where query_param="c" AND match(query_value,"(?i)^echo(\s|20)+GW_READY_OK$")
34+
| eval src=src_ip, activity="gw_ready_ok_probe"
35+
36+
| stats count min(_time) as firstTime
37+
max(_time) as lastTime
38+
values(log_level) as log_level
39+
values(logger) as logger
40+
values(http_method) as http_method
41+
values(status) as status
42+
values(uri_only) as uri_path
43+
values(query_string) as query_string
44+
by src activity query_param query_value
45+
46+
| `security_content_ctime(firstTime)`
47+
| `security_content_ctime(lastTime)`
48+
| `ptc_windchill_gw_ready_ok_probe_filter`
49+
how_to_implement: |
50+
To implement this analytic, ingest PTC Windchill MethodServer log4j logs into Splunk with sourcetype `log4j`.
51+
Update the `windchill_log4j` macro to include the appropriate index constraints for your environment.
52+
The analytic expects log entries from the `wt.servlet.ServletRequestMonitor.request` and `wt.method.MethodContextMonitor.contexts.servletRequest` loggers.
53+
known_false_positives: |
54+
This probe string is specific to the PTC-published Windchill exploitation indicators. False positives should be rare. Validate whether any internal testing, incident response activity, or vendor diagnostics intentionally generated `GW_READY_OK` requests.
55+
references:
56+
- https://www.ptc.com/en/about/trust-center/advisory-center/active-advisories/windchill-flexplm-critical-vulnerability
57+
- https://nvd.nist.gov/vuln/detail/CVE-2026-4681
58+
- https://www.cisa.gov/news-events/ics-advisories/icsa-26-085-03
59+
drilldown_searches:
60+
- name: View the detection results for - "$src$"
61+
search: '%original_detection_search% | search src = "$src$"'
62+
earliest_offset: $info_min_time$
63+
latest_offset: $info_max_time$
64+
- name: View risk events for the last 7 days for - "$src$"
65+
search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$src$") | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`'
66+
earliest_offset: 7d
67+
latest_offset: "0"
68+
intermediate_findings:
69+
entities:
70+
- field: src
71+
type: system
72+
score: 20
73+
message: PTC Windchill GW READY OK exploitation probe detected from $src$.
74+
threat_objects:
75+
- field: src
76+
type: ip_address
77+
analytic_story:
78+
- PTC Windchill Exploitation
79+
asset_type: Web Application
80+
cve:
81+
- CVE-2026-4681
82+
mitre_attack_id:
83+
- T1190
84+
- T1059
85+
product:
86+
- Splunk Enterprise
87+
- Splunk Enterprise Security
88+
- Splunk Cloud
89+
category: application
90+
security_domain: network
91+
tests:
92+
- name: True Positive Test
93+
attack_data:
94+
- data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/emerging_threats/windchill/windchill_exploitation.log
95+
source: not_applicable
96+
sourcetype: log4j
97+
test_type: unit

macros/windchill_log4j.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
name: windchill_log4j
2+
id: 0b89b4b9-f91d-447c-abe9-24d9c5ff3ae2
3+
version: 1
4+
creation_date: '2026-06-14'
5+
modification_date: '2026-06-14'
6+
author: Nasreddine Bencherchali, Splunk Threat Research Team
7+
description: customer specific splunk configurations(eg- index, source, sourcetype). Replace the macro definition with configurations for your Splunk Environment.
8+
definition: sourcetype=log4j
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: PTC Windchill Exploitation
2+
id: 3edf40e6-d641-48e1-a6d2-0eed37284dd5
3+
version: 1
4+
creation_date: '2026-06-14'
5+
modification_date: '2026-06-14'
6+
author: Nasreddine Bencherchali, Splunk
7+
status: production
8+
description: |
9+
Leverage searches that allow you to detect and investigate activity that may relate to exploitation of PTC Windchill and FlexPLM CVE-2026-4681.
10+
narrative: |
11+
CVE-2026-4681 is a critical remote code execution vulnerability affecting PTC Windchill PDMLink and FlexPLM. PTC reports that the vulnerability may be exploited through deserialization of untrusted data and published urgent mitigation guidance for Windchill and FlexPLM environments.
12+
13+
During exploitation, attackers may stage gateway or JSP components and then interact with them through suspicious HTTP request patterns. PTC identifies `run?c=`, `run?p=`, `.jsp?c=`, and `.jsp?p=` as suspicious request patterns to correlate, with `run?c=echo%20GW_READY_OK`, `c=echo%20GW_READY_OK`, and `GW_READY_OK` called out as log and error indicators. Once the staged component is reachable, the `c=` parameter can be used to send operating system commands such as `whoami`, while `p=` may indicate file read behavior.
14+
15+
This analytic story focuses on Windchill MethodServer log4j telemetry, especially the `wt.servlet.ServletRequestMonitor.request` and `wt.method.MethodContextMonitor.contexts.servletRequest` loggers, to identify exploitation probes and follow-on command or file read activity. Organizations should combine these detections with the PTC-published HTTP server mitigations, patching guidance, and file-system IOC checks for artifacts such as `GW.class`, `payload.bin`, and randomly named `dpr_<8 hex>.jsp` files.
16+
references:
17+
- https://www.ptc.com/en/about/trust-center/advisory-center/active-advisories/windchill-flexplm-critical-vulnerability
18+
- https://nvd.nist.gov/vuln/detail/CVE-2026-4681
19+
- https://www.cisa.gov/news-events/ics-advisories/icsa-26-085-03
20+
cve:
21+
- CVE-2026-4681
22+
category:
23+
- Adversary Tactics
24+
product:
25+
- Splunk Enterprise
26+
- Splunk Enterprise Security
27+
- Splunk Cloud
28+
usecase: Application Security

0 commit comments

Comments
 (0)