
trouver les données sensibles qui fuient des instances ServiceNow.
snowpick est un scanner d'exposition ServiceNow qui détecte les ACL de widgets mal configurés, les contrôles d'accès à l'API REST et l'exposition de données sans authentification.
ServiceNow expose des données via deux surfaces publiques courantes : les widgets Service Portal et l'API REST Table. Lorsque les contrôles d'accès sur l'une ou l'autre surface sont mal configurés, des utilisateurs non authentifiés peuvent être en mesure d'interroger des enregistrements internes tels que les tickets d'incident, les annuaires d'utilisateurs, les articles de la base de connaissances et les éléments du catalogue de services. snowpick teste les deux surfaces, distingue l'exposition de lignes de la simple preuve de comptage et produit des détails de reproduction pour une validation autorisée.
snowpick obtient un jeton de session depuis la page de connexion ServiceNow sans aucun identifiant, puis l'utilise pour interroger les API internes de la plateforme. Il vérifie deux surfaces d'attaque :
Widgets sont de petites applications qui alimentent le Service Portal de ServiceNow. Chacune possède ses propres paramètres de contrôle d'accès. Lorsque ces paramètres sont trop permissifs, une session non authentifiée peut être en mesure de récupérer des données à partir du widget. snowpick demande d'abord à l'instance la liste des widgets installés lorsque c'est possible, puis sonde chacun d'eux et vérifie s'il renvoie des enregistrements ou une simple preuve de comptage.
Table API est une interface REST située à /api/now/table/ permettant d'interroger directement les tables ServiceNow. Elle possède des contrôles d'accès distincts de ceux des widgets, si bien qu'une cible peut être verrouillée sur une surface et ouverte sur l'autre. snowpick sonde des tables à forte valeur comme sys_user, incident et oauth_entity.
Oracle de comptage. Parfois, un widget ou une table confirme l'existence d'enregistrements correspondants sans renvoyer les lignes. snowpick signale cela comme un count_oracle — ce n'est pas une exposition complète, mais ce n'est pas non plus sain, car les compteurs peuvent être sondés avec des filtres pour déduire les données à l'aveugle.
❯ go install github.com/BishopFox/snowpick@latest
Ou construisez à partir des sources :
❯ git clone https://github.com/BishopFox/snowpick.git
❯ cd snowpick
❯ go build -o snowpick .
Nécessite Go 1.21 ou ultérieur.
Pointez snowpick vers une instance ServiceNow. Aucun identifiant n'est nécessaire.
❯ snowpick -target prod.service-now.com
snowpick v1.0.0 | 1 targets | 6 widgets | proxy direct
[!] prod.service-now.com
| ticket-attachments 272 records [internal_operations:inferred]
[*] 1/1 targets complete, 1 with findings
RESULTS
1 targets scanned in 8.2s | 1 reachable | 1 with findings
EXPOSED prod.service-now.com 272 records [internal_operations:inferred]
| ticket-attachments 272 records [internal_operations:inferred]
| ServiceNow Overview and Open House 'How To.... Videos'
| How to - JIRA and Confluence Access Process
| Updating Your Personal Time Zone in ServiceNow
ATTACK SURFACE
ticket-attachments #################### 272 across 1 target
DATA CLASSIFICATION
OPERATIONS 1 finding across 1 target
snowpick découvre automatiquement les widgets installés sur l'instance et sonde chacun d'eux en plus de ses valeurs par défaut intégrées. Les résultats sont classés par gravité.
Progress markers (left of each host):
[!] findings [+] clean [-] unreachable or no session [*] progress
Summary buckets:
EXPOSED data or a confirmed count came back CLEAN nothing reachable
SKIP no public session (e.g. SSO-only login) DOWN host unreachable
Counts:
272 records total the instance reports as matching
272 records, 10 sampled total, plus the rows snowpick pulled as evidence
Tags:
[pii:observed] a hint, written as category:basis
basis observed = value seen in returned data
inferred = from a table/field/widget name
category pii, credentials, infrastructure,
internal_operations, review_required
[blind oracle] count confirmed but no rows returned (a count_oracle)
[API] finding came from the Table REST API, not a widget
[stats.do] the /stats.do diagnostic endpoint is publicly reachable
Passez un fichier avec un nom d'hôte par ligne. snowpick les analyse en parallèle.
❯ snowpick -targets hosts.txt -concurrency 5
snowpick v1.0.0 | 6 targets | 6 widgets | proxy direct
[!] prod.service-now.com
| ticket-attachments 272 records [internal_operations:inferred]
[*] 1/6 targets complete, 1 with findings
[+] staging.service-now.com clean
[*] 2/6 targets complete, 1 with findings
[!] dev.service-now.com [stats.do]
| ticket-attachments 61 records [internal_operations:inferred]
[*] 3/6 targets complete, 2 with findings
[+] sandbox.service-now.com clean
[*] 4/6 targets complete, 2 with findings
[-] internal.service-now.com bootstrap failed: /login.do returned 302
[+] test.service-now.com clean
[*] 6/6 targets complete, 2 with findings
ServiceNow expose également une API REST Table à /api/now/table/ pour interroger directement les tables backend. Il s'agit d'une surface de contrôle d'accès distincte de celle des widgets. Utilisez -table-api pour vérifier les deux.
❯ snowpick -target prod.service-now.com -table-api
snowpick v1.0.0 | 1 targets | 6 widgets | proxy direct
[!] prod.service-now.com
| [API] cmn_department 1,234 records, 10 sampled [infrastructure:inferred]
[*] 1/1 targets complete, 1 with findings
Pour les résultats de l'API Table, record_count représente le nombre total d'enregistrements exposés lorsque ServiceNow renvoie un compte total. sample_count indique le nombre d'enregistrements que snowpick a collectés comme preuve bornée.
Par défaut, snowpick vérifie un ensemble sélectionné de tables à forte valeur (tickets d'incident, enregistrements utilisateurs, pièces jointes, etc.). Avec -discover, il tente d'énumérer les noms de tables depuis l'instance et vérifie également ceux-ci.
❯ snowpick -target prod.service-now.com -discover -discover-limit 200
Utilisez -fingerprint pour identifier la version de ServiceNow exécutée par la cible. Cela aide à déterminer quels correctifs de sécurité sont en place.
❯ snowpick -target prod.service-now.com -fingerprint
snowpick v1.0.0 | 1 targets | 6 widgets | proxy direct
[!] prod.service-now.com [Zurich (glide-zurich-07-01-2025__patch7-02-19-2026)] [stats.do]
| ticket-attachments 61 records [internal_operations:inferred]
[*] 1/1 targets complete, 1 with findings
Acheminez le trafic via Burp, ZAP ou un proxy SOCKS. Utilisez -rate pour limiter les requêtes sur les instances de production.
❯ snowpick -target prod.service-now.com -proxy socks5://127.0.0.1:1080 -insecure -rate 200ms
Supprimez la sortie de progression avec -quiet. Le JSON sort sur stdout par défaut, ou dans un fichier avec -output. Le code de sortie 2 signifie que des résultats ont été trouvés, 1 qu'une ou plusieurs cibles n'ont pas pu être testées, et 0 que l'analyse s'est terminée sans résultat.