Pentest

SSRF Demystifie: Exploiter Cloud Metadata dans un Lab AWS Local

Por Equipe Basilisk ·

Reproduction ethique de SSRF contre IMDS avec LocalStack, payloads reels, capture de credentials simules et blocage definitif via IMDSv2.

L endpoint 169.254.169.254 a grille plus de carrieres de SRE que toute autre IP de l histoire du cloud. Capital One en 2019 a perdu 100 millions d enregistrements parce qu un WAF mal configure a laisse un SSRF atteindre l Instance Metadata Service et recuperer les credentials temporaires de la role EC2. Sept ans plus tard on recoit encore des rapports de bug bounty avec le meme schema: l app telecharge une image depuis une URL fournie par l utilisateur, personne ne valide la destination, IMDSv1 reste actif, partie terminee. Reproduisons l attaque depuis zero dans un lab AWS local avec LocalStack, comprenons pourquoi IMDSv2 change la donne, et finissons par un checklist de hardening applicable aujourd hui.

L environnement d abord. Lance LocalStack Pro 4.x via docker-compose avec ec2, iam, sts et s3 actives, plus un conteneur Flask sur le port 5000 qui execute une API fetch-image vulnerable. Le code fait dix-huit lignes: il recoit ?url=, appelle requests.get sans validation, renvoie le body. Pour simuler IMDS dans LocalStack tu as besoin du plugin localstack-ec2-metadata-mock ou d un mock dedie en 169.254.169.254 via netns. Ceux qui veulent une fidelite maximale utilisent un vrai t3.micro a deux centimes l heure, mais LocalStack couvre 95% de l apprentissage sans carte bancaire. Pentest Web depuis Zero: Construire un Lab Sur avec DVWA, Juice Shop et Burp Suite couvre le setup de base des conteneurs vulnerables que tu reutilises ici.

Lab demarre, le payload classique IMDSv1 est litteralement un GET. Depuis Burp, intercepte la requete de l app et remplace le parametre url par http://169.254.169.254/latest/meta-data/iam/security-credentials/. La reponse fuite le nom de la role attachee, disons app-server-role. Ensuite GET http://169.254.169.254/latest/meta-data/iam/security-credentials/app-server-role renvoie un JSON avec AccessKeyId, SecretAccessKey et Token. Exporte les comme variables d environnement, lance aws sts get-caller-identity --endpoint-url http://localhost:4566 et tu es authentifie comme l application. C est le moment ou les blue teams sautent de leur chaise pendant la demo.

L escalade depend des permissions de la role. Dans notre lab j ai attache une policy deliberement permissive avec s3:* et iam:ListRoles. Avec les creds voles: aws s3 ls revele un bucket backups-prod-2026, aws s3 cp s3://backups-prod-2026/db.dump telecharge le dump, et aws iam list-attached-role-policies trace le chemin d escalade via PassRole. Des outils comme Pacu, ScoutSuite et cloudfox automatisent cette enumeration post-compromission. Des patterns similaires apparaissent dans Pentest APIs REST et GraphQL : Checklist Technique pour Bug Bounty Legal quand des endpoints webhook ou image-proxy acceptent des URLs internes sans allowlist. Horodate chaque commande, parce qu un rapport de bug bounty sans PoC reproductible paie zero.

IMDSv2 casse l attaque en exigeant une session avec token. Le flux correct est PUT http://169.254.169.254/latest/api/token avec header X-aws-ec2-metadata-token-ttl-seconds: 21600, puis GET avec header X-aws-ec2-metadata-token. Un SSRF qui ne fait que des GET, sans controle des headers ni de la methode, se bloque tout seul. Force IMDSv2 avec aws ec2 modify-instance-metadata-options --http-tokens required --http-put-response-hop-limit 1. Le hop-limit 1 est crucial: il empeche les conteneurs en bridge d atteindre IMDS via le NAT de l hote. Combine avec un blocage egress 169.254.0.0/16 dans le security group et l app perd tout chemin vers l endpoint magique.

La defense en profondeur ne s arrete pas a IMDS. Valide les URLs dans l app en rejetant 169.254.0.0/16, 127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, fd00::/8 et resous le hostname avant la requete pour bloquer le DNS rebinding. Utilise une lib comme ssrf-protect ou implemente avec getaddrinfo plus verification par famille d IP. Reduis les permissions de la role au strict necessaire, prefere IRSA sur EKS, active GuardDuty pour detecter l usage anormal de credentials, et passe Prowler regulierement. Des techniques web liees figurent dans SQL Injection en Pratique: Exploiter, Detecter et Mitiger dans un Lab Controle et XSS Moderne: DOM, Stored et Reflected avec Exemples Reels en Environnement de Test, qui forment avec SSRF le trio le plus frequent en bug bounty d entreprise. Pour aller plus loin en pivoting interne apres avoir vole des credentials, Pivoting avec Chisel et Ligolo-ng : Reseaux Segmentes en Lab de Pentest est la suite logique.

Takeaway pratique: lance aws ec2 describe-instances --query 'Reservations[].Instances[].[InstanceId,MetadataOptions.HttpTokens]' sur ton inventaire MAINTENANT. Toute instance qui repond optional est exposee au SSRF classique. Force required en masse via un SSM Automation Document, audite les roles avec policies *:* et ajoute un test E2E dans le CI qui tente d atteindre 169.254.169.254 depuis le conteneur de l app et echoue le build sur une reponse 200. Il a fallu dix-sept minutes pour reproduire Capital One dans le lab. Il faut les memes dix-sept minutes pour fermer le trou en production.

Nenhum comentário ainda

Seja o primeiro a comentar.

Deixe seu comentário

Entre com sua conta Canverly para comentar. Você pode usar a mesma conta em qualquer site da rede.

Entrar com Canverly