专栏首页ChaMd5安全团队记一次腾讯SDK源代码审计后的CSRF攻击

记一次腾讯SDK源代码审计后的CSRF攻击

0x00 前言

初进ChaMd5安全团队,应M姐姐之邀写下这篇技术文章,这篇文章主要讲述本人近期代码审计腾讯的第三方登录SDK包时发现的一个漏洞,阅读这篇文章需要读者对OAuth2.0协议的原理和应用特别熟悉,如果读者对此不了解,请参考以下链接:

OAuth2.0协议RFC 文档:

https://tools.ietf.org/html/rfc6749

QQ开放平台的接入说明:

http://wiki.connect.qq.com/oauth2-0%e7%ae%80%e4%bb%8b

这是我之前写的一篇分析OAuth2.0协议安全性的文章:

https://www.anquanke.com/post/id/98392

0x01 攻击模型分析

我在这篇文章里讲的这种攻击方法是针对OAuth协议的一种CSRF攻击,大家都知道,很多网站都有绑定第三方账号的功能,这种攻击手段就是利用了网站的这种功能,为了深入分析漏洞,我先把绑定第三方账号的流程分析一下:

Step 1:某妹子使用账户密码登录XX网站

Step 2:妹子选择绑定QQ账户,在输入凭证信息后,QQ返回如下形式的链接:

http://xx.com/Index.php?Code=XXX

Step 3: 妹子访问上述链接,服务器接收到code参数,进行验证后与当前用户绑定。

为了说明这种攻击方法,我从2012年全国网络与信息安全峰会上知道创宇的一位大佬的PPT里借用一张图:

这种攻击方式看似复杂其实说起来也很简单,主要的问题出现在了上图的第四步中,即攻击者构造链接http://xx.com/Index.php?Code=XXX,其中Code参数绑定的是攻击者的QQ账户,然后发给Victim诱骗点击(CSRF),Victim点击之后,他的账户就与攻击者的QQ账户绑定了,这样攻击者就能通过其QQ登录Victim的账户,实现用户劫持!

当然了,为了防止这种攻击,腾讯在返回的授权登录链接中增加了一个state参数用于防止类似的CSRF攻击。用户在请求使用QQ登录的时候会生成一个与session绑定的不可预测字符串state,并把这个参数发送给授权服务器,授权服务器验证完用户身份后会返回如下形式的链接:

http://xx.com/Index.php?Code=XXX&state=XXX

在接收到此链接时,xx.com会先检测当前session中的state参数和收到的链接中的state参数是否匹配,如果匹配才会进行下一步的操作。这样的话,即使攻击者把自己的授权链接发给Victim,也会因为state验证失败而无法绑定攻击者的账户(攻击者无法预测Victim的session中的state参数,因此就无法构造恶意链接来进行CSRF攻击)。

0x02 漏洞分析

在详细了解了攻击原理之后,我们来剖析一下QQ登录的官方SDK文件。

这里我们废话不多说,直接定位到核心类文件Oauth.class.php

在这个类文件中qq_login方法用于第一步生成state参数并跳转到QQ授权登录接口,可以看到state参数在第36行生成并紧接着调用recorder类的write方法写入到session中,跟进recorder类继续分析:

定位到32行,write方法是把传入的值写到self::$data中,在看到26行,构造函数中self::$data被初始化为一个空数组。

在最后的析构函数中self::$data被存入到session中,这里看上去没有什么大问题,继续向下分析,我们找到Oauth.class.php中的qq_callback方法:

qq_callback方法用于验证state参数并利用传入的code参数获得access_token,我们主要关注state参数的验证阶段,在第57行我们看到有一个if条件判断当前session中的state参数($state)和链接中传入的state参数($_GET['state'])是否匹配,如果不匹配则直接调用showError方法die掉:

但是,问题就出现在这里!之前我们已经分析到,state参数在qq_login方法中生成,但是如果Victim没有调用这个方法,self::$data就会被构造函数初始化为一个空数组,再来看一下recorder类中的read方法:

如果self::$data为空则返回null,因此这里存在一个很明显的逻辑缺陷,只要攻击者把恶意链接的state参数留为空,这时$_GET['state']为空值,$state也为空值,if($_GET['state'] != $state)为false,这样就可以完美的躲过CSRF检测,嘿嘿!

0x04 后记

这个漏洞从确认到修复只用了三个小时的时间,腾讯SRC的响应速度也是非常惊人。

在最新版的SDK文件中,在验证state时会先判断当前的session中是否保存有state参数,即判断当前用户是否调用过qq_login方法,这样就可以成功的阻止类似的CSRF攻击了:

本文分享自微信公众号 - ChaMd5安全团队(chamd5sec),作者:呆哥

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-03-22

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 0ctf2018 heapstorm2详解

    题目链接 https://github.com/eternalsakura/ctf_pwn/tree/master/0ctf2018/heapstorm2 前置...

    ChaMd5安全团队
  • CryptoShield勒索病毒分析

    这篇文章主要分析一下Cryptoshield,来自于RITEST RIG EK的一个勒索病毒。病毒样本可以从这里得到: http://www.malware-t...

    ChaMd5安全团队
  • 360春秋杯3道web题的简单分析

    360春秋杯3道web题的简单分析 From ChaMd5安全团队核心成员 pcat&香香 where is my cat 这题一开始很坑的,存在着/.git/...

    ChaMd5安全团队
  • Flink State 最佳实践

    本文主要分享与交流 Flink 状态使用过程中的一些经验与心得,当然标题取了“最佳实践”之名,希望文章内容能给读者带去一些干货。本文内容首先是回顾 state ...

    Spark学习技巧
  • 小程序云开发仿爱彼迎小程序 | 云开发实战

    目前作者只完成了主页、日期的选择及一个主题民宿页面,这附上源码地址:https://github.com/BeichenloveNancy/mpvue-airb...

    腾讯云开发TCB
  • tensorflow学习笔记(三十七):如何自定义LSTM的initial state

    如何初始化LSTM的state LSTM 需要 initial state。一般情况下,我们都会使用 lstm_cell.zero_state()来获取 ini...

    ke1th
  • weex里Vuex state使用storage持久化

    在weex里使用Vuex作为state管理工具,问题来了,如何使得state可以持久化呢?weex官方提供store模块,因此我们可以尝试使用该模块来持久化st...

    JadePeng
  • CSRF来袭

    最近收到了一份安全漏洞警告--用户账户恶意劫持漏洞,直指我们联登中的state参数存在严重问题

    码农戏码
  • 一次性比较目前前端最流行的状态管理,mobx,vuex,redux-saga使用方式用方式

    杭州前端工程师
  • Chrome插件开发之隐藏页面图片

    forrestlin

扫码关注云+社区

领取腾讯云代金券