目錄
前言
正文
信息收集
代碼審計
?驗證
結尾
前言
七月始,暑假副本也正式開啟
正文
信息收集
看著貌似沒啥意義
看樣子是有備份文件
下載下來
快速審計一下
代碼審計
來吧
app.js沒啥東西,主要是功能是實現error
我們找一找有沒有index.js
找到了
\www\routes\index.js
var express = require('express');
const setFn = require('set-value');
var router = express.Router();const Admin = {"password":process.env.password?process.env.password:"password"
}router.post("/getflag", function (req, res, next) {if (req.body.password === undefined || req.body.password === req.session.challenger.password){res.send("登錄失敗");}else{if(req.session.challenger.age > 79){res.send("糟老頭子壞滴很");}let key = req.body.key.toString();let password = req.body.password.toString();if(Admin[key] === password){res.send(process.env.flag ? process.env.flag : "flag{test}");}else {res.send("密碼錯誤,請使用管理員用戶名登錄.");}}});
router.get('/reg', function (req, res, next) {req.session.challenger = {"username": "user","password": "pass","age": 80}res.send("用戶創建成功!");
});router.get('/', function (req, res, next) {res.redirect('index');
});
router.get('/index', function (req, res, next) {res.send('<title>BUGKU-登錄</title><h1>前端被炒了<br><br><br><a href="./reg">注冊</a>');
});
router.post("/update", function (req, res, next) {if(req.session.challenger === undefined){res.redirect('/reg');}else{if (req.body.attrkey === undefined || req.body.attrval === undefined) {res.send("傳參有誤");}else {let key = req.body.attrkey.toString();let value = req.body.attrval.toString();setFn(req.session.challenger, key, value);res.send("修改成功");}}
});module.exports = router;
看到了沒掃到的接口
同時也發現setFn極有可能存在原型鏈污染
const setFn = require('set-value');
setFn(req.session.challenger, key, value);
由于名字叫做sodirty,所以更加堅定了這個想法
我們來講一講什么原型鏈污染
原型鏈污染是一種在JavaScript中可能存在的安全漏洞,它允許攻擊者修改對象的原型屬性,從而影響到其他依賴這些屬性的對象。這種攻擊通常發生在Web應用程序中,當開發者沒有正確地驗證或清理用戶提交的數據,并且這些數據被用作構造函數或對象方法的參數時,就可能發生原型鏈污染
這里setFn作為指針動態調用set-value,且key 的值完全由用戶控制(通過 req.body.attrkey)
如果我們嘗試構造"__proto__[password]"
或 "constructor.prototype.password"
,那么他們可以嘗試修改對象原型,從而改變其繼承的屬性
具體來說,當 key 是一個指向原型屬性的路徑時,set-value 庫可能會嘗試在原型鏈上設置這個屬性,這就會導致原型鏈污染
這邊Admin 對象的 password 字段被用于比較,如果攻擊者能夠通過原型鏈污染將原型中的 password 屬性設置為與 Admin 相同的值,那么他們就可以繞過身份驗證,從而獲取到 flag
當然這目前只是猜想
除此之外
if(req.session.challenger.age > 79){res.send("糟老頭子壞滴很");}
router.get('/reg', function (req, res, next) {req.session.challenger = {"username": "user","password": "pass","age": 80}res.send("用戶創建成功!");
});
/reg默認創建age:80
所以我們需要通過
router.post("/update", function (req, res, next) {if(req.session.challenger === undefined){res.redirect('/reg');}else{if (req.body.attrkey === undefined || req.body.attrval === undefined) {res.send("傳參有誤");}else {let key = req.body.attrkey.toString();let value = req.body.attrval.toString();setFn(req.session.challenger, key, value);res.send("修改成功");}}
?進行修改
?驗證
首先注冊
然后就是
我也不知道為什么使用bp進行傳參時會失敗.......所以使用hackbar進行測試
接下來就是修改admin的password
然后就可以直接獲取flag
還有就是為什么ip不一樣了,因為前面的環境崩了
?
成功
結尾
學習學習學習!!!!
求贊求關注
感謝
作者的其他文章
攻防世界-WEB-WEIPHP(記一次有趣的代碼審計)-CSDN博客
攻防世界-WEB-catcat-new-CSDN博客
攻防世界-WEB-filemanager-CSDN博客
BugKu-new_php_bugku newphp-CSDN博客