Quando O Novo Mercado entrou em contato comigo me oferecendo um box de livros passei a procurar meios práticos e confiáveis de receber esse mimo sem precisar compartilhar meu endereço (sou tímido 🤣).
Isso me levou a empresa da vulnerabilidade de hoje. Uma startup brasileira que atua na logística de last mile principalmente em SP e RJ. Final de 2023, ela já tinha captado mais de R$ 80 milhões em aportes 🤑. Além de ter grandes parceiros, como Americanas e Correios, e fez umas ações bem legais como a do Roc* In R*o. Por isso, decidi dar uma olhada na segurança do serviço. O resultado foi bem… supreendente 👀.
Como a vulnerabilidade ainda não foi corrigida, pra tentar proteger os dados dos clientes da empresa, preferi ocultar algumas informações que permitissem a imediata exploração dessas vulnerabilidades.
Normalmente, testes de segurança tem 3 fases: reconhecimento (recon), exploração (exploit), e report. Vou tentar seguir essa estrutura também aqui nesse post.
Recon
Fiz o meu reconhecimento básico com Amass, HTTPX, Nuclei, e manualmente com o Burp Suite, como quase sempre (às vezes uso Shodan também). Que é algo como
amass enum -d target.com.br -o amass.txt
cat amass.txt | httpx --silent > httpx.txt
nuclei -l httpx.txt -eid http-missing-security-headers
Como resultado, obtive uma lista de subdomínios e detalhes sobre eles (como algumas tecnologias usadas, CVEs, etc).
Na análise manual, achei algumas coisas interessantes, como um bucket S3 (com acesso público) com fotos de colabs com empresas parceiras, uma chave do TeamViewer e até dois vídeos de funcionários da empresa operando a infraestrutura.
Mas o que me chamou atenção foi um endpoint de uma API que estava sendo chamado sem autenticação.
/api/v1/<REDACTED>/site
Usando um Google Dork, acabei achando a documentação de outros endpoints. Aparentemente, esses endpoints foram criados para serem públicos. E basicamente todos exigiam um token.
intext:/api/v1/ "<REDACTED>.com.br"
Procurando por APIs no Burp Suite, achei ocorrências em um arquivo JS que pareceu estranho 🤔
/package/dynamic_js/e92aa9308720f1faae7c37c942da5e6bc0f22660f1bdce51bddde9cd643a5af8/<REDACTED>/live/index/xnull/xfalse/xfalse/en_us/xfalse/xfalse/dynamic.js
Ainda estou pesquisando sobre essa URL, mas ela parece estar relacionada com o serviço de low (no) code . E parece que sempre ocorre esse caso de vazamento de credenciais.
Olhando de perto esse arquivo, achei não só uma outra API (essa não parecia ser pública porque não era citada na documentação), mas achei também um token válido pra chamar a API 😱
"url":"https://REDACTED.com.br/io/api/v1/order","rank":0,"method":"post",
"headers":{"cmNoX":{"%k":"Authorization","%v":"Bearer eyJhbGc....","private":false},"cmNpO":{"%k":"Content-Type","%v":"application/json","private":false}
Exploração
A partir daí, usei a ferramenta FUFF para tentar achar outros endpoints da API
Acabei achando alguns endpoints interessantes, como
ffuf -u https://REDACTED.com.br/io/api/v1/FUZZ -w Wordlist/objects.txt -fc 403 -H "Authorization: Bearer eyJhbGci..."
company [Status: 200, Size: 1963, Words: 3, Lines: 1]
cluster [Status: 200, Size: 247214, Words: 8, Lines: 1]
group [Status: 200, Size: 21, Words: 1, Lines: 1]
product [Status: 200, Size: 21, Words: 1, Lines: 1]
settings [Status: 200, Size: 167, Words: 1, Lines: 1]
order [Status: 200, Size: 58257, Words: 153, Lines: 1]
Mas tinha algo faltando ainda. Como poderia existir um endpoint que retorna as orders de um customer, linkando com um objeto customer, mas não tem um endpoint pra customer 🤔.
Testando manualmente o endpoint /api/v1/customer
e descobri que estava sendo retornado um erro de timeout (504), ao invés de um típico 404.
Brincando um pouco com o os query parameters para limitar a quantidade de registros retornados, cheguei a uma consulta que retornava dados dos clientes 👀.
curl https://REDACTED.com.br/io/api/v1/customer\?offset\=0\&limit\=20 -H "Authorization: Bearer eyJhbGc..."
Aí sim comecei a chegar no ouro, mas estava longe de acabar.
Brincando um pouco mais com a API, cheguei ao endpoint /io/api/v1/REDACTED
(mas é o nome de um produto) que parecia bem especial.
A resposta tinha coisas como:
- Versão de sistema operacional:
"osVersion":"windows \"Windows 10 Pro\" 10.0 (Build 22621)"
- Informações de porta serial:
"serialPortMaster":"COM3",
- Informações do Github, como githubOrganization, githubRepository githubPersonalAccessToken 😱
Exatamente, até o githubPersonalAccessToken.
Que evidentemente testei se era válido
curl -H "Authorization: token ghp_..." https://api.github.com/user
curl -H "Authorization: token ghp_..." https://api.github.com/orgs/REDACTED/repos
Salvar segredos, como o Personal Access Token do Github em texto plano no banco é uma péssima prática (do ponto de vista de segurança). As formas mais seguras de armazenar esse tipo de informação são:
- Usando um cofre de senhas (preferível)
- Salvando criptografado no banco
Dados esses achados, entrei em uma outra fase. Que na verdade, como profissional de segurança, dificilmente faço que é descobrir até onde era possível ir no ecossistema da aplicação.
Elevação de Privilégios
Sabendo da possibilidade de ter acesso ao código da aplicação, dois planos de ação surgiram na minha cabeça:
- Procurar chaves, api keys e segredos no geral nos projetos do Github
- Analisar melhor a API em busca de outras formas de exploração, como um SQL Injection, ou BOLA.
No final das contas, a primeira opção acabou bastando, me garantindo acesso total a infraestrutura da aplicação (que não testei. O objetivo não é prejudicar o negócio).
Para clonar os repositórios usei
git clone https://<usuário>:<personal_access_token>@github.com/REDACTED/REDACTED-users.git
Após clonar alguns repositórios e executar a ferramenta Gitleaks para tentar achar os segredos de forma automatizada, BINGO! Chaves da AWS. Agora restava saber se ainda eram válidas né 👀.
Pra isso, usei a belíssima ferramenta Pacu https://github.com/RhinoSecurityLabs/pacu.
Com ela, testei as permissões das credenciais, acessei segredos setados nas varíaveis de ambiente, como:
- DB_HOST, DB_USER, DB_PASSWORD
- paypal client_id e client_secret
- pagseguro token
- rede token (aquela API de cartões de crédito 👀 https://developer.userede.com.br/)
Fora isso, ganhei acesso aos bancos de dados também. Mas não explorei, porque pra acessá-los, eu precisaria mudar uma política de acesso no RDS, não quero fazer nenhuma mudança no ambiente.
Fiquei sabendo até dos custos com a cloud 🤣
Essa análise se deu ao longo de vários dias. Uns 4, eu diria. No primeiro dia, quando obtive acesso a API já enviei um email ao suporte da empresa. A próxima seção descreve as minhas tentativas de contato.
Report
Primeiro passo do report é achar um email de contato. Como sempre, usei a ótima ferramenta de encontrar emails públicos https://hunter.io/. E achei aquele clássico email de contato para onde escrevi aquele email básico e enviei.
Pouco tempo depois, recebi uma resposta automatizada.
Depois de não obter resposta por 2 dias, resolvi encaminhar o email para o email de um líder técnico da empresa (o dono do token do Github que estava no código). Sem resposta também.
2 dias depois, resolvi responder o email automatizado pra saber de novidades. Como sempre, sem respostas.
1 dia depois, resolvi pedir ajuda de um amigo da mídia tech para tentar contactar a empresa.
1 dia depois é hj. O momento em que escrevo esse post. Caso eu tenha alguma novidade referente a comunicação, adiciono aqui. ⬇️
Conclusão
Diferente do nosso último caso (De um tweet a SQL Injection), dessa vez não tivemos uma conclusão tão agradável. Infelizmente, esse caso não é uma exceção. A resposta mais comum para reports de vulnerabilidade é apenas o silêncio e o vácuo nos emails 😆.
Update 05/08/2023:
Como a vulnerabilidade ainda não foi corrigida, pra tentar proteger os dados dos clientes da empresa, preferi ocultar algumas informações que permitissem a imediata exploração dessas vulnerabilidades (apesar de que com um pouco de pesquisa, ainda é 100% possível).
Ainda aguardo uma resposta da empresa via email, mas estou tentando acioná-la via outros canais, como pela mídia. A denúncia por violação da LGPD ainda é uma possibilidade também. Independente do caso, atualizo vocês 👍.
Dia 04/08/2023 consegui contato com a empresa, graças ao amigo @felipepayao. Dia 05/08/2023 eles já tinham aplicado um fix na aplicação vazando os tokens. Além disso, se comprometeram a fazer uma análise 360 para mitigar os outros riscos. Dado isso, agora posso contar que a empresa é XXX. Por fim, como retribuição, me ofereceram 2 anos do serviço de caixa postal, que eu fico feliz em aceitar ❤️.
DISCLAIMER: Esse é um conteúdo educativo sobre cibersegurança e sobre os riscos de não conhecê-la 🤣. Se voce tomar qualquer ação baseada nas informações desse post, tome por sua própria conta e risco. Abusar de vulnerabilidades pode trazer graves consequências legais.
Top comments (1)
Bom demais, triste ver isso de empresas que tem recursos e negligenciam de forma proposital pra "caminhar mais rapido"