#JavaScript原型链污染
这篇文章详解了原型链污染
注册页面看到
let user = {username, password, isAdmin}if(isAdmin){if(!inviteCode){alert('invite code required')return}user = {...user, inviteCode}}fetch('/register', {method: 'post',body: JSON.stringify(user)}).then(res => res.json()).then(res => {alert(res.msg)if(!res.err){location.href = '/login'}})}function handle_isAdmin_change(isAdmin){document.getElementById('div-invitecode').hidden = !isAdmin}
没什么用
[[JavaScript 原型链与原型链污染全解析]]
看了wp才知道 是JavaScript 原型链与原型链污染
fuzz测试
源码:
// post请求的路径
app.post('/register', (req, res) => {let user = JSON.parse(req.body) // 把我们输入的账号密码,从json字符串转成对象// 判断我们有没有输入账号和密码if (!user.username || !user.password) { return res.json({ msg: 'empty username or password', err: true })}// 判断账号是否存在总对象的username里,如果相同的username就是重复用户名了if (users.filter(u => u.username == user.username).length) { return res.json({ msg: 'username already exists', err: true })}// isAdmin是否true 与 邀请码是不是等于这个常量,所以sql注入没用,邀请码是个常量if (user.isAdmin && user.inviteCode != INVITE_CODE) {user.isAdmin = falsereturn 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 }) // 设置返回信息
})
这里的 Object.assign 类似merge
,如果源对象包含 { __proto__: { isAdmin: true } }
,合并时会修改目标对象的原型链,导致 Object.prototype
被篡改。
且看到user 为json解析出来的,故json里任意一处添加"__proto__": {" isAdmin": true }
都行
(检测过了,这里的payload还必须是这种形式:"__proto__": {" isAdmin": true }
[[如何修改原型?]] 我们要修改原型admin为true从而造成它下面污染 我们通过 __proto__
污染原型链
抓包
污染成功
CatCTF{test_flag_h0w_c@n_I_l1ve_w1th0ut_nilou}