代码之美
首发于代码之美
CSRF实战:借刀杀人之全民助我投诉吧主

CSRF实战:借刀杀人之全民助我投诉吧主

CSRF全称为“跨站请求伪造”,顾名思义:外站可以通过特殊技巧伪造一个发往本站的请求。但是这里的“跨站”是狭义上的跨站,事实上该请求也是可以来自本站。

为什么我开头要强调这里的跨站是侠义的呢?因为今天我要演示的这个漏洞实际上利用了百度贴吧的两个漏洞。一个是投诉吧主接口的CSRF漏洞,另一个是百度贴吧发视频贴时可以修改视频预览缩略图为黑客任意指定的URL。前者为漏洞的核心利用方式,后者为漏洞的核心触发方式。

挖掘篇:

既然要实现伪造请求,那么我们得先看看请求长什么样。

第一步,老老实实按照正常逻辑提交表单,但是提交的过程中请打开chrome的开发者工具或者其他可以抓取浏览器HTTP请求包的软件。


比如说我想投诉某吧吧主,先填写好表单,打开开发者工具,切换到network选项卡,将network上的黑色点点点成红色(新版本貌似默认为红色,红色表示网页出现跳转的时候不清空列表中已经抓到的数据包)。

点击提交按钮,请求已经发送成功,观察开发者工具。

是否多了一条请求。

接着我们到form data这里,然后点view source把格式化的post数据转化为URLencode数据方便我们构造请求。(如果不懂这一步的意义可以忽略,看到后面就明白了)

也就是这个样子,这是投诉的接口

构造csrf的payload(有效载荷)为http://tieba.baidu.com/pmc/tousu/commitTousu?然后加上前面那个post数据也就是
manager_uid=725070526&manager_uname=%25E9%25AB%25987192&forum_id=7993&forum_name=%25E5%25BF%2583%25E7%2590%2586%25E5%25AD%25A6&complaint_type=illegal&reason=%25E5%2588%25B6%25E5%25AE%259A%25E5%2590%2584%25E7%25A7%258D%25E4%25B8%258D%25E5%2590%2588%25E7%2590%2586%25E7%259A%2584%25E5%2590%25A7%25E8%25A7%2584%25EF%25BC%258C%25E7%25BA%25B5%25E5%25AE%25B9%25E6%259F%2590%25E4%25BA%259B%25E6%259C%2589%25E5%2581%25BF%25E6%2594%25B6%25E8%25B4%25B9%25E5%25BF%2583%25E7%2590%2586%25E5%2592%25A8%25E8%25AF%25A2%25E6%259C%25BA%25E6%259E%2584%25E5%258F%2591%25E5%25B8%2583%25E5%25B9%25BF%25E5%2591%258A%25E3%2580%2582

最终构造为

这个样子。

我们需要伪造的请求URL已经全部构造完毕,任何用户只要登录之后访问该链接,就会自动提交和我之前提交过的一模一样的那种吧主投诉请求(包括投诉理由,要投诉的吧主id等等),并且看到一条json数据,json里面的error错误码如果为0表示投诉成功了。

利用篇:

接下来我们需要思考,怎么让广大百度贴吧吧友们都能点开我这个链接呢?难道我直接作为帖子内容发给别人吗?肯定不行的,虽然确实有很多安全意识薄弱的用户会随便点击链接,但是毕竟我们能不能再提高一下这个链接的点击率,比如说让用户只要看到我的帖子就能自动请求这个链接呢?这就涉及到了CSRF的第二个关键点——触发方式了。

我曾经在乌云逛过一段时间,根据别人的思路,发现了一个可以让用户在贴吧的吧主页(frs)看到我的帖子之后立马请求该链接的方式。该方式的核心原理其实就是发送一个视频贴,但是在发送之前,我们通过一些技巧,悄悄的把视频贴的预览缩略图URL替换成我们自己的URL,也就是上面那个请求链接。

下面来看具体操作。

首先发一个视频,然后右键点击该视频,在弹出来的菜单中点击审查元素


在审查元素里面我们能看到许许多多的html元素,我们重点关注data-vpic部分,发现它其实就是视频的缩略图,我们尝试直接替换该缩略图然后发帖发现提示发帖失败。根据我逛乌云社区,参考别的大神的思路,把data-pkey删除一位,然后再把data-vpic改为刚才构造好的链接,然后接着在末尾加上&.jpg。把data-pkey删除一位是为了让该校验数据失效(这里就是该漏洞所在,位数不对就不校验data-vpic是否被篡改了),加上&.jpg目的是为了绕过百度对data-vpic的末尾参数是否为jpg图片格式的检测。

然后我们把该视频发出去,结果还是提示失败。怎么回事呢?难道就这样放弃了吗?

不,再想想,发送失败是不是data-vpic的长度太长了,要不我们把投诉理由改短一点,然后不做URL编码了,直接把该链接做urldecode处理(因为像chrome等主流浏览器在遇到请求中带中文的情况都会自动做urlendoce编码处理,我们不需要自己转换,只要在URL里面带上原始的中文参数即可),最后把URLdecode之后链接替换data-vpic发送发现成功,然后我们切换到小号,打开那个被我们发送了带有CSRF漏洞帖子的贴吧主页,过几秒钟等页面图片全部加载完毕,然后去消息中心查查投诉记录,是否多了一条记录,多了说明成功了。

要扩大该漏洞影响力,可以尝试在中型贴吧发帖,然后不停顶帖。但是由于手机客户端访问不会显示视频预览图,因此我们可以针对一些计算机,编程类贴吧发送这类帖子,因为他们的用户群使用电脑访问贴吧的比例更大,这也是CSRF漏洞利用的一些小技巧。

修复篇:

当然我在BUG吧第一次发这个贴的时候(【BUG】◇15-05-17◆〖教程帖〗我发一个教程贴不晓得可否申精品_bug吧_百度贴吧),第三天该漏洞就被修复了,不得不佩服百度程序员的速度。

至于如何修复和防范,那么得从CSRF的原理入手了。

CSRF本质上是外站可以对本站发起任意请求,其中跨站请求伪造的伪造指的是用户本身没有主动发起请求,这个请求是我们带上用户的身份伪造出来的。因为浏览器有cookie机制,所以我们请求的时候只要用户处于登录状态,那么就会带上这个cookie,由于大多数用户登陆的时候都习惯性的勾上保持登录xx天状态。那么伪造就会变得十分简单。

那么我们该如何防止外站对本站发起伪造的请求呢?

最原始的就是通过referer判断了,由于在客户端(浏览器)层面,JavaScript是无法修改referer然后发起请求的,所以看似这个方法具有可行性,但是别忘了本文开头就说过,跨站是侠义的,正如本篇文章所述的漏洞就是来自本站伪造的请求。并且现在还有很多客户端会跳转到网页,客户端跳转也是不带referer的。综上所述,referer判断这种方式几乎没什么安全性可言。

接着还有就是通过csrf_token了。对前端安全有所了解得人都知道,客户端浏览器都有一种安全机制叫做“同源策略”,他保证了不同的域下不能互相访问各自的资源。那么只要我们在网页视图生成的时候往表单上添加一个hidden域内容为csrf_token,然后每次提交都带上这个csrf_token,服务器检测之前发送过来的csrf_token是否一致,是的话就说明是正常提交,非伪造请求。由于外域受到同源策略限制,无法读取攻击目标域下的csrf_token字段,因此无法通过服务器对csrf_token的验证,共计也就不可能完成。那么有人会问,同域下怎么办呢?由于同域下要读取csrf_token字段,必须要通过JavaScript来完成,如果目标域下没有xss漏洞,我们就无法注入自己的JavaScript脚本,也就无法获取到该csrf_token,一样可以成功防御CSRF攻击。

百度这次的修复方式也是在投诉吧主的表单里面添加了csrf_token字段。(在百度贴吧产品线中该字段的name为tbs,可通过tieba.baidu.com/dc/comm获取,算法是根据当前时间戳加上他们写在服务端脚本中的一个密钥然后substr前16位,别问我怎么知道的)。

而目前主流的PHP全栈框架比如说Laravel,Yii等都自带CSRF防御的中间件(与java中的拦截器,过滤器比较类似),大大减少了目前新应用中出现CSRF攻击的几率。



本文章由 @昌维 原创,在百度贴吧BUG吧【BUG】◇15-05-17◆〖教程帖〗我发一个教程贴不晓得可否申精品_bug吧_百度贴吧首发,由作者转载到知乎专栏-代码之美 https://zhuanlan.zhihu.com/codes ,转载请注明出处,谢谢。

文章被以下专栏收录

    对于一些人来说,编程可能只是一项工作,对于另一些人来说,编程就像一种创作,对于少数人来说,编程仿佛是一种艺术。我希望你看完我的专栏,能成为最后的少数人。 我希望把自己的学习经历,自己所了解到的许多专业知识分享给你们,让许多充满热情与创造力的programmer能够不被那些学习道路上的BUG拦住了你那颗火热的上进之心。 也许我废话连篇,也许我有技术性的错误,也许我在写作方向上与你的口味有所不对,希望你能私信与我畅谈,你们的宝贵意见,你们的批评与见解将帮助我和其他我专栏的关注者带来更好的体验与收获。 QQ交流群:255258140