某系统任意用户伪造登录

  • A+
所属分类:安全文章

学了一段时间漏洞复现,也有点手痒了,所以就有了这篇文章。


0x01 漏洞简介


该漏洞是由于在验证用户是否登录的时候采用了jwt-token验证的形式,又加上服务端生成jwt-token的时候使用了密钥硬编码,所以导致token伪造,任意用户登录。文章可能涉及一些 jwt 和 spring security 相关的知识,感兴趣的可以去学习一下。


0x02 漏洞分析


由于是未公开的漏洞,所以某些代码可能会打上码,希望理解,主要是分享一下这种类型漏洞的挖掘思路。


该系统是基于SpringBoot+MyBatis+spring security实现的,首先我们要清楚的知道,文件上传意义不是非常大了,因为springboot不能很好的支持jsp文件解析,除去极少个别的linux系统任意文件上传到任务管理反弹shell的情况,其他文件上传意义并不是特别大,当然如果大佬们有什么其他的骚姿势,也可以互相交流下。


源码down下来后,第一件事就是idea打开查看下pom.xml文件,看看引入了哪些依赖,如图

某系统任意用户伪造登录


首先引起我注意的就是jjwt,因为jwt-token如果用作用户身份凭证,是有可能存在token伪造的。


看到使用了jwt了,就习惯性地 ctrl+shift+r 全局搜索 "jwt"

某系统任意用户伪造登录


可以看到一些关键性的信息,jwt存储的请求头和jwt加解密使用的密钥,然后可以看到生成token的方法,这些信息是比较关键的,我们一定要留意。


因为,jwt加解密密钥如果是写死的话,那么我们就可以伪造用户登陆了,现在我们就来看看jwt-token,是如何生成的,跟进generateToken(userDetails)方法,如图

某系统任意用户伪造登录


可以看到是从userDetails对象中获取到用户名设置到claims集合中,key为sub,还有将created设置为当前时间。


然后带入了generateToken(claims)方法中,我们继续跟入

某系统任意用户伪造登录


可以看到使用了jjwt组件的默认工具类创建了token,分别设置了claims、过期时间、加密方式和密钥。这是jwt常用的加密方式,看到这里我们就能知道token是如何创建的了,前面说过,只要secret密钥可以知道,我们就可以伪造token了。


但是,先别激动,我们得确认是否真的就是只验证了token正确,就可以伪造用户登陆了,因为有些系统是会从数据库中查询是否存在我们传入的token的,如果数据库中不存在,那么也是无法登陆的。


这时我们就需要查看配置文件了,看看设置了哪些过滤器,关于用户身份认证的过滤器。由于该系统是使用了security作为认证和权限校验框架,所以我们就去找对应的配置类,ctrl+shift+r 全局搜索 "websecurityconfigurerAdapter",如图

某系统任意用户伪造登录


因为该项目是使用的注解方式配置security配置文件的,所以我们针对性搜索就可以搜索出配置类。


上图可以看到添加了jwtAuthenticationTokenFilter()过滤器,看到 jwt 我们就应该敏感起来了,看一下该类做了哪些操作,如图

某系统任意用户伪造登录


可以看到,首先先从request对象中获取this.tokenHeader请求头,该请求头为前面看到的Authorization请求头。然后判断请求头是否不为null同时以Authorization开头,之后截取Authorization之后的内容,也就是token的内容,使用的是bearer方式,只要拿着token令牌就可以访问对应的资源。


然后将获取到的token带入getUserNameFromToken(authToken)方法,解析获取到用户名。再将解析出来的用户名带入数据库查询,获取到真实用户对象,也就是包含用户的所有信息(账号密码之类的)。


最关键的就是jwtTokenUtil.validateToken(authToken, userDetails)方法,因为只有该方法为true时才算通过认证了。我们可以跟进去看一下是如何检验的。如图

某系统任意用户伪造登录


可以看到,先是调用了前面一样的方法,从token中获取用户名,然后判断获取到的用户名和数据库中查询出来的用户名是否相等,并且token没有过期,就可以返回true。所以我们重点关注点就是在getUserNameFromToken方法,只要该方法没有从数据库中来校验token,那么我们就可以确定存在token伪造漏洞了,跟进去如图

某系统任意用户伪造登录


继续跟进

某系统任意用户伪造登录


可以看到使用了jwt工具类解析的token,并没有从数据库中查询来校验token,到这里我们就可以确认该系统存在token伪造漏洞了。


现在我们来整理一下已知的信息:

  • 该系统支持jwt-token身份认证

  • jwt密钥可知,硬编码了

  • 没有从数据库中查询验证token是否真实存在


那么,就可以愉快的使用默认的密钥来构造token了,如图

某系统任意用户伪造登录


最后来看一下伪造token使用前后的对比图


使用前,如图

某系统任意用户伪造登录


使用后,如图

某系统任意用户伪造登录


到此,漏洞也就分析完毕了,个人感觉,拿到源码审计的时候,要多留意系统有没有使用一些容易出现问题的组件,或者是一些密钥硬编码的问题,因为如果使用了硬编码的话,很可能就是一个通用漏洞哦。



0x03 修复建议


不要使用密钥硬编码,从数据库中查询验证用户token是否有效。


本文始发于微信公众号(伟盾网络安全):某系统任意用户伪造登录

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: