AWS - S3 Unauthenticated Enum

Suporte ao HackTricks

Buckets Públicos S3

Um bucket é considerado “público” se qualquer usuário pode listar o conteúdo do bucket, e “privado” se o conteúdo do bucket pode ser listado ou escrito apenas por certos usuários.

As empresas podem ter permissões de buckets mal configuradas dando acesso a tudo ou a todos autenticados na AWS em qualquer conta (ou seja, a qualquer um). Note que, mesmo com tais configurações incorretas, algumas ações podem não ser realizadas, pois os buckets podem ter suas próprias listas de controle de acesso (ACLs).

Saiba mais sobre a má configuração do AWS-S3 aqui: http://flaws.cloud e http://flaws2.cloud/

Encontrando Buckets AWS

Diferentes métodos para encontrar quando uma página da web está usando AWS para armazenar alguns recursos:

Enumeração & OSINT:

  • Usando o plugin de navegador wappalyzer

  • Usando burp (spidering a web) ou navegando manualmente pela página, todos os recursos carregados serão salvos no Histórico.

  • Verifique os recursos em domínios como:

http://s3.amazonaws.com/[bucket_name]/
http://[bucket_name].s3.amazonaws.com/
  • Verifique por CNAMES como resources.domain.com que pode ter o CNAME bucket.s3.amazonaws.com

  • Verifique https://buckets.grayhatwarfare.com, um site com buckets abertos já descobertos.

  • O nome do bucket e o nome do domínio do bucket precisam ser os mesmos.

  • flaws.cloud está em IP 52.92.181.107 e se você for lá, ele redireciona você para https://aws.amazon.com/s3/. Além disso, dig -x 52.92.181.107 retorna s3-website-us-west-2.amazonaws.com.

  • Para verificar se é um bucket, você também pode visitar https://flaws.cloud.s3.amazonaws.com/.

Força Bruta

Você pode encontrar buckets forçando nomes relacionados à empresa que você está testando:

# Gere uma lista de palavras para criar permutações
curl -s https://raw.githubusercontent.com/cujanovic/goaltdns/master/words.txt > /tmp/words-s3.txt.temp
curl -s https://raw.githubusercontent.com/jordanpotti/AWSBucketDump/master/BucketNames.txt >>/tmp/words-s3.txt.temp
cat /tmp/words-s3.txt.temp | sort -u > /tmp/words-s3.txt

# Gere uma lista de palavras com base nos domínios e subdomínios a serem testados
## Escreva esses domínios e subdomínios em subdomains.txt
cat subdomains.txt > /tmp/words-hosts-s3.txt
cat subdomains.txt | tr "." "-" >> /tmp/words-hosts-s3.txt
cat subdomains.txt | tr "." "\n" | sort -u >> /tmp/words-hosts-s3.txt

# Crie permutações com base em uma lista com os domínios e subdomínios a serem atacados
goaltdns -l /tmp/words-hosts-s3.txt -w /tmp/words-s3.txt -o /tmp/final-words-s3.txt.temp
## A ferramenta anterior é especializada em criar permutações para subdomínios, vamos filtrar essa lista
### Remover linhas que terminam com "."
cat /tmp/final-words-s3.txt.temp | grep -Ev "\.$" > /tmp/final-words-s3.txt.temp2
### Criar lista sem TLD
cat /tmp/final-words-s3.txt.temp2 | sed -E 's/\.[a-zA-Z0-9]+$//' > /tmp/final-words-s3.txt.temp3
### Criar lista sem pontos
cat /tmp/final-words-s3.txt.temp3 | tr -d "." > /tmp/final-words-s3.txt.temp4http://phantom.s3.amazonaws.com/
### Criar lista sem hífens
cat /tmp/final-words-s3.txt.temp3 | tr "." "-" > /tmp/final-words-s3.txt.temp5

## Gere a lista de palavras final
cat /tmp/final-words-s3.txt.temp2 /tmp/final-words-s3.txt.temp3 /tmp/final-words-s3.txt.temp4 /tmp/final-words-s3.txt.temp5 | grep -v -- "-\." | awk '{print tolower($0)}' | sort -u > /tmp/final-words-s3.txt

## Chame s3scanner
s3scanner --threads 100 scan --buckets-file /tmp/final-words-s3.txt  | grep bucket_exists

Saque de Buckets S3

Dado buckets S3 abertos, BucketLoot pode automaticamente procurar informações interessantes.

Encontrar a Região

Você pode encontrar todas as regiões suportadas pela AWS em https://docs.aws.amazon.com/general/latest/gr/s3.html

Por DNS

Você pode obter a região de um bucket com um dig e nslookup fazendo uma solicitação DNS do IP descoberto:

dig flaws.cloud
;; ANSWER SECTION:
flaws.cloud.    5    IN    A    52.218.192.11

nslookup 52.218.192.11
Non-authoritative answer:
11.192.218.52.in-addr.arpa name = s3-website-us-west-2.amazonaws.com.

Verifique se o domínio resolvido contém a palavra "website". Você pode acessar o site estático indo para: flaws.cloud.s3-website-us-west-2.amazonaws.com ou você pode acessar o bucket visitando: flaws.cloud.s3-us-west-2.amazonaws.com

Tentando

Se você tentar acessar um bucket, mas no nome de domínio você especificar outra região (por exemplo, o bucket está em bucket.s3.amazonaws.com, mas você tenta acessar bucket.s3-website-us-west-2.amazonaws.com, então você será indicado para o local correto:

Enumerando o bucket

Para testar a abertura do bucket, um usuário pode simplesmente inserir a URL em seu navegador. Um bucket privado responderá com "Acesso Negado". Um bucket público listará os primeiros 1.000 objetos que foram armazenados.

Aberto para todos:

Privado:

Você também pode verificar isso com o cli:

#Use --no-sign-request for check Everyones permissions
#Use --profile <PROFILE_NAME> to indicate the AWS profile(keys) that youwant to use: Check for "Any Authenticated AWS User" permissions
#--recursive if you want list recursivelyls
#Opcionally you can select the region if you now it
aws s3 ls s3://flaws.cloud/ [--no-sign-request] [--profile <PROFILE_NAME>] [ --recursive] [--region us-west-2]

Se o bucket não tiver um nome de domínio, ao tentar enumerá-lo, coloque apenas o nome do bucket e não o domínio completo do AWSs3. Exemplo: s3://<BUCKETNAME>

Modelo de URL pública

https://{user_provided}.s3.amazonaws.com

Obter ID da Conta a partir de um Bucket público

É possível determinar uma conta AWS aproveitando a nova S3:ResourceAccount Chave de Condição de Política. Esta condição restrige o acesso com base no bucket S3 em que uma conta está (outras políticas baseadas em conta restringem com base na conta em que o principal solicitante está). E como a política pode conter coringas, é possível encontrar o número da conta apenas um número de cada vez.

Esta ferramenta automatiza o processo:

# Installation
pipx install s3-account-search
pip install s3-account-search
# With a bucket
s3-account-search arn:aws:iam::123456789012:role/s3_read s3://my-bucket
# With an object
s3-account-search arn:aws:iam::123456789012:role/s3_read s3://my-bucket/path/to/object.ext

Esta técnica também funciona com URLs do API Gateway, URLs do Lambda, conjuntos de dados do Data Exchange e até mesmo para obter o valor de tags (se você souber a chave da tag). Você pode encontrar mais informações na pesquisa original e na ferramenta conditional-love para automatizar essa exploração.

Confirmando que um bucket pertence a uma conta AWS

Como explicado em este post do blog, se você tiver permissões para listar um bucket é possível confirmar um accountID ao qual o bucket pertence enviando uma solicitação como:

curl -X GET "[bucketname].amazonaws.com/" \
-H "x-amz-expected-bucket-owner: [correct-account-id]"

<?xml version="1.0" encoding="UTF-8"?>
<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">...</ListBucketResult>

Se o erro for "Acesso Negado", isso significa que o ID da conta estava errado.

Usando Emails como enumeração de conta root

Como explicado em este post do blog, é possível verificar se um endereço de email está relacionado a alguma conta AWS tentando conceder permissões a um email sobre um bucket S3 via ACLs. Se isso não gerar um erro, significa que o email é um usuário root de alguma conta AWS:

s3_client.put_bucket_acl(
Bucket=bucket_name,
AccessControlPolicy={
'Grants': [
{
'Grantee': {
'EmailAddress': 'some@emailtotest.com',
'Type': 'AmazonCustomerByEmail',
},
'Permission': 'READ'
},
],
'Owner': {
'DisplayName': 'Whatever',
'ID': 'c3d78ab5093a9ab8a5184de715d409c2ab5a0e2da66f08c2f6cc5c0bdeadbeef'
}
}
)

Referências

Suporte ao HackTricks

Last updated