【CVE-2019-3778】Spring-Security-OAuth2 Open Redirection 复现分析
2020-03-24 10:49:10 Author: xz.aliyun.com(查看原文) 阅读量:345 收藏

在学习复现OAuth2相关漏洞时,发现对于CVE-2019-3778,网上并没有公开真正可以利用的EXP,且少有的分析并不正确。于是我对源码进行了分析,编写了EXP。因此有了这篇文章。文章中出现的代码以及环境在https://github.com/ananaskr/OAuth2\_Vulnerabilities\_Reproduction/tree/master/CVE-2019-3778上可以找到

CVE描述


攻击者使用授权码模式可以构造一个请求发送至授权端点。在构造的请求中,攻击者篡改了redirect_uri参数的值,导致授权服务端将用户回调至攻击者可控的URI,泄漏了授权码(因为授权码是附在redirect_uri后面)。

影响版本

2.3 - 2.3.4
2.2 - 2.2.3
2.1 - 2.1.3
2.0 - 2.0.16

环境要求

漏洞描述中要求应用必须满足以下2点:

  • 必须是授权服务器的角色,即需要@EnableAuthorizationServer注解
  • 使用的DefaultRedirectResolver类来解析redirect_uri。

注册client

需要在服务端注册客户端的信息,包括client_id,redirect_uri等。复现时直接向数据库表oauth_client_details中插入了如下数据

client_id : ananskr
client_secret: 123456
redirect_uri: http://www.baidu.com
scope: all
authorized_grant_type: authorization_code

添加用户信息

com.ananaskr.oauth.config中的WebConfig,添加了3个用户的信息

由于Open Redirection与redirect_uri相关,首先定位到获取redirect_uri的函数obtainMatchingRedirect()中(位于org.springframework.security.oauth2.provider.endpoint.DefaultRedirectResolver)。代码如下:

可以得知,在通过了redirectMatches()函数的验证后,就会直接返回输入的redirect_uri值。进一步跟进redirectMatches()函数,代码如下:

这段代码中,对scheme、host、path以及port四部分进行了检查,与注册的redirect_uri一致才可通过验证。此时想到了利用userinfo来进行绕过,因此需要满足的条件是userinfo中包含了evil url且在浏览器中,要跳转到evil url。因此立刻想到了诸如http://evil.com\@www.baidu.com,很遗憾的是,\在此程序中会被当作是不合法字符,在高版本的tomcat中会报错。在换成低版本的tomcat后,\会被解析为%5C,导致浏览器中的值为http://evil.com%[email protected],还是跳转到了baidu。
在网上进行利用姿势的寻找时,发现Blackhat 2019有一篇文章"Make Redirection Evil Again URL Parser Issues in OAuth"中提到了一种利用方式,通过添加%ff,在服务端解析错误后,会将其变成?,从而达到目的。

关于OAuth2.0相关知识,可以从很多地方得知,这里就不赘述了。

在浏览器打开如下链接,会跳转至/login,然后输入上述添加的用户信息,点击authorize。

http://localhost:9090/oauth/authorize?response_type=code&client_id=ananaskr&redirect_uri=http://www.google.com%[email protected]&scope=all&client_secret=123456

可以看到授权后跳转到了www.google.com,而不是注册的www.baidu.com

通过对比2.3.5版本,发现2.3.5版本中org.springframework.security.oauth2.provider.endpoint的DefaultRedirectResolver类中,首先对redirect_uri合理性检验增加了对userinfo的检查,且对请求参数也进行了检查。

然后在obtainMatchingRedirect函数中,不再返回用户输入的值,而是在注册的redirect_uri的基础上进行更改,然后返回。


文章来源: http://xz.aliyun.com/t/7409
如有侵权请联系:admin#unsafe.sh