4 tipos de ataques comuns no XML


Para quem não conhece, a sigla XML é o acrônimo de EXtensible Markup Language, um termo que foi originalmente criado para suprir os desafios das publicações em larga escala. Hoje, o XML é muito utilizado em serviços web como SOAP, REST, WSDL, RSS feed, Atom e também arquivos de configurações de aplicações mobile e desktop.
Os ataques a esse formato de arquivo normalmente acontecem na inserção de dados no XML ou na entrada que é usada para criá-lo - muitos desses ataques utilizam funcionalidades específicas do XML para a ação.
Confira abaixo alguns ataques que podem acontecer no XML:
XML External Entities (XXE)
O ataque XXE é um dos mais conhecidos no XML e o que tem sido explorado ultimamente em aplicações de grandes empresas, incluindo as que participam de programas de bug bounty, onde são oferecidas recompensas para pesquisadores que encontram vulnerabilidades no sistema.
O XML possui uma característica que permite que o desenvolvedor aponte para um endereço onde o dado está armazenado, local ou remotamente.
Com isso, um atacante pode alterar essa informação e solicitar dados locais ou remotos como no exemplo abaixo:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [  
 <!ELEMENT foo ANY >
 <!ENTITY xxe SYSTEM "file:///etc/passwd" >]><foo>&xxe;</foo>


XML Injection
Os ataques de injeção de dados no XML funcionam de forma parecida com o de scripts, para quem está familiarizado. Podemos subdividir este ataque em três: XML Data Injection, Extensible Stylesheet Language Transformations (XSLT) Injection e XPath/XQuery Injection.


  • XML Data Injection: neste tipo de ataque é realizada a inserção de dados no arquivo XML. Normalmente esses dados não são controlados pelo atacante, mas são interpretados pela aplicação para determinar uma ação, por exemplo:
<?xml version="1.0" encoding="UTF-8"?>
<USER role="user">Atacante</USER>
Caso a aplicação leia estas informações acima para determinar uma ação, o atacante poderá inserir alguns dados com outras permissões para tentar fazer um bypass no controle de acesso de usuários, da seguinte forma:
<?xml version="1.0" encoding="UTF-8"?>
<USER role="user">Usuario1</USER>
<USER role="admin">Atacante</USER>


  • Extensible Stylesheet Language Transformations (XSLT) Injection: neste tipo de ataque, em vez de injetar dados no arquivo XML, o objetivo é inserir códigos que sejam executados no documento. O XSL consiste em XSL Transforms (XSLT), expressões XML Path Language (XPath), XSL Formatting Objects (XSL-FO) e uma folha de estilo (tipo um CSS) que pode ser aplicado em um arquivo XML. Esta folha de estilos pode transformar os dados do arquivo XML em novos dados XML aplicando esta formação. Com isso, um atacante pode injetar códigos capazes de resultar na execução do script no navegador.


  • XPath/XQuery Injection: o XPath e XQuery são linguagens que permitem consultar um documento XML de forma muito semelhante ao SQL, aliás muitos bancos de dados permitem consultar o banco de dados usando XPath ou XQuery. Neste caso um atacante pode criar uma instrução XPath ou XQuery e injetar consultas para obter dados que não seriam possíveis através pelo método convencional. Confira abaixo o exemplo retirado da apresentação do Daniel Tomescu para o OWASP.
Arquivo: employees.xml
<?xml version="1.0" encoding="utf-8"?>
<Employees>
<Employee ID="1">
<Name>Mike</Name>
<UserName>Mike07</UserName>
<Password>TopSecret</Password>
<Type>Admin</Type>
</Employee>
</Employees>
Código C#
String FindUserXPath;
FindUserXPath =
    "//Employee[UserName/text()='"
    + Request("Username")
    + "' And Password/text()='"
    + Request("Password") + "']";


Payload
Username: Mike07
Password: oops' or 'a'='a
Resultado da injeção: FindUserXPath
//Employee[UserName/text()='Mike07' And Password/text()='oops' or 'a'='a']


Infinite Entity Loops
É possível criar um loop infinito dos entities quando criamos duas entradas e uma chama a outra, veja o exemplo abaixo:
<!ENTITY % aa '&#x25;bb;'>
<!ENTITY % bb '&#x25;aa;'>
%aa;
Se você observar o código acima, verá que o entity aa chama o entity bb, que por fim chama o entity aa e com isso entra em um loop infinito gerando um ataque de DoS.
XML Bombing
O ataque de XML Bombing é muito parecido com o loop infinito e tem como objetivo causar um ataque DoS. Confira abaixo um exemplo retirado do artigo do Rami Jaamour:
<?xml version="1.0" ?>
<!DOCTYPE foobar [
<!ENTITY x0 "Bang!">
<!ENTITY x1 "&x0;&x0;">
<!ENTITY x2 "&x1;&x1;">
...
<!ENTITY x99 "&x98;&x98;">
<!ENTITY x100 "&x99;&x99;">
]>
Quando as entities são chamadas recursivamente, ele irá chamar uma quantidade enorme de elementos que irão aumentar o uso de recursos e causar o DoS.


Conclusão
Mesmo no XML os cuidados de segurança devem aplicados de forma rígida, seja na configuração, na validação de dados ou na criação do arquivo XML, além disso, a aplicação do XML Encryption e o XML Signature são obrigatórias quando houver a manipulação de dados sensíveis.
Caso você tenha interesse em testar esses ataques de uma maneira mais prática, eu recomendo olhar o framework chamado Magical Code Injection Rainbow (MCIR) criado pelo Daniel Crowley e disponível no endereço https://github.com/SpiderLabs/MCIR.


Fontes:

GALLAGHER Tom; JEFFRIES Bryan; LANDAUER Bryan. Hunting Security Bugs (Developer Reference) Microsoft Press; 1 edition (June 9, 2006)

Cross-Site WebSocket Hijacking (CSWSH)

Websocket é um protocolo que tem como função habilitar o canal de comunicação full-duplex, persistente, entre servidores e clientes. Sendo assim, ambas as partes podem ser utilizadas para envio de dados a qualquer momento.

Utilizando o protocolo, também é possível fazer troca de mensagens de texto e binárias do servidor ao browser, e vice versa.
       
Como o protocolo vem sendo muito utilizado por desenvolvedores, passou a chamar a atenção dos analistas de segurança. E durante alguns experimentos e pentests dos analistas em aplicações que utilizam Websocket, foi identificado um tipo de cenário onde existe a vulnerabilidade chamada de Cross-Site Websocket Hijacking (CSWSH).
       
Para criar o canal de comunicação full-duplex o protocolo requer um handshake (realizado em http:// ou https://) para mudar para um protocolo WebSocket. O handshake faz um upgrade do protocolo de comunicação para ws:// (ou wss://), porém, por transferir a comunicação baseada em HTTP (S) para o WS(S), este processo de upgrade pode ser um potencial alvo de ataques e o ponto fraco da utilização deste protocolo.
       
O ciclo de vida da interação do Websocket entre cliente e servidor tipicamente é:
1- Cliente inicia uma conexão enviando um request de handshake HTTP (S) Websocket
2- Servidor responde com o handshake response (manipulado pelo servidor de forma transparente para a aplicação) e envia o status de 101 – troca de protocolos.

Desse ponto, tanto o servidor quando o browser se comunicam usando a API do Websocket, com uma conexão simétrica (cada lado pode enviar e recuperar mensagens de texto e binárias).

No nível do browser isso é definido pela especificação da W3´s HTML5 Websocket5 API, já no nível do protocolo via RFC 6455 “The Websocket Protocol”.

Abaixo, vamos analisar a solicitação de um handshake para fazer upgrade do protocolo para Websockets e inspecionar os headers em um cenário imaginário, que usa Websockets para mover rapidamente novas cotações de ações para usuários logados e também recuperar ordens de estoque deles.         

GET /trading/ws/teste HTTP/1.1
Host: www.aplicacao.com.br
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:23.0) Firefox/23.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: de-de,de;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
Sec-WebSocket-Version: 13
Origin: https://www.aplicacao.com.br
Sec-WebSocket-Key: x7nPlaiHMGDBuJeD6l7y/Q==
Cookie: JSESSIONID=1A9431CF043F851E0356F5837845B2EC
Connection: keep-alive, Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
Como podemos ver, da requisição dos headers HTTP (S) handhake request, o dado de autenticação (cookie header) é enviado junto com o handshake de upgrade.

O mesmo seria verdade para os dados de autenticação HTTP. Ambos são corretamente comportados de acordo com a especificação mencionada anteriormente, RFC.
 
Após um handshake bem sucedido do Websocket, o servidor responde com o status 101 – Switching Protocols e a partir daí a conexão ws://(ou wss://) é estabelecida entre o browser e o servidor.

O header Sec-WebScoket-Key é uma parte do handshake interno do browser/servidor, é automaticamente criado e toma conta da iniciação do Websocket quando o browser faz o request.
      
Em relação do cliente durante esta fase de handshake/upgrade, o RFC 6455 diz o seguinte:
This protocol doesn't prescribe any particular way that servers can authenticate clients during the WebSocket handshake. The WebSocket server can use any client authentication mechanism available to a generic HTTP server, such as cookies, HTTP authentication, or TLS authentication.

Isso significa que desenvolvedores podem usar, por exemplo, cookies ou HTTP-Authenticantion para autenticar Websocket handshake request, como se fosse um request HTTP(S) de uma aplicação web.  
       
Considerando o que acontece quando um desenvolvedor adota este estilo que utiliza sessões cookie para autenticar a requisição WebSocket handshake/upgrade dentro de uma parte logada de uma aplicação.

Como o WebSockets não são restringidos pela  política same-origin, um atacante pode facilmente iniciar um request Websocket (ex: processo handshake/upgrade) de uma página maliciosa segmentando o ws:// ou wss:// na URL da aplicação atacada.

Devido  ao fato que o request é um request HTTP(S) regular, os browsers enviam os cookies e os headers de autenticação HTTP juntos, mesmo de cross-site. Como no exemplo abaixo:
GET /trading/ws/teste HTTP/1.1
Host: www.aplicacao.com.br
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:23.0) Firefox/23.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: de-de,de;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
Sec-WebSocket-Version: 13
Origin: https://www.aplicacao-maliciosa-do-atacante.com.br
Sec-WebSocket-Key: hP+ghc+KuZT2wQgRRikjBw==
Cookie: JSESSIONID=1A9431CF043F851E0356F5837845B2EC
Connection: keep-alive, Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
      
O browser envia a informação de autenticação junto com o request de handshake/upgrade do Websocket. Sendo semelhante a um cenário de ataque Cross-Site Request Forgery (CSRF).

Entretanto, no cenário do Websocket este ataque pode ser estendido de um ataque write-only para uma comunicação read/write  com um serviço Websocket, por estabelecer fisicamente uma nova conexão Websocket com um serviço com os mesmos dados de autenticação da vitima. Por isso, chamado de Cross-Site WebSocket Hijacing (CSWSH).
Mitigando
Tornar aplicação mais segura contra ataques CSWSH pode ser feitas seguindo estas contramedidas:
  • Verificar o header de Origin  da solicitação de WebSocket handshake no servidor, uma vez que o header foi designado para proteger o servidor contra ataques cross-site nós browser das vítimas.

  • Utilize tokens aleatórios (como CSRK-Tokens) de sessão individual (session-indivual) no handshake request e verifique-os no servidor.



Referências: