
Ein S3-Konto-ID-Enumeration- und Bucket-Erkennungstool
Ein Tool zur Aufzählung von S3-Konto-IDs und zur Entdeckung von Buckets
Bei einem einzelnen zugänglichen S3-Bucket extrahiert bucky die 12-stellige AWS-Konto-ID des Besitzers und entdeckt dann weitere Buckets desselben Kontos, indem es Bucket-Namen gegen eine Wortliste fuzzt – alles in einem Befehl.
s3:ResourceAccount, um die 12-stellige AWS-Konto-ID mithilfe von Inline-STS-Sitzungsrichtlinien Ziffer für Ziffer durch Brute-Force zu ermitteln.S3-Bucket-Namen teilten ursprünglich einen einzigen globalen Namensraum, was zu Bucketsquatting führte – Angreifer konnten auf Namen sitzen bleiben, von denen sie erwarteten, dass Organisationen sie erstellen würden. AWS hat dies durch die Einführung kontoregionaler Namensräume behoben, einem Namensschema, das jeden Bucket an sein besitzendes Konto und seine Region bindet:
{name}-{accountID}-{region}-an
Ein Bucket namens myapp-123456789123-eu-north-1-an würde sich unter https://myapp-123456789123-eu-north-1-an.s3.eu-north-1.amazonaws.com befinden. AWS empfiehlt dieses Format jetzt für neue Buckets, auch wenn es noch nicht die Standardeinstellung ist. (Hintergrundinformationen dazu, wie der neue Namensraum Bucketsquatting beendet, finden Sie unter One Cloud Please.)
Der Nachteil ist, dass die Konto-ID und die Region nun in den Bucket-Namen selbst eingebettet sind. Sobald ein Angreifer die Konto-ID eines Ziels erlangt, kann er sie mit einer Wortliste kombinieren und systematisch gültige Bucket-URLs konstruieren – und S3 wird bestätigen, ob jeder einzelne existiert, selbst wenn der Bucket privat ist. Diese Antwort allein ist eine nützliche Aufklärung.
Bucky nutzt genau dies aus. Basierend auf Forschungsergebnissen von Pwned Labs stellt es zunächst die 12-stellige Konto-ID von jedem zugänglichen Bucket mithilfe der s3-account-search-Technik wieder her und brute-forct dann das Muster {name}-{accountID}-{region}-an, um die breitere S3-Fußabdruck des Ziels aufzudecken.
s3:ListBucket oder s3:GetObject auf dem Ziel-Bucket hat.sts:AssumeRole für diese Rolle auf und übergeben eine Inline-Sitzungsrichtlinie mit einer s3:ResourceAccount-Bedingung wie "1*".1 beginnt, ist der HeadBucket-Aufruf erfolgreich; andernfalls wird 403 zurückgegeben.Dies erfordert höchstens 120 API-Aufrufe (12 Positionen × 10 Ziffern) und ist normalerweise in unter einer Minute abgeschlossen.
go installgo install github.com/umair9747/bucky@latest
git clone https://github.com/umair9747/bucky.git
cd bucky
go build -o bucky .
sudo mv bucky /usr/local/bin/
bucky --update
Dies zieht die neueste Version aus dem Repository und installiert sie.
Bevor Sie bucky verwenden, benötigen Sie eine IAM-Rolle in Ihrem eigenen AWS-Konto, die auf den Ziel-S3-Bucket zugreifen kann. Der Ziel-Bucket muss öffentlich zugänglich sein oder eine Bucket-Richtlinie haben, die den Zugriff von Ihrem Konto aus erlaubt.
Erstellen Sie trust-policy.json – dies erlaubt Ihrem IAM-Benutzer, die Rolle zu übernehmen:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<YOUR_ACCOUNT_ID>:root"
},
"Action": "sts:AssumeRole"
}
]
}
Ersetzen Sie
<YOUR_ACCOUNT_ID>durch Ihre 12-stellige AWS-Konto-ID. Sie können den Prinzipal auf eine bestimmte IAM-Benutzer- oder Rollen-ARN anstelle von:rooteingrenzen.
Erstellen Sie s3-policy.json – die Rolle benötigt breiten S3-Lesezugriff (die s3:ResourceAccount-Bedingung in buckys Inline-Sitzungsrichtlinie übernimmt die Kontofilterung):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetObject"
],
"Resource": "*"
}
]
}
aws iam create-role \
--role-name bucky-role \
--assume-role-policy-document file://trust-policy.json
aws iam put-role-policy \
--role-name bucky-role \
--policy-name S3ReadAccess \
--policy-document file://s3-policy.json
aws iam get-role --role-name bucky-role --query 'Role.Arn' --output text
# Ausgabe: arn:aws:iam::123456789012:role/bucky-role
Wenn Ihr IAM-Benutzer noch nicht über die sts:AssumeRole-Berechtigung verfügt, fügen Sie sie hinzu:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::<YOUR_ACCOUNT_ID>:role/bucky-role"
}
]
}
Die primäre Art, bucky zu verwenden – Konto-ID aus einem bekannten Bucket ermitteln und dann in einem Durchgang nach weiteren Buckets fuzzen:
bucky \
--role-arn arn:aws:iam::123456789012:role/bucky-role \
--bucket target-bucket \
--wordlist wordlists/default.txt \
--access-key AKIA... \
--secret-key wJal...
Mit einem bekannten Objektschlüssel (verbessert die Zuverlässigkeit):
bucky \
--role-arn arn:aws:iam::123456789012:role/bucky-role \
--bucket s3://target-bucket/index.html \
--wordlist wordlists/default.txt \
--workers 20
Mehrere Buckets (kommasepariert):
bucky \
--role-arn arn:aws:iam::123456789012:role/bucky-role \
--bucket bucket1,bucket2,bucket3 \
--wordlist wordlists/default.txt
Mehrere Buckets aus einer Datei:
bucky \
--role-arn arn:aws:iam::123456789012:role/bucky-role \
--bucket-file targets.txt \
--wordlist wordlists/default.txt
Ergebnisse als JSON speichern:
bucky --bucket target-bucket --wordlist wordlists/default.txt --json
bucky --bucket target-bucket --wordlist wordlists/default.txt --json --output results.json
Ausgabe:
=== Phase 1: Konten-ID-Ermittlung ===
[*] Überprüfe Zugriff auf Bucket: target-bucket
[+] Zugriff bestätigt
[+] Bucket-Region: us-west-2
[*] Ermittle Konto-ID...
[██████████████████████████████] 12/12 | 675351422352
[+] Konto-ID: 675351422352
=== Phase 2: Bucket-Entdeckung ===
[*] Fuzze Buckets für Konto: 675351422352
[*] 312 Kandidaten aus Wortliste geladen
[+] GEFUNDEN: target-backups
[+] GEFUNDEN: target-logs
[██████████████████████████████] 312/312 | 2 gefunden
=== Zusammenfassung ===
Konto-ID : 675351422352
Quelle : target-bucket
Region : us-west-2
Entdeckt : 2 weitere Buckets
- target-backups
- target-logs