servicenow.md (6547B)
1 --- 2 title: "ServiceNow" 3 section: "Network Services" 4 sectionSlug: "network-services-pentesting" 5 sourcePath: "src/network-services-pentesting/pentesting-web/servicenow.md" 6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/network-services-pentesting/pentesting-web/servicenow.md" 7 sha: "188de82beb54e70956b2952367a0af91d26758b8" 8 isIndex: false 9 modified: true 10 license: "CC-BY-NC-4.0" 11 --- 12 13 # ServiceNow 14 15 ## Quick notes 16 17 Useful paths during recon: 18 19 - `/login.do` 20 - `/api/now/sp/widget/<widget_id>` 21 - `/api/now/table/<table_name>` 22 - `/stats.do` 23 24 The important ServiceNow mistake is often **not a single CVE**, but **public or weak ACLs** reached through a widget or API. Test **widgets** and the **Table REST API** as distinct request paths, while remembering that both ultimately depend on the effective roles plus applicable table, field, and endpoint controls.<sup>[[1]](#references)[[3]](#references)[[5]](#references)</sup> 25 26 ## Bootstrap an unauthenticated session 27 28 ServiceNow commonly issues a usable **anonymous session** before authentication. Request `/login.do`, keep the cookies (for example `JSESSIONID`), and extract the `g_ck` value used as `X-UserToken`. Reuse that anonymous session for every probe.<sup>[[1]](#references)</sup> 29 30 If `/login.do` immediately redirects to SSO/IdP, anonymous bootstrapping may fail, but still inspect the redirect flow (`oauth_redirect.do`) in Burp because some deployments still leak a usable cookie/token pair there. 31 32 ## Treat Service Portal widgets as backend APIs 33 34 A public widget is also a **JSON API**. Service Portal widgets can contain both client-side and server-side logic, so call the exposed endpoint directly instead of assessing only the portal UI.<sup>[[6]](#references)</sup> 35 36 ```http 37 POST /api/now/sp/widget/WIDGET_ID HTTP/1.1 38 Host: target.service-now.com 39 X-UserToken: <public_g_ck> 40 Cookie: JSESSIONID=<public_session> 41 Content-Type: application/json 42 43 {"payload":{"start":0,"end":1}} 44 ``` 45 46 Interesting built-in widgets to probe: 47 48 - `ticket-attachments` 49 - `kb-article-page` 50 - `kb-search` 51 - `kb-category-list` 52 - `sc-category` 53 - `widget-simple-list` 54 55 Don't stop at defaults. Mature instances often contain **custom widgets** with organization-specific ACL assumptions, so enumerate installed widget IDs and test them with the same anonymous session. 56 57 ## Abuse `widget-simple-list` as a table oracle 58 59 If `widget-simple-list` is public, it can become a **generic table-query primitive**. The attacker supplies a table (`t`) and optionally a display field (`f`), while the widget queries backend records with the permissions of the anonymous session.<sup>[[1]](#references)[[3]](#references)</sup> 60 61 ```http 62 POST /api/now/sp/widget/widget-simple-list?t=incident&f=number HTTP/1.1 63 Host: target.service-now.com 64 X-UserToken: <public_g_ck> 65 Cookie: JSESSIONID=<public_session> 66 Content-Type: application/json 67 ``` 68 69 Use curated and environment-specific table/field pairs such as: 70 71 - `sys_user.email` 72 - `incident.number` 73 - `kb_knowledge.short_description` 74 - `cmn_department.name` 75 - `oauth_entity.name` 76 77 If `display_value` is `null` but the widget still reports a positive count, treat it as a signal that the **table is reachable** and the chosen field is the wrong one or field-level ACLs differ. 78 79 ## Test the Table REST API separately 80 81 Widget server scripts and the Table REST API are different access paths and can produce different outcomes. A target may block one widget but still expose rows through `/api/now/table/*`; ServiceNow documents that the Table API caller must have sufficient roles for the requested data.<sup>[[5]](#references)</sup> 82 83 ```bash 84 curl -s 'https://target.service-now.com/api/now/table/sys_user?sysparm_limit=1' \ 85 -H 'X-UserToken: <public_g_ck>' \ 86 -H 'Cookie: JSESSIONID=<public_session>' 87 ``` 88 89 Prioritize high-value tables such as `sys_user`, `incident`, `kb_knowledge`, `sc_cat_item`, `cmn_department`, `cmdb_ci`, and `oauth_entity`. 90 91 ## Count-only responses are blind inference oracles 92 93 If ServiceNow refuses to return rows but still reveals **how many records matched** attacker-controlled filters, you have a **count oracle**, not a clean denial. Vary `filterText`, prefixes, or boolean predicates and compare counts to infer protected data incrementally.<sup>[[4]](#references)</sup> 94 95 Treat this as **blind data inference**, not direct row disclosure. Report the oracle separately from full record exposure. 96 97 ## `snowpick` 98 99 [`snowpick`](https://github.com/BishopFox/snowpick) automates the anonymous-session bootstrap, widget discovery, `widget-simple-list` table enumeration, and optional Table REST API probing.<sup>[[1]](#references)[[2]](#references)</sup> 100 101 ```bash 102 go install github.com/BishopFox/snowpick@latest 103 snowpick -target target.service-now.com 104 snowpick -target target.service-now.com -table-api 105 snowpick -target target.service-now.com -discover -discover-limit 200 106 snowpick -targets hosts.txt -concurrency 5 -proxy http://127.0.0.1:8080 -rate 200ms 107 ``` 108 109 Useful behaviors: 110 111 - Distinguishes **`exposed`** rows from **`count_oracle`** findings 112 - Preserves **bounded evidence** (`record_count`, small samples, reproducible request details) 113 - Flags public `/stats.do` access 114 - Supports JSON output for triage and replay 115 116 ## Detection / validation notes 117 118 From a defender or purple-team perspective, review logs for:<sup>[[1]](#references)</sup> 119 120 - Anonymous requests to `/api/now/sp/widget/*` 121 - Anonymous requests to `/api/now/table/*` 122 - Systematic variation of `t`, `f`, table names, field names, or `filterText` 123 - Public access to `/stats.do` 124 125 When validating impact, prefer **bounded evidence**: keep the total count, a minimal sample, and a reproducible request instead of bulk-exporting every accessible row. 126 127 ## References 128 129 - [1] [Bishop Fox - Introducing snowpick: Testing ServiceNow for Public Data Exposure](https://bishopfox.com/blog/introducing-snowpick-testing-servicenow-for-public-data-exposure) 130 - [2] [BishopFox/snowpick](https://github.com/BishopFox/snowpick) 131 - [3] [Data Exposure and ServiceNow: The Elephant in the ITSM Room](https://www.enumerated.ie/servicenow-data-exposure) 132 - [4] [Varonis - Count(er) Strike: Data Inference Vulnerability in ServiceNow](https://www.varonis.com/blog/counter-strike-servicenow) 133 - [5] [ServiceNow - Table API reference](https://www.servicenow.com/docs/r/api-reference/rest-apis/c_TableAPI.html) 134 - [6] [ServiceNow - Service Portal widget API reference](https://www.servicenow.com/docs/r/platform-user-interface/service-portal/widget-api-reference.html)