SAML Hacking (phần 2) - XML Signatures
Ở phần trước (nếu bạn nào chưa đọc phần 1 thì có thể tìm và đọc tại đây https://viblo.asia/p/saml-hacking-phan-1-gioi-thieu-ve-saml-Ny0VGd384PA) mình có nói về cách thức hoạt động của SAML. Phần này mình sẽ tiếp tục chia sẻ những gì mình biết về các lỗ hổng có thể tồn tại trong việc triển khai SAML.
XML Signatures
<Response>
<Signature>
<SignedInfo>...</SignedInfo>
<SignatureValue>...</SignatureValue>
<KeyInfo>...</KeyInfo>
</Signature>
<Response>
Như nội dung phần trước, <Signature>
là chứng thực ký số của SAML Response, đảm bảo tính toàn vẹn và xác thực của dữ liệu SAML Response gửi về SP.
SAML sử dụng XML signatures để xác thực thông tin trong quá trình trao đổi dữ liệu. Một vài các thư viện mã hóa XML signatures thường được sử dụng với SAML như:
- OpenSAML
- XMLSec
- Apache Santuario
- …
Chi tiết cấu trúc dữ liệu
Một SAML Response đã được ký sẽ có dạng như sau
<samlp:Response>
<saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">...</saml:Issuer>
<samlp:Status>...
</samlp:Status>
<saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" Version="2.0"
ID="_bZrE7vUYjMxoRV1i3g71Xk8VZbN6Z3vZ" IssueInstant="2023-05-08T07:34:34.718Z">
<saml:Issuer>...</saml:Issuer>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
<SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
<Reference URI="#_bZrE7vUYjMxoRV1i3g71Xk8VZbN6Z3vZ">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
<DigestValue>OyMFJGYZQ55hg1EzTtCNBbuBnI5KpxCEN6hnVwSAfsA=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>
yqVIyhx2Dfch10rp1/mmPwqZwOId7jkZ02xigeVftSF8mAECfqICLCBqPLr4tUbqrcrf0hSUdDVsO78wq0+dyfA/FG212V70BLZBr4mVJ15q220vZmXtK8CxWH+kGJ+XlqGN8Ce1C4luOR8oxLPyfMGbnVAZ5nZWGf+v/vO1Y2gGyxaUhUs4aN3P9537wggzLboaVBDTQYDTSr6CTQbvZOwKcZlmZQ06FI3/JbKtyKfg3ccXf5P99AyOrpNStSwZRNyVtro8G8JRj3cYQUfDKlPTQ8N0n0FIC27T/nFe+PHY3d71xXbMJN8VuvBKeCg7YZb8Doij/ePU4qRa+naKqA==</SignatureValue>
<KeyInfo>
<X509Data>
<X509Certificate>
MIIDDTCCAfWgAwIBAgIJCzMnKigRXB/bMA0GCSqGSIb3DQEBCwUAMCQxIjAgBgNVBAMTGWRldi05bHJsdnllci51cy5hdXRoMC5jb20wHhcNMjIwNzEyMDc0NDQ0WhcNMzYwMzIwMDc0NDQ0WjAkMSIwIAYDVQQDExlkZXYtOWxybHZ5ZXIudXMuYXV0aDAuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3WID/XJzFGML+LQ1f3LmnkwcB5f+Aj6n2Nbor/zEiQ8L4l7LT1t83TLWPVwCgmINB4c83k4i7jf6dt5C2AnLYQbYpGOxJbKMwuG56OMS/5iVI8ICst1xysJFeE2oyPxb+VnNCdGjpWN3DYS916Wbroisk52Q6XLDvDeyzBxGlP0wtWb2yCahE44UB08LjH9jvsKyPaIS6SR30oXc2wEuFi3I+/DF5OTlAQDK52x1UmExsR/mapdHdHjXsMIhM9lHSv9IkdVdkjQDevfSyK+ZhEU5wzTTSj2zDe/ehQ8Oh/2TTvQTs2zRl9oTNtqcNvCnVlqlVVONQFq5X5TiVt77lQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTrGfWhcEbGHwW5sN9HpKWDfE6BQDAOBgNVHQ8BAf8EBAMCAoQwDQYJKoZIhvcNAQELBQADggEBAKpgfhQIeOxC5FMiUK7RP2F7jvfROJP1+TfvzbAylP/RW9ssCFerCT1bGfzaPrJ1CwyfE6PFRGDEZ1qAMdsoObc1GaLBhge/gcLKsasySowWFQgV+Oka1aeYbz9ekj9hSC7lNUZ+JfF4HQn3hZ/sqb77XZZyl0YphwPNEctlfA3r6IRmnvGWeudZEbYL1B5aSAy0R4r45qms2FKyh3lYD5Kki2E9l1xLgkv1MNWWbbj8F2tM1Mf2JpiecSMl/+B/2A4OqtCrRI/awmhvfN25TC/TcH2nBW2ltNGFpPV+A5rBwvS7hi9nrTfa3ciYXDB7skBInViEmXzYeLxrcvm3bqQ=</X509Certificate>
</X509Data>
</KeyInfo>
</Signature>
<saml:Subject>...
</saml:Subject>
<saml:Conditions>...
</saml:Conditions>
<saml:AuthnStatement>...
</saml:AuthnStatement>
<saml:AttributeStatement>...
</saml:AttributeStatement>
</saml:Assertion>
</samlp:Response>
Chi tiết hơn về cấu trúc dữ liệu sau khi ký được mô tả như sau
-
<CanonicalizationMethod>
(Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"): Đây là thuật toán chuẩn hóa dữ liệu được sử dụng để đảm bảo rằng tất cả các phần tử trong tài liệu XML đều được sắp xếp và định dạng theo cách nhất định để tránh bị giả mạo. -
<SignatureMethod>
(Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"): Đây là thuật toán ký số được sử dụng để tạo chữ ký số. -
<Reference>
(URI="#_bZrE7vUYjMxoRV1i3g71Xk8VZbN6Z3vZ"): Tham chiếu đến phần tử cần ký số trong tài liệu XML. -
<Transforms>
: Thực hiện các phép biến đổi trên dữ liệu trước khi tính toán giá trị băm. -
<DigestMethod>
(Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"): Đây là thuật toán băm được sử dụng để tính toán giá trị băm của dữ liệu sau khi thực hiện các phép biến đổi. -
<DigestValue>
: Giá trị băm được tính toán từ dữ liệu tham chiếu và thuật toán băm đã chọn. -
<SignatureValue>
: Giá trị chữ ký số được tạo ra từ dữ liệu được ký số và thuật toán ký số đã chọn. -
<KeyInfo>
: Thông tin về khóa công khai được sử dụng để xác thực chữ ký số, được mã hóa bằng thuật toán RSA.
Quá trình ký XML document
Quá trình ký XML document bao gồm các bước sau:
-
Lấy dữ liệu XML: Đầu tiên, dữ liệu XML cần được thu thập hoặc tạo ra từ nguồn nào đó. Dữ liệu XML này có thể là một tài liệu hoặc một phần của tài liệu được xác định để ký.
-
Áp dụng các biến đổi (Transformations): Tiếp theo, các biến đổi có thể được áp dụng lên dữ liệu XML để chuẩn hóa nó và chuẩn bị cho quá trình ký. Các biến đổi thường được sử dụng bao gồm:
- C14N (Canonicalization): Chuẩn hóa cú pháp của dữ liệu XML để đảm bảo tính duy nhất và thống nhất trong quá trình ký. Như ví dụ bên trên chính là dạng C14N XML
- XSLT (XSL Transformations): Áp dụng các quy tắc và biến đổi XSLT để chuyển đổi dữ liệu XML thành một định dạng khác nếu cần thiết. Ví dụ về XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="xml" indent="yes" /> <xsl:template match="/"> <xsl:apply-templates select="samlp:Response" /> </xsl:template> <xsl:template match="samlp:Response"> <!-- XSLT transformation rules go here --> <TransformedResponse> <!-- Transformation logic --> </TransformedResponse> </xsl:template> </xsl:stylesheet>
- XPath (XML Path Language): Sử dụng các biểu thức XPath để xác định các phần tử hoặc thuộc tính cụ thể trong dữ liệu XML.
/samlp:Response/saml:Assertion/saml:Subject/saml:NameID
-
Tạo Digest (Băm dữ liệu): Sau khi dữ liệu XML đã được chuẩn hóa và biến đổi, một băm (digest) của dữ liệu này được tạo ra. Quá trình băm sử dụng một thuật toán băm như SHA-256 để tính toán giá trị băm (digest) duy nhất từ dữ liệu.
-
Chuẩn hóa SignedInfo: Tiếp theo, phần SignedInfo trong XML document được chuẩn hóa, tức là nó được đưa về một định dạng cụ thể và duy nhất để đảm bảo tính nhất quán và thống nhất trong quá trình ký.
-
Ký SignedInfo: Cuối cùng, phần SignedInfo được ký. Quá trình này sử dụng một thuật toán ký như RSA-SHA256 hoặc HMAC-SHA256 để tạo chữ ký dựa trên dữ liệu đã được chuẩn hóa. Chữ ký được tạo ra bằng cách sử dụng khóa riêng tư của người ký để mã hóa các giá trị của phần SignedInfo. Kết quả là chữ ký được tạo ra và chèn vào XML document, bên trong phần Signature.
Quá trình ký XML document này đảm bảo tính toàn vẹn, xác thực và không thể thay đổi của dữ liệu XML bằng cách kết hợp việc tạo chữ ký với các biến đổi và chuẩn hóa dữ liệu.
Các lỗ hổng trong XML Signatures
Tuy nhiên, khi triển khai XML signatures, cần lưu ý rằng có một số lỗ hổng có thể xảy ra, ảnh hưởng đến tính bảo mật của hệ thống. Dưới đây là một số lỗ hổng phổ biến liên quan đến việc sử dụng XML signatures trong SAML:
-
Key Management: Việc quản lý và bảo vệ các khóa (keys) sử dụng trong quá trình ký số là rất quan trọng. Nếu khóa bị rò rỉ hoặc bị tấn công, nguy cơ giả mạo và xâm nhập vào hệ thống có thể xảy ra.
-
XML Parsing: XML signatures phụ thuộc vào quá trình phân tích cú pháp (parsing) của XML. Nếu có lỗ hổng trong quá trình này, tấn công XML parsing có thể được thực hiện để gửi các dữ liệu độc hại hoặc thực hiện các hành vi xâm nhập vào hệ thống.
-
Algorithm: Các thuật toán mã hóa và băm (hash) được sử dụng trong XML signatures cần được chọn và cấu hình đúng. Nếu sử dụng các thuật toán yếu hoặc bị lỗi, nguy cơ tấn công và giả mạo có thể tăng lên.
-
Validation: Việc kiểm tra và xác thực chính xác của XML signatures là rất quan trọng. Nếu quá trình kiểm tra không được thực hiện đúng cách hoặc bị tắt, lỗ hổng xâm nhập và tấn công giả mạo có thể xảy ra.
Để đảm bảo tính bảo mật của hệ thống SAML, các lỗ hổng này cần được hiểu và giải quyết một cách cẩn thận trong quá trình triển khai XML signatures. Bên cạnh đó, việc sử dụng các thư viện mã hóa XML signatures đáng tin cậy và luôn cập nhật cũng là một yếu tố quan trọng để đảm bảo an toàn và tin cậy trong việc trao đổi dữ liệu SAML.
Một vài lỗ hổng liên quan đến XML Signatures:
CVE-2019-12400
- https://github.com/apache/santuario-java/commit/52ae824cf5f5c873a0e37bb33fedcc3b387cdba6
- https://security.snyk.io/vuln/SNYK-JAVA-ORGAPACHESANTUARIO-460281
CVE này liên quan đến việc org.apache.santuario:xmlsec
(phiên bản 2.0.3) sử dụng cơ chế caching (lưu trữ tạm thời) để tăng tốc quá trình tạo các XML document mới bằng cách sử dụng một nhóm DocumentBuilders tĩnh (liên quan đến XML Parsing). Tuy nhiên cơ chế này có tồn tại lỗ hổng XXE, giúp attacker khai thác lỗ hổng, có thể đọc file tùy ý, .v.v..
CVE-2022-34716: External Entity Injection during XML signature verification
//src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/Utils.cs
XmlReaderSettings settings = new XmlReaderSettings();
settings.XmlResolver = xmlResolver; (B)
settings.DtdProcessing = DtdProcessing.Parse; (A)
settings.MaxCharactersFromEntities = MaxCharactersFromEntities;
settings.MaxCharactersInDocument = MaxCharactersInDocument;
XmlReader reader = XmlReader.Create(stringReader, settings, baseUri);
doc.Load(reader);
Lỗ hổng được phát hiện bởi fwilhelm@google.com, Dtd Processing
được bật tại (A) và một XmlResolver
được cấu hình tại (B), điều này có nghĩa là các External Entity sẽ được xử lý trong quá trình phân tích cú pháp miễn là xmlResolver
không bằng null => XXE
CVE-2021-21239
pysaml2
sử dụng CryptoBackendXmlSec1
để verify signed SAML theo mặc định. Nhưng CryptoBackendXmlSec1
lại sử dụng xmlsec1
binary để verify chữ ký của signed SAML document. Lại nhưng nữa, xmlsec1
lại ưu tiên sử dụng public key có chứa trong SAML document do người dùng gửi lên để verify chữ ký (tham khảo tại https://www.aleksey.com/pipermail/xmlsec/2013/009717.html). Người dùng có thể tạo ra 1 private key, sau đó sử dụng private key này để ký lên SAML document, vậy là chúng ta có thể bypass được việc xác minh chữ ký trên pysaml2
.
Do việc kiểm tra và xác thực chính xác của XML signatures trên pysaml2
sai (thay vì sử dụng public key của Identity Provider lại sử dụng public key trên SAML document) nên chúng ta có CVE này.
Và còn nhiều lỗ hổng khác liên quan đến XML Signatures như không thực hiện validate chữ ký, sử dụng mã hóa yếu, ... Bạn đọc có thể tìm hiểu thêm.
Kết
Vậy đó là tất cả mình biết về XML Signatures, phần tiếp theo mình sẽ đi tiếp về các cách tấn công khác với SAML. See you 😍
Tham khảo
- https://epi052.gitlab.io/notes-to-self/blog/2019-03-13-how-to-test-saml-a-methodology-part-two/
- https://www.slideshare.net/TharinduEdirisinghe2/securing-saml-sso-from-xsw-attacks
- https://twitter.com/_fel1x
- https://www.techtarget.com/searchsecurity/definition/SAML
- https://duo.com/blog/the-beer-drinkers-guide-to-saml
All rights reserved