在学习复现OAuth2相关漏洞时,发现对于CVE-2019-3778,网上并没有公开真正可以利用的EXP,且少有的分析并不正确。于是我对源码进行了分析,编写了EXP。因此有了这篇文章。文章中出现的代码以及环境在https://github.com/ananaskr/OAuth2\_Vulnerabilities\_Reproduction/tree/master/CVE-2019-3778上可以找到
攻击者使用授权码模式可以构造一个请求发送至授权端点。在构造的请求中,攻击者篡改了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_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的基础上进行更改,然后返回。