AWS - S3 Enum Não Autenticado

Reading time: 9 minutes

tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprenda e pratique Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Support 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 tanto a tudo quanto 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
  • s3dns – Um servidor DNS leve que identifica passivamente buckets de armazenamento em nuvem (S3, GCP, Azure) analisando o tráfego DNS. Ele detecta CNAMEs, segue cadeias de resolução e combina padrões de buckets, oferecendo uma alternativa silenciosa à descoberta por força bruta ou baseada em API. Perfeito para fluxos de trabalho de recon e OSINT.
  • 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á no 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:

# Gerar 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

# Gerar 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

# Criar 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

## Gerar 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

## Chamar 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:

bash
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 pode acessar o bucket visitando: flaws.cloud.s3-us-west-2.amazonaws.com

Tentando

Se você tentar acessar um bucket, mas no nome do 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:

bash
#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 por vez.

Esta ferramenta automatiza o processo:

bash
# 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

Essa 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:

bash
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.

Emails usados como enumeração de conta root

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

python
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

tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprenda e pratique Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks