Rafael Fidelis

I write about programming and random things

A História De Uma Falha De Segurança De 16 Milhões De Reais

| Comments

Aqui estou eu novamente, pronto pra revelar para vocês mais uma falha de segurança que eu encontrei em dos produtos/sites mais utilizados do mercado brasileiro. Vamos nessa?

No post anterior (Como eu usei o cartão de crédito do CEO do Trampos.co para pagar minha assinatura premium) eu contei um pouco sobre como descobri uma brecha inocente - porem severamente crítica - nos endpoints da aplicação do trampos.co. Essa falha está relacionada diretamente ao nível de controle de acesso dos usuários e os recursos da aplicação, uma falha MUITO comum em aplicações web.

Dessa vez eu consegui explorar as brechas da aplicação unindo as falhas de Access Control Level(ACL) como descritas no post anterior, porém combinada com uma brecha de segurança conhecida como Sensitive Data Exposure. Nesse momento você já deve estar imaginando que eu consegui acesso a dados privados de usuários sem precisar invadir nada, certo? Certo!

OBS: Esse post vai ser um pouco mais longo, pois gostaria de contextualizar um pouco sobre os danos que poderiam ser causados se um atacante permanecesse explorando essa falha, e também falar um pouco sobre o impacto negativo que a marca poderia sofrer. Desenvolver produtos é muito mais que simplesmente escrever código, é necessário entender que somos também responsáveis pela imagem pública das empresas para qual trabalhamos.



Alvo: Petlove.com.br

Talvez você não conheça a Petlove.com.br (antigo PetSuperMarket), mas eles já estão no mercado de vendas online há mais de 15 anos, e atualmente dizem ser o maior pet shop online do Brasil. Desde sua fundação, a empresa já conta com investimentos da Monashees Capital (BRASILLLLLLLL), Tiger Global e Kaszek Ventures, totalizando 4.8 milhões de dólares(16 milhões de R$) em rodadas de investimentos. (fonte: crunchbase)

Ou seja, os caras são BIG PLAYERS MESMO, veja só as estatísticas do site:

Posição no Brasil: 1,136 (fonte: Alexa)
Faturamento anual(em R$): R$ 10 mi a R$ 25 mi (fonte: 99jobs)
Estastisticas de acesso: (fonte: Similar Web):

Estastisticas de acesso da Petlove.com.br

Conforme você pode verificar na imagem acima, só no mês de abril desse ano o site recebeu incríveis 1 milhão e 300 mil visitas (estimadas), e olha só o up no início desse ano. Ou seja, desde o começo do ano o site recebeu cerca de 7 MILHÕES DE VISITAS, o que pra mim significa: muitos acessos = muitos usuários = alvo em potencial.

OBS: O título desse post faz referência ao valor total investido por fundos na Petlove.com.br até o mês de maio de 2016



Contextualização

Ok, eu sei que você provavelmente está ansioso para descobrir como eu consegui acesso aos dados, mas calma lá nego! Vamos com calma que vai rolar.

Uma das coisas interessante sobre esse hacking é que novamente, ele não foi planejado, aconteceu por acaso! Eu fui convidado pela equipe da Petlove para fazer uma entrevista para um cargo de desenvolvedor web, como eu sou um cara bem curioso obviamente eu aceitei e fui até lá trocar uma ideia com os malucos, e foi MUITO bacana! Pude comprovar que eles realmente manjam muito de tecnologia e desenvolvimento, e certamente possuem um time de desenvolvimento muito bom!

Após a troca de ideias, voltei pra casa motivado para entender melhor do que se tratava o site da Petlove (eu conhecia de nome, mas nunca tinha acessado de “verdade”). Cheguei, sentei no computador e já fui abrindo a página para dar uma explorada. Eu tenho uma mania (~TOC~) que pode ser explicada pela imagem abaixo :

Console

Eu sou uma espécie de tarado em ficar visualizando o que tá rolando por baixo dos panos dos sites que eu acesso, e acabo descobrindo algumas coisas bem bizarras as vezes - principalmente relacionadas a tracking de informações, e claro: falhas de seguranças.

Mas eu também gosto de ver exatamente como certas coisas funcionam, dessa forma eu posso adquirir conhecimento só observando como outros desenvolvedores implementaram algo. A partir daí, eu começo a visualizar as respostas de cada endpoint, verifico os headers das requisições, faço replay dos requests pra verificar as permissões… É como um pequeno playground na sala de casa. E foi nessa que eu percebi que dados sensíveis de usuários estavam expostos na API da Petlove.

Assim que eu percebi isso, eu logo fui tentando acessar os dados de outros usuários (irráaa)!



Fala logo como você explorou çaporra carai!

Beleza, chega de enrolação e vamos finalmente partir para a parte do enredo aonde a ação acontece: o ataque!

Spree e PetLove

O site da Petlove é construído em cima do Spree, que é uma plataforma de ecommerce open-source desenvolvida em cima do tão popular framework server-side Ruby on Rails.

Para entender melhor como funciona a comunicação entre client e server, eu fiquei navegando pelo site até entender que o Spree expõe uma API para que o front-end (loja/site) requisite os dados. Entretanto, o site também usa uma API independente para buscar outros tipos de informações.

Observando os requests off-spree, notei que para a API do site Petlove é necessário enviar nos headers de cada request um Token de acesso a API(X-Petlove-Api-Key) e um Token de acesso do usuário(X-Petlove-Access-Token), abaixo um exemplo de uma requisição HTTP para a API:

Requisição HTTP para API da Petlove.com.br

Requisição HTTP para API da Petlove.com.br

Charles HTTP Proxy

Após ter entendido o básico que eu precisava para completar as requisições HTTP com sucesso através do browser, dei um upgrade nas ferramentas, migrando do console do Chrome para uma ferramenta completa de debug: Charles HTTP Proxy. O Charles é uma ferramenta INCRÍVEL para debugar, monitorar e logar requisições HTTP, se liga em um print do menino up & running:

Charles é amor <3

A partir desse momento eu fui observando resposta por resposta de cada endpoint, verificando os dados dos JSON retornado, tentando assumir relacionamentos, endpoints, e o que era público e privado dentro desse contexto.

O Charles tem uma feature muito interessante que permite editar um request já realizado, e então enviar novamente. Decidi começar tentando pelo endpoint de sessão /api/v2/sessions/current, cuja resposta só me traz dados do usuário logado. Sendo assim, decidi tentar a sorte em outro endpoint: /api/v2/users/:email/public.

Aqui eu já comecei a sentir mais firmeza, mas sabia que ainda não seria aqui que eu encontraria o que eu procurava! Logo abaixo encontrei um request que tinha algo que SEMPRE me chama a atenção por padrão: IDS Sequenciais. Só de ver isso em qualquer canto eu já fico na vontade de imputar qualquer id aleatório - geralmente eu uso meu_id - 1 - pra começar a brincadeira, e foi o que eu fiz:

GET /api/v2/users/:user_id/ship_addresses

Efetuei algumas requisições com ids aleatórios e confirmei que eu conseguiria ao menos acessar os dados de endereço de outro usuário, mas ao ver a resposta do endpoint:

1
2
3
4
5
6
7
8
9
10
[{
  "id": 9999999, // -> id ficticio,
  "lastname": "*",
  "address1": "Rua Giacom******",
  "address2": "centro",
  "city": "Pen******",
  "zipcode": "*****-000",
  "phone": "*******5993"
  (...)
}]

Eu achei muito interessante essa abordagem da API do PetLove, essa ofuscação dos dados me deu a sensação que eu não encontraria nada nessa API, mesmo quando eu vi o endpoint /api/v2/users/:user_id no Charles. A primeira coisa que eu pensei é que eu não conseguiria obter os dados por conta do nível de acesso, e também já esperava uma resposta ofuscada no mesmo padrão… mas é claro que eu iria verificar isso pra ter certeza!

Dei uma olhada na resposta que já estava logada pelo Charles, que obviamente era correspondente aos dados do meu usuário. Observei o formato da resposta e escolhi um ID aleatório para tentar um novo request e pra minha SUPRESA o request foi autorizado! Porém a resposta havia se tornado um pouco diferente: os dados do usuário também estavam omitidos, assim como no endpoint que retorna os dados de endereço do usuário…. mas, calma… deixa eu ver melhor essa resposta… analisar cada linha e….

EITA PORRA, o email tá PLAIN mesmo? Sério? Não… não é possível (sempre rola esse processo de negação quando vem TÃO FÁCIL assim)….

Resposta do endpoint com dados do usuário ocultos, porém email plain

Continuei testando com outros ids e tive a certeza que SIM, eu tinha acabado de conseguir um banco de dados de emails for-free. Nada mal, né?

Imediatamente comecei a escrever um script para buscar pelo menos uns 100 usuários para eu poder FINALMENTE ter certeza que eu havia conseguindo acesso a esses dados.

Rodei o script com a instrução para baixar os usuários a partir do ID 1000 até 1100 e salvar no disco em formato JSON:

Arquivos com dados dos usuários

OBS: Todos e qualquer dado coletados durante a pesquisa foram devidamente apagados e nunca compartilhado com terceiros.

Verifiquei manualmente as respostas de alguns JSON e - sim meu caro Watson - PQ RAIOS O EMAIL TA PLAIN? PQ FASIÇU COMIGO?! (abaixo explico o por quê)



Mas guenta que tem mais

Fui até o site da Petlove novamente e adicionei um endereço ao meu usuário para verificar o endpoint e principalmente o formato do body dessa requisição. Após cadastrar o endereço, percebi a existência de um novo endpoint:

/api/v2/users/:user_id/ship_addresses/:address_id

Instantaneamente eu me perguntei: “Provavelmente implementaram CRUD desse endpoint, será que eu consigo deletar pela API?” - Já que pela interface do site não é possível, mandei o request e voilá:

Edição de request Request concluido

Fiquei animado com a resposta 200 OK, dei um refresh no site e realmente meu endereço cadastrado havia sido deletado. Nesse momento me questionei novamente:

“Mas será que eu consigo deletar o endereço algum outro usuário?” (pensamento maligno, eu tô ligado, mas se você pretende encontrar brechas, é melhor começar a pensar de forma neutra)

Se você estiver prestando atenção nesse artigo, vai lembrar que lá no início eu citei o endpoint para buscar os endereços de um usuário, mas a resposta veio ofuscada e eu já tinha meio que descartado a possibilidade de usar qualquer dado daquele endpoint. Só que não mais! Esse endpoint me fornece a combinação perfeita do que eu precisava para responder a pergunta acima. (id do usuário + id dos endereços)

Logo eu já busquei os endereços de qualquer usuário aleatório, peguei o ID e tentei requisitar o endpoint /api/v2/users/:user_id/ship_addresses/:address_id, contudo para o meu desgosto a resposta foi um 401 - Unauthorized. Bom, a ideia aqui é realmente tentar todos os cenários, poderia ter sido uma porta MUITO ABERTA para um atacante deletar todos os endereços de todos os usuários, mas felizmente isso não vai ser possível! (Tentei um PUT e POST para ter certeza que não conseguia atualizar o endereço)

Mas porque eu estou te falando isso se eu não tive sucesso? A resposta é bem simples: O intuito desse post é abrir os seus olhos quanto a segurança das aplicações que desenvolvemos todos os dias! Graças ao bom trabalho da equipe da Petlove(ou do Spree) não foi possível explorar essa falha, mas as possibilidades sempre existem em qualquer sistema, por isso certifique-se de validar TODOS OS CENÁRIOS POSSÍVEIS de um endpoint, pois você pode ter certeza que o atacante irá tentar por você… VALIDE TUDO, sempre!

Bom, pra não dizer que eu não consegui nada, ao menos consegui burlar uma limitação da interface do site né?



Dados expostos, mas nunca utilizados

É também possível obter endereços de email através da página de detalhes do produto, aonde são exibidos avaliações feitas pelos usuários e perguntas. Ao verificar a resposta de ambos endpoints pude verificar que o email está sendo retornado na resposta. Obviamente essa informação não é utilizada em NENHUM momento, então qual a utilidade de retornar? Nenhuma!

Sendo assim, mesmo que não fosse possível conseguir os dados de TODOS os usuários, seria possível obter o email de VÁRIOS utilizando-se dessa brecha. Por isso, sempre OLHE para a sua resposta, verifique se os dados que você está expondo são realmente úteis para algum client (browser, apps mobile, integração de parceiros). Se não tiver certeza, valide com o gerente de projeto ou alguém responsável, não custa nada no final das contas :) Abaixo os prints das respostas aos entrar na página de um produto:

Resposta: Endpoints de reviews

Resposta: Endpoints de perguntas e respostas sobre o produto

Novamente, seria MUITO SIMPLES obter os dados de review + questões em mais de 10.000 produtos cadastrados no site, já que os ids de produtos também são ids chaves auto increment sequenciais.



Formulários de atualização de dados

Continuando a minha busca, voltei para o site da Petlove e procurei por algum formulário aonde eu pudesse editar os dados do meu usuário. Novamente para verificar o endpoint e o formato do corpo do request.

Com o request salvo no Charles, decidi reenviar com os dados alterados, conforme o print abaixo:

[PUT] /api/v2/users/:email

1
Se você observar atentamente, eu alterei os valores de cada chave antes de enviar o request, para poder saber o que seria permitido alterar.

Alterando os valores no momento do Request

Pela API eu consegui alterar meu número de documento para um valor inválido, a minha data de nascimento para o futuro, meu telefone para somente 1 dígito, além de facebook_id, google_id e vtex_id (eu não sei exatamente a utilidade desses dados, mas ai já temos uma porta para tentar explorar alguma outra brecha - talvez esses dados estejam associados ao login social…), já esse vtex_id parece ser o dado mais crítico disso tudo, mas ainda não tive tempo de verificar aonde ele é usado.

Porém o valor que eu esperava conseguir alterar não foi possível: email - pra minha decepção, já que se eu conseguisse alterar o email de algum usuário para o meu id, talvez conseguisse logar como qualquer usuário utilizando a minha senha, mas não foi dessa vez :(



Criando pedidos para outros usuários

A Petlove tem uma usabilidade um tanto quanto questionável: É possível efetuar uma espécie de compra rápida somente com o endereço de email do usuário….Bom, pra mim (atacante) isso não é mais um problema, PQ EU PODERIA TER TODOS OS ENDEREÇOS DE EMAIL DO SITE HAHAHAHAHAHAHA

”> Tá bom Fidelis, deixa de causar e explica logo isso!” (você nesse momento)

Admito que até o momento de escrever esse post eu não tinha percebido a brecha que vou descrever abaixo, o fluxo para efetuar uma compra rápida é o seguinte:

1 -> Sistema cria um pedido temporário e salva referencia em um cookie.



2 -> Usuário digita email no processo do checkout e o pedido temporário agora é associado a esse usuário.

Request para associar um pedido a um endereço de email: A imagem abaixo exibe o corpo da REQUISIÇÃO(e não da resposta)



3 -> O site redireciona para a página de pagamento do pedido, aonde é possível efetuar o pagamento com boleto ou cartão de crédito (inclusive com 1 click buy). Abaixo o print de como os dados são exibidos na página.

Página de pagamento de pedido



4 -> Ao selecionar boleto como meio de pagamento, o sistema emite um boleto e para minha surpresa a resposta contém os dados PLAIN do endereço selecionado + PLAIN do número do documento(CPF) do usuário.



5 -> Site redireciona para página de detalhes do pagamento, aonde os dados do usuário são exibidos sem nenhum tipo de ofuscação:

O que isso significa? Que se eu (atacante) realmente quiser obter TODOS os endereços + número do CPF de todos os usuários da Petlove , eu posso fazer um script para reproduzir o fluxo acima para cada um dos endereços cadastrados pelos usuários, somente para chegar até o final da transação e obter dados privados do usuário em questão. Sendo assim conseguimos resolver um problema que até então estava sem solução, finalmente é possível obter o endereço + numero do CPF dos usuários, e isso agrega mais valor ainda ao banco de dados…



Dados de cartão de crédito

Ao acessar a página de pagamento do pedido com o email de algum usuário que possui cartões de créditos cadastrados para compra rápida, o site exibe os dados do cartão, somente sendo necessário preencher o Codigo de segurança, o que serve como uma barreira pra evitar compras no cartão do usuário. Mesmo assim, eu ainda posso tentar criar um script que tente uma combinação diferente a cada requisição, até encontrar o CVV correto do cartão do usuário… (ou no minimo bloquear o cartão na operadora por inúmeras tentativas sem sucesso no momento da compra)…

Página de pagamento rápido:

Mesmo que não seja possível efetuar compras com os cartões cadastrados pelos usuários, o atacante ainda pode agir de má fé somente para aterrorizar o proprietário do cartão: Bancos costumam enviar SMS a cada tentativa de transação, não seria nada legal clientes do site receberem mensagens SMS do tipo:

Sua transação em Petlove.com.br foi negada: Motivo: CVV incorreto

Agora imagine os clientes da Petlove recebendo inúmeras mensagens dessas, você ainda acha que o cliente vai manter os dados do cartão salvo no site da Petlove? Você acha que esse usuário vai recomendar a Petlove para seus amigos? É claro que não!

Depois de uma experiência dessas, certamente a credibilidade e a imagem da Petlove.com.br iria sofrer danos irreparáveis ao olhar dos seus clientes - se o atacante tivesse todos os email salvos, seria possível buscar todos os usuários que possuem cartões cadastrados no site e mandar bala em todos!

Provavelmente o atendimento da Petlove receberia ligações e emails de clientes desesperados em massa! A credibilidade que uma empresa de mais de 15 anos conseguiu conquistar no mercado poderia ser destruída em poucas horas! Trágico, não?



E daí? Você só conseguiu acesso aos emails dos usuários….

Se você pensa dessa forma, tem algo errado na sua cabeça, e eu vou te explicar o porque:

Primeiramente, qualquer dado pessoal/sensitivo de qualquer usuário deve ser SEMPRE mantido privado, isso é parte do seu compromisso com a privacidade dos seus usuários.

Com essa brecha, TODOS os usuários do sistema da Petlove estariam expostos, e eu tenho certeza que essa centena de milhares de endereços de email custaram caro (R$$$) para a equipe de marketing do Petlove em leads, sem falar que essa base de dados provavelmente tem mais de 10 anos, ou seja, anos de trabalho para serem “levados” em poucos minutos.

Além do mais, é uma base de email bem específica: pessoas/empresas que compram produtos para animais online, já pensou esses emails caindo na mão de algum concorrente para dar início naquela bela campanha de email marketing? Seria uma das formas de atrair os clientes da Petlove para o site deles, bastaria uma promoção bem bacanuda para ser disparada para esse mailing list para que ao menos alguns usuários tentarem a experiência de compra em outro site.

Estamos olhando somente do ponto de vista de quem tá por trás (empresa), mas e o usuário que teve seus dados expostos, você ficaria feliz em receber uma campanha de email marketing de algo que você nunca assinou? Toda semana? Agora adicione a possibilidade de um atacante malicioso vender essa base de emails para outros concorrentes, ou para qualquer pessoa interessada em conseguir milhares de usuários “reais/ativos” para qualquer tipo de campanha? (afinal, além de comprar produto para pet, as pessoas também compram outros tipo de produtos online)

É realmente assustador!



Resumão: TL;TR

Esse é um post com muito conteúdo técnico e didático, e eu já sei que você passou o olho, scrollou até o final do artigo, calculou o tempo de leitura, e certamente pensou: “Vou deixar aberto aqui, mais tarde eu leio…”. Bom, tenho boas notícias pra você!

Abaixo enumero um pequeno resumo do que eu expliquei nesse post, porém para compreender o processo todo não tem jeito, só lendo com calma.

1 - Consegui obter dados (email, cpf, id de redes sociais) + os endereços cadastrados de centena de milhares de usuários.

2 - Pude efetuar transações com CVV aleatório para bloquear e aterrorizar clientes. (ou mesmo efetuar transações reais em caso de CVV ser o correto).



Notas Finais

Como eu disse na introdução desse artigo, um combo de brechas: ACL(A7) + Exposição de Dados Sensíveis(A6) me permitiu acesso aos dados dos usuário.

Pra quem tiver interesse a OWASP disponibiliza material como o livro 10 tipos de riscos de segurança mais críticos em aplicações web, se liga:

Dados de 2013: [link para download do PDF da versão pt-BR] (http://owasptop10.googlecode.com/files/OWASP_Top_10-2013_Brazilian_Portuguese.pdf):

OWASP Web top 2013



E para finalizar, para quem tiver interesse em entender como o Charles HTTP Proxy funciona, recomendo a leitura do artigo “Creating the missing Instagram web Interface” escrito pelo mislav, foi graças a esse post que eu tive conhecimento dessa ferramenta maravilhosa <3.

Gostaria também de deixar uma citação do prefácio do Top 10 do Open Web Application Security Project (OWASP) que resume bem o que eu quis dizer nesse post:

“O software inseguro está debilitando nossa infraestrutura financeira, de saúde, de defesa, de energia e outras infraestruturas críticas. À medida que nossa infraestrutura digital fica cada vez mais complexa e interligada, a dificuldade em obter segurança em aplicações aumenta exponencialmente. Não podemos mais tolerar os problemas de segurança relativamente simples. A OWASP encoraja a utilização do Top 10 para que as organizações comecem com segurança em suas aplicações. Os desenvolvedores podem aprender com os erros de outras organizações. Os executivos devem começar a pensar em como gerenciar o risco que as aplicações de software criam em suas empresas.”



Responsible Disclosure

Entrei em contato com a empresa responsável pelo site no dia 13/05/16 e notifiquei a falha:

Dia que entrei em contato: 13/05/16
Dia que corrigiram: Entre 14/05 e 19/05
Dia que responderam: 13/05/16
Meios de contato: Falei diretamente com o CTO (Gerente de TI), e também com o COO da Petlove por telefone, email e presencialmente na sede da Petlove em São Paulo.

Resposta da Petlove

Acredito que a Petlove foi MUITO responsável e agradecida por eu ter reportado a falha, o que me deixa realmente feliz, já que minha intenção é realmente ajudar a melhorar o cenário nacional quando se trata de questões de segurança em aplicações.

Uma das coisas mais bacana foi que a Petlove criou uma política de White Hat para tratar esse caso, e obviamente os casos futuros, se liguem: https://www.petlove.com.br/empresa/politica-white-hat

Além do mais, a Petlove me recompensou com uma quantia em dinheiro pelo report, muito bacana né? E para finalizar, conversei com os caras e eles autorizaram que outras empresas usem a política deles como base para suas próprias políticas de white hat! Fica a dica para vocês que possuem produtos e ainda não tem ideia de onde começar nessa questão.

Comments