DEV Community

Bolha Sec
Bolha Sec

Posted on • Updated on

De um mimo até a elevação de privilégios na Cloud

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
Enter fullscreen mode Exit fullscreen mode

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.
parceiros

Mas o que me chamou atenção foi um endpoint de uma API que estava sendo chamado sem autenticação.

/api/v1/<REDACTED>/site
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

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}
Enter fullscreen mode Exit fullscreen mode

api 1 response

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]
Enter fullscreen mode Exit fullscreen mode

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.
customers

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..."
Enter fullscreen mode Exit fullscreen mode

users

Aí sim comecei a chegar no ouro, mas estava longe de acabar.

hands

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
Enter fullscreen mode Exit fullscreen mode

User account

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:

  1. Procurar chaves, api keys e segredos no geral nos projetos do Github
  2. 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
Enter fullscreen mode Exit fullscreen mode

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é 👀.

AWS keys
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.
RDS
Fiquei sabendo até dos custos com a cloud 🤣
AWS Cost
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.

Email 1
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)

Collapse
 
iagocavalcante profile image
Iago Angelim Costa Cavalcante

Bom demais, triste ver isso de empresas que tem recursos e negligenciam de forma proposital pra "caminhar mais rapido"