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

第三十八天(Node.JS)

#环境搭建-NodeJS-解析安装&库安装

0、文档参考:

Node.js 教程 | 菜鸟教程

1、Nodejs安装

Node.js — Run JavaScript Everywhere

确保输入 node 时 可以输出版本

输入npm时可以显示下面内容 就算安装完成了

2、三方库安装

express

Express是一个简洁而灵活的node.js Web应用框架

body-parser

node.js中间件,用于处理 JSON, Raw, Text和URL编码的数据。

cookie-parser

这就是一个解析Cookie的工具。通过req.cookies可以取到传过来的cookie,并把它们转成对象。

multer

node.js中间件,用于处理 enctype="multipart/form-data"(设置表单的MIME编码)的表单数据。

mysql

Node.js来连接MySQL专用库,并对数据库进行操作。

安装命令:

npm i express

npm i body-parser

npm i cookie-parser

npm i multer

npm i mysql

#功能实现-NodeJS-数据库&文件&执行

1、Express开发

2、实现用户登录

3、加入数据库操作

 先安装mysql 库

npm install mysql

连接数据库和对数据库内容进行查询,这里是查询admin表中 id=1 的数据

var mysql      = require('mysql');
var connection = mysql.createConnection({
    host     : 'localhost',
    user     : 'root',
    password : '654321',
    database : 'phpstudy'
});
 
connection.connect();
 
var sql = 'SELECT * FROM admin where id=1';
 
connection.query(sql, function (error, results, fields) {
    if (error) throw error;
    console.log(results[0]);
});

将id值改成2

将id接收值改成一个可控变量,尝试用sql注入语句测试执行

 
var express =require('express');
var app = express();
 
var mysql      = require('mysql');
var connection = mysql.createConnection({
    host     : 'localhost',
    user     : 'root',
    password : '654321',
    database : 'phpstudy'
});
 
connection.connect();
app.get('/sql', function (req, res) {
    var id = req.query.id;
    var sql = 'SELECT * FROM admin where id='+id;
    connection.query(sql, function (error, results, fields) {
        if (error) {throw error;
        console.log('[SELECT ERROR] -',error.message);
        return;}
        console.log('[SELECT OK] -',results);
        res.send(results);
    });
});
 
var server = app.listen(8032, function () {
 
    var host = server.address().address
    var port = server.address().port
 
    console.log("应用实例,访问地址为 http://%s:%s", host, port)
 
});

正常输入参数值

输入sql 语句,获取参数显示位置

在显示位置中输入sql语句,获取数据库名和用户名

-文件操作

1、Express开发

2、实现目录读取

3、加入传参接受

 先创建一个1.txt文件,往里面输入一些内容

再创建一个js文件,写入下面代码

右键运行该文件,可以看到,这里的console 显示的内容是在程序里面显示而不是在浏览器中的控制台中,这里也说明node.js 可以相当于浏览器

这里访问js文件时不会运行里面的代码,而是直接输出了

如何在node.js中启动网站?如何让node.js运行在网站中?

先安装一个express库

先引入express 库 ,写一个端口监听的,然后启动这个js

在网页中访问这个js文件,网页中可以看到 并未执行上面的读取文件的操作,因为这里要加一个路由关系,比如:访问某个路径时执行这个函数

将要在访问某个地址时执行的代码放在函数里面,这样一访问地址时就会触发,从而执行里面的代码

这里刷新一次就会打印一次数据,但是这里还是将数据显示在js运行框里

如何让代码执行结果输出到浏览器中呢?

只需要加一句代码就可以将数据内容显示到浏览器上面去 ,输入 :res.send(data); 这个res是和上面那个有关的,所以当上面的名字改变时,那么下面的也要跟着改动

接收输入参数 req.query.x 将接收过来的值赋值给name ,res.send(name); 将那么值在浏览器中输出出来

其实req就是接收输入的内容,res就是 返回值

那么将文件名改成一个可控变量不就可以实现任意文本读取,这里用get请求方式

app.get('/file', function (req, res) {
    var name = req.query.file;
    // res.send(name);
 
    fs.readFile(name, 'utf-8', function (err, data) {
        if(err) throw err;
        console.log(data);
        res.send(data);
    });
})

这里在js文件上级创建了一个1.txt文件,将参数值file 加一个../ 跳到上一级,读取1.txt文件,执行成功

这里是读取不了php文件,但是可以读取js文件,应该是不支持读取其他类型文件

将文件读取改成目录读取,用post提交方式请求

app.post('/dir', function (req, res) {
    var name = req.query.dir;
    // res.send(name);
    fs.readdir(name, 'utf-8', function (err, data) {
        if(err) throw err;
        console.log(data);
        res.send(data);
    });
})

打开postman 选择post 提交方式, 将变量名和值输入到网址去,下面就会根据输入内容,将内容以post方式发送

这里就遍历 到了当前目录下的所有文件

遍历上级目录下的所有文件

这里右键源代码是查看不到任何代码的,只能看到执行结果,和之前原生开发时可以看到前端的js代码完全相反

那么可以看到用了node.js 后 ,它既有前端的效果,又有后端的隐蔽性,同时 还是一个运行JavaScript的环境,不用搭建apache,也可以运行到web应用中

-命令执行(RCE)

1、eval

2、exec & spawnSync

 先安装一个 child_process

执行命令测试: exec & spawnSync

const child_process = require('child_process');

child_process.exec('calc');

代码执行测试: eval

#NodeJS安全

1、SQL注入&文件操作

2、RCE执行&原型链污染

 RCE执行

构建网站:

const child_process = require('child_process');
var express =require('express');
var app = express();
// 命令执行
// child_process.exec('calc');
// child_process.spawnSync('calc');
// 代码执行
// eval('child_process.exec(\'calc\');');
 
app.get('/rce', function (req, res) {
    const cmd = req.query.cmd;   //定义一个变量接收参数值
    child_process.exec(cmd);
 
 
})
 
var server = app.listen(8032, function () {
    var host = server.address().address
    var port = server.address().port
    console.log("应用实例,访问地址为 http://%s:%s", host, port)
 
});

将cmd值输入 calc ,成功弹出计算器

原型链污染

原理:在一个应用中,如果攻击者控制并修改了一个对象的原型,那么将可以影响所有和这个对象来自同一个类、父祖类的对象。这种攻击方式就是原型链污染

当谈到继承时,JavaScript 只有一种结构:对象。每个实例对象(object)都有一个私有属性(称之为 proto )指向它的构造函数的原型对象(prototype)。该原型对象也有一个自己的原型对象(proto),层层向上直到一个对象的原型对象为 null。根据定义,null 没有原型,并作为这个原型链中的最后一个环节。

几乎所有 JavaScript 中的对象都是位于原型链顶端的 Object 的实例。

意思:原型链污染是只要污染了object对象中的proto 就相当于把所有的对象都污染了,因为object是所有对象的顶级父类;

举例:

在 JavaScript 中,当访问对象的某个属性(如 obj.prop)时,查找顺序是:

  1. 先在对象自身上查找该属性,如果存在则直接返回其值。
  2. 如果自身不存在,就沿着 __proto__ 指向的原型对象查找。
  3. 如果原型对象也没有,就继续沿着原型的 __proto__ 向上查找(即原型链),直到找到 Object.prototype。
  4. 若整个原型链都没有该属性,则返回 undefined。

这里foo 的第二次输出bar值时仍是1,因为查询规则 先查 foo 自身,发现有 bar: 1,直接返回;

foo.__proto__.bar = 2;   //foo.__proto__ 指向 Object.prototype(因为 foo 是普通对象,原型是 Object.prototype
这行代码实际是给 Object.prototype 添加了一个属性 bar,值为 2

新建的zoo 是一个空对象,自身没有 bar 属性

zoo 的 __proto__ 同样指向 Object.prototype(所有普通对象的原型都是 Object.prototype) 所以会输出2

// foo是一个简单的JavaScript对象
let foo = {bar: 1}
 
// foo.bar 此时为1
console.log(foo.bar)
 
// 修改foo的原型(即Object
foo.__proto__.bar = 2
 
// 由于查找顺序的原因,foo.bar仍然是1
console.log(foo.bar)
 
// 此时再用Object创建一个空的zoo对象
let zoo = {}
 
// 查看zoo.bar,此时bar为2
console.log(zoo.bar)

原型链污染配合RCE

有原型链污染的前提之下,我们可以控制基类的成员,赋值为一串恶意代码,从而造成代码注入。

运行代码之后会弹出计算器

let foo = {bar: 1}
 
console.log(foo.bar)
 
foo.__proto__.bar = 'require(\'child_process\').execSync(\'calc\');'
 
console.log(foo.bar)
 
let zoo = {}
 
console.log(eval(zoo.bar))

效果

2、NodeJS黑盒无代码分析

实战测试NodeJS安全:

判断:参考前期的信息收集

黑盒:通过对各种功能和参数进行payload测试

白盒:通过对代码中写法安全进行审计分析

-原型链污染

如果攻击者控制并修改了一个对象的原型,(proto)

那么将可以影响所有和这个对象来自同一个类、父祖类的对象。

http://www.dtcms.com/a/336581.html

相关文章:

  • 【LeetCode 热题 100】(八)二叉树
  • 如何使用java写一个agent
  • 说一下分离读写
  • c_str()函数的详细解析
  • 力扣438:找到字符串中所有的字母异位词
  • ACCESS/SQL SERVER保存软件版本号为整数类型,转成字符串
  • 第13章《远程处理:一对一及一对多》——PowerShell Remoting 学习笔记
  • Windows_Server软件定义网络架构
  • MXFP4量化:如何在80GB GPU上运行1200亿参数的GPT-OSS模型
  • 编程算法实例-阶乘
  • 天地图开发的优点
  • Steam 上传游戏包体操作步骤
  • Win11 文件资源管理器预览窗格显示 XAML 文件内容教程
  • K8S集群环境搭建(一)
  • STL 容器
  • 华东师范上海AiLab商汤!NaviMaster:学习适用于GUI和具身导航任务的统一策略
  • React学习(四)
  • 计算机视觉(一):nvidia与cuda介绍
  • 王树森深度强化学习DRL(一)RL基本概念+价值学习
  • 基于51单片机汽车自动照明灯超声波光敏远近光灯设计
  • Git安装使用
  • 【软考中级网络工程师】知识点之网络存储
  • 如何巧妙通过面试提高业务经验?
  • Spring IoC DI 终极指南:从造车模型到企业级开发实战
  • 嵌入式开发入门—电子元器件~半导体
  • Linux中iSCSI存储配置与管理指南
  • Java的网络攻防仿真演练系统
  • 深度学习·GFSS
  • C语言字符串操作汇总
  • 线程相关知识