萌新第一次分析Discuz,瑟瑟发抖中....

此次记录采用正向分析的流程,从web功能点入手

正文 - 输入

/misc.php?mod=ranklist&type=member

上榜宣言这里存在及其复杂的DOM 存储型XSS,笑哭 ==

分析了一天一夜这个别人的漏洞,好惨 ==

通过F12查看,表单action="home.php?mod=spacecp&ac=top"

跳到home.php发现其他代码没啥用,最后一行载入了其他文件

/home.php

跟进libfile函数,Discuz使用该函数来载入所需文件

/source/function/function_core.php

将参数带入该函数得知:调用了/source/module/home/home_spacecp.php文件

跳到home_spacecp.php发现其他代码没啥用,最后一行载入了其他文件

/source/module/home/home_spacecp.php

将参数带入libfile函数得知:调用了/source/include/spacecp/spacecp_top.php文件

跳到spacecp_top.php文件

发现将note参数的值带入了getstr函数

/source/include/spacecp/spacecp_top.php:68

查看getstr函数得知,将note参数的值代入了dhtmlspecailchars函数

/source/function/function_home.php:29

查看dhtmlspecialchars函数得知,会将<">&实体化

/source/function/function_core.php :204

后续的流程就是存储到数据库里面,便不再赘述

正文 - 输出

输出点在查看全部排行处

/misc.php?mod=ranklist

跟进misc.php文件,结尾处载入了/source/module/misc/misc_ranklist.php文件

跟进misc_ranklist.php文件,中间位置载入了/source/inclue/misc/misc_ranklist_index.php文件

跟进misc_ranklist_index.php文件

/source/inclue/misc/misc_ranklist_index.php

第115行调用了getranklist_members函数

可以得知再提取note参数后,将它带入了dhtmlspecialchars函数进行了转义

/source/module/misc/misc_ranklist.php :167

第129行是使用了模板进行渲染,最后include的文件是/data/template/1_diy_ranklist_ranklist.tpl.php文件

/data/template/1_diy_ranklist_ranklist.tpl.php :40

note参数直接输出到tip属性中,跟进一下前面onmouseover属性里面的showTip函数

/static/js/common.js :1063

传入了$F函数,跟进看一下得知_showTip是一个函数

/static/js/common.js :414

跟进_showTip函数

需要注意的是_showTip函数此时传入的参数ctrlobj,是当初html里面的this,也就是包含note参数值的整个标签

/static/js/common_extra.js :932

第942行得知将tip属性的值输出到了div标签里面

如上便是从输入到输出的整个流程

正文-BYPASS

再回过头来看一眼dhtmlspecialchars函数

/source/function/function_core.php :204

针对该处存储型XSS,主要的过滤便是入库是带入了一次dhtmlspecialchars函数;

出库时,又带入了一次dhtmlspecialchar函数。

由于两次带入该函数,第二个参数均未设置,所以只需要着重研究该函数的第二个if判断,也就是第210行即可。

通过输出点可以看到(static/js/common_extra.js :942),输出点在文本标签内,所以需要构造的是完整的HTML标签的Payload。

使用该Paylaod:

<details/open/ontoggle=alert(1)>

关于该Payload,感兴趣的同学可以移步我的另一篇文章:http://teagle.top/index.php/archives/128/

此刻来进行模拟:

输入该Payload,入库时将尖括号替换为HTML实体:( /source/function/function_core.php :211 )

&lt;details/open/ontoggle=alert(1)&gt;

出库时:

  1. &替换为HTML实体: &amp;lt;details/open/ontoggle=alert(1)&amp;gt; (/source/function/function_core.php :211 )

此时浏览器的HTML引擎是无法识别的。

此时赤裸裸的输入Payload是无法成功执行的。

回过头来咱们再看一下第212行,HTML实体化之后,进行了一个判断该字符串是否存在&amp;#,如果存在则进行下面的正则替换。

看一下正则替换:

匹配&# 后面三到五个数字或者x开头后面4个在[a-fA-f0-9]范围内的字符。

然后将&替换为&,后面再拼接井号(#)跟匹配到的字符串。

也就是说如果$sting变量是:

&amp;#1234test

那么会被替换为

&#1234test

如果$string变量是:

&amp;#x1234test

那么会被替换为

&#x1234test

可以明显的看到,是HTML十进制与HTML十六进制的格式。

回过头来再看一下输出点:

/static/js/common_extra.js :942

第942行,可以看到使用了JS里面标签对象的getAttribute方法,这个方法可以直接解析HTML编码,也就是说:

如果最后这个tip参数的值为:

  1. <details/open/ontoggle=alert(1)>或者
  2. &#x003c;details/open/ontoggle=alert(1)&#x003e;

那么都会成功触发XSS,这里之所以在x后面加上两个零是为了构造可以绕过dthmlspecials函数里面的正则替换

此时咱们可以逆向一下流程,来确定一下输入时输入什么Payload,才能绕过过滤执行XSS攻击:

最后输出为:

&#x003c;details/open/ontoggle=alert(1)&#x003e;

正则替换前:
&amp;#x003c;details/open/ontoggle=alert(1)&amp;#x003e;

输出时HTML实体编码前:
&#x003c;details/open/ontoggle=alert(1)&#x003e;

输入时HTML实体编码时:

发现如上Payload不会触发检测

也就是说最终要输入的Payload便是:

HTML十进制/HTML十六进制的尖括号的Payload

&#x003c;details/open/ontoggle=alert(1)&#x003e;

discuz_xss.gif

临别

感谢团队HeatSky师傅以及Thinking师傅的鼎力相助,在我对知识点困惑不解时,无私并且及其耐心的为我讲解。

Thinks。

经研究发现,尽管是刚爆发的漏洞,但是3.4版本并不受影响。

原因是3.4版本中,dhtmlspecailchars函数已经删除preg_replace那一行:

Snipaste_2018-10-24_18-28-10.png

确定3.3版本是存在的。

感谢团队狗哥的斧正。


本文由 TEag1e 创作,采用 知识共享署名 3.0,可自由转载、引用,但需署名作者且注明文章出处。

还不快抢沙发

添加新评论

icon_redface.gificon_idea.gificon_cool.gif2016kuk.gificon_mrgreen.gif2016shuai.gif2016tp.gif2016db.gif2016ch.gificon_razz.gif2016zj.gificon_sad.gificon_cry.gif2016zhh.gificon_question.gif2016jk.gif2016bs.gificon_lol.gif2016qiao.gificon_surprised.gif2016fendou.gif2016ll.gificon_mrgreen.pngicon_neutral.pngicon_twisted.pngicon_arrow.pngicon_eek.pngicon_smile.pngicon_confused.pngicon_cool.pngicon_evil.pngicon_biggrin.pngicon_idea.pngicon_redface.pngicon_razz.pngicon_rolleyes.pngicon_wink.pngicon_cry.pngicon_surprised.pngicon_lol.pngicon_mad.pngicon_sad.pngicon_exclaim.pngicon_question.pngicon_rolleyes.gif2016gz.gif2016kun.gif2016zhem.gif2016am.gif2016kel.gificon_twisted.gif2016lh.gificon_neutral.gif2016ka.gif2016tx.gificon_evil.gif2016bb.gif2016yun.gif2016qq.gif2016baojin.gificon_confused.gif2016kk.gif2016zk.gif2016kb.gificon_mad.gif2016yhh.gificon_exclaim.gif2016xia.gif2016gg.gif2016qd.gificon_smile.gif2016lengh.gificon_biggrin.gif2016bz.gif2016wq.gificon_eek.gificon_arrow.gificon_wink.gif2016tuu.gif