日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢(xún)
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
JavaScript原型鏈污染

前言

在瀏覽某個(gè)論壇的時(shí)候,第一次看到了JavaScript原型鏈污染漏洞。當(dāng)時(shí)非常的好奇,當(dāng)時(shí)我一直以為js作為一種前端語(yǔ)言,就算存在漏洞也是針對(duì)前端,不會(huì)危害到后端,因此我以為這種漏洞危害應(yīng)該不大。可當(dāng)我看到他的漏洞危害還有可以執(zhí)行任意命令的時(shí)候,發(fā)現(xiàn)可能我想到有點(diǎn)簡(jiǎn)單了。js也是可以用來(lái)做后端語(yǔ)言的。這篇文章就來(lái)認(rèn)識(shí)一下這個(gè)漏洞。

創(chuàng)新互聯(lián)公司專(zhuān)注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于做網(wǎng)站、網(wǎng)站建設(shè)、柞水網(wǎng)絡(luò)推廣、微信小程序開(kāi)發(fā)、柞水網(wǎng)絡(luò)營(yíng)銷(xiāo)、柞水企業(yè)策劃、柞水品牌公關(guān)、搜索引擎seo、人物專(zhuān)訪、企業(yè)宣傳片、企業(yè)代運(yùn)營(yíng)等,從售前售中售后,我們都將竭誠(chéng)為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);創(chuàng)新互聯(lián)公司為所有大學(xué)生創(chuàng)業(yè)者提供柞水建站搭建服務(wù),24小時(shí)服務(wù)熱線:028-86922220,官方網(wǎng)址:www.cdcxhl.com

JavaScript原型鏈?zhǔn)鞘裁矗?/h2>

既然漏洞名稱(chēng)是JavaScript原型鏈污染,那么首先就要先明白JavaScript原型鏈?zhǔn)鞘裁础?/p>

正如我們所知,Javascrip的復(fù)雜類(lèi)型都是對(duì)象類(lèi)型(Object),而js不是一門(mén)完全面對(duì)對(duì)象編程的語(yǔ)言。那么對(duì)于對(duì)象編程來(lái)說(shuō)要考慮對(duì)象的繼承。

js實(shí)現(xiàn)繼承的核心就是原型鏈。我理解的就是原型鏈的存在就是js中的繼承機(jī)制,保證函數(shù)或?qū)ο笾械姆椒ǎ瑢傩钥梢韵蛳聜鬟f。

js使用了構(gòu)造函數(shù)來(lái)創(chuàng)建對(duì)象,如下,我們可以通過(guò)構(gòu)造函數(shù)來(lái)定義一個(gè)類(lèi):

// 構(gòu)造函數(shù)
function Person(name, age) {
    this.name = name;
    this.age = age;
}

// 生成實(shí)例
const p = new Person('zhangsan', 18);

1692167778_64dc6e62b659f0a4498b9.png!small?1692167779350

可以看到這個(gè)類(lèi)除了我們定義的兩個(gè)屬性以外,還有一個(gè)prototype的屬性。prototype指向函數(shù)的原型對(duì)象,這是一個(gè)顯式原型屬性,只有函數(shù)才擁有該屬性。

prototype也擁有兩個(gè)屬性:

constructor:指向原型的構(gòu)造函數(shù)

prototype:指向了Object的原型

在prototype的屬性中有一個(gè)_proto_,那么這個(gè)_proto_與prototype又有什么關(guān)系?

1692167810_64dc6e826449231561148.png!small?1692167811088

原型prototype是類(lèi)的一個(gè)屬性,而所有用類(lèi)實(shí)例化的對(duì)象,都將擁有這個(gè)屬性中的所有內(nèi)容,包括變量和方法。比如上圖中的p對(duì)象,其天生就具有類(lèi)Person的屬性和方法。

我們可以通過(guò)Person.prototype來(lái)訪問(wèn)Person類(lèi)的原型,但Person實(shí)例化出來(lái)的對(duì)象,是不能通過(guò)prototype訪問(wèn)原型的。這時(shí)候,就該__proto__登場(chǎng)了。

也就是類(lèi)可以用prototype來(lái)訪問(wèn)類(lèi)的原型,而實(shí)例化的對(duì)象可以用_proto_來(lái)訪問(wèn)對(duì)象所在類(lèi)的prototype屬性。

總結(jié):

其實(shí)我們只要明白一點(diǎn)就可以了,JavaScript原型鏈?zhǔn)莏s中實(shí)現(xiàn)繼承的核心,js的對(duì)象都會(huì)執(zhí)行其它的原型,最后指向的原型為null。最后關(guān)于原型鏈再來(lái)總結(jié)一下

1)js是通過(guò)原型鏈來(lái)實(shí)現(xiàn)繼承的。

2)所有類(lèi)對(duì)象在實(shí)例化的時(shí)候?qū)?huì)擁有prototype中的屬性和方法

3)類(lèi)可以使用prototype來(lái)訪問(wèn)類(lèi)的原型對(duì)象,而實(shí)例化對(duì)象可以通過(guò)_proto_來(lái)訪問(wèn)類(lèi)的原型對(duì)象

let f = new Foo();
f.constructor === Foo;
f._proto_ === Foo.prototype
f._proto_ === Foo.prototype
Foo._proto_ === Function.prototype

原型鏈污染

在了解了原型鏈的相關(guān)知識(shí)以后,可以來(lái)看看竟然什么是原型鏈污染漏洞。

上面說(shuō)過(guò)實(shí)例化對(duì)象的__proto__指向了類(lèi)的prototype。那么,如果我們修改了實(shí)例化對(duì)象__proto__中的值,是不是就可以修改類(lèi)中的值呢?是否可以影響所有和這個(gè)對(duì)象來(lái)自同一個(gè)類(lèi)、父祖類(lèi)的對(duì)象?

其實(shí)這就是原型鏈污染的原理。我們通過(guò)修改實(shí)例化對(duì)象的__proto__中的值,污染了類(lèi)本體,進(jìn)而影響所有和這個(gè)對(duì)象來(lái)自同一個(gè)類(lèi)、父祖類(lèi)的對(duì)象。

p神的博客上有一個(gè)這樣的例子,用來(lái)說(shuō)明原型鏈污染:

1692167987_64dc6f332874455dd5d81.png!small?1692167987836

實(shí)際情況下利用分析

在實(shí)際的情況中,我們可能只能控制部分參數(shù),那么我們?cè)趺床拍転開(kāi)_proto__賦值呢?

要為_(kāi)_proto__賦值就要求__proto__作為變量傳進(jìn)去并且作為鍵名,這種情況一般出現(xiàn)在下面的三種場(chǎng)景中:

  • 對(duì)象merge
  • 對(duì)象clone(其實(shí)內(nèi)核就是將待操作的對(duì)象merge到一個(gè)空對(duì)象中)
  • 路徑查找屬性然后修改屬性的時(shí)候

下面借用p神文章中的一個(gè)例子來(lái)看看具體操作,原文鏈接為:https://www.leavesongs.com/PENETRATION/javascript-prototype-pollution-attack.html

以對(duì)象merge為例,我們想象一個(gè)簡(jiǎn)單的merge函數(shù):

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]
        }
    }
}

在合并的過(guò)程中,存在賦值的操作target[key] = source[key],那么,這個(gè)key如果是__proto__,是不是就可以原型鏈污染呢?

let o1 = {}
let o2 = {a: 1, "__proto__": {b: 2}}
merge(o1, o2)
console.log(o1.a, o1.b)

o3 = {}
console.log(o3.b)

結(jié)果是,合并雖然成功了,但原型鏈沒(méi)有被污染:

1692168050_64dc6f7280e79c362a397.png!small?1692168051194

這是因?yàn)?,我們用JavaScript創(chuàng)建o2的過(guò)程(let o2 = {a: 1, "__proto__": {b: 2}})中,__proto__已經(jīng)代表o2的原型了,此時(shí)遍歷o2的所有鍵名,你拿到的是[a, b],__proto__并不是一個(gè)key,自然也不會(huì)修改Object的原型。從下面的圖中也可以看出,在o1中,參數(shù)b并沒(méi)有出現(xiàn)在原型中。

1692168062_64dc6f7e3ea57daf7bf33.png!small?1692168062943

那么,如何讓__proto__被認(rèn)為是一個(gè)鍵名呢?

我們將代碼改成如下:

let o1 = {}
let o2 = JSON.parse('{"a": 1, "__proto__": {"b": 2}}')
merge(o1, o2)
console.log(o1.a, o1.b)

o3 = {}
console.log(o3.b)

可見(jiàn),新建的o3對(duì)象,也存在b屬性,說(shuō)明Object已經(jīng)被污染

1692168090_64dc6f9ae493107bec1d4.png!small?1692168091483

這是因?yàn)?,JSON解析的情況下,__proto__會(huì)被認(rèn)為是一個(gè)真正的“鍵名”,而不代表“原型”,所以在遍歷o2的時(shí)候會(huì)存在這個(gè)鍵。

再來(lái)看看o1發(fā)現(xiàn),b屬性是定義在原型之中的。

1692168096_64dc6fa0980dab3967fd7.png!small?1692168097212

merge操作是最常見(jiàn)可能控制鍵名的操作,也最能被原型鏈攻擊,很多常見(jiàn)的庫(kù)都存在這個(gè)問(wèn)題。

js原型鏈污染漏洞分析

接下來(lái)用一個(gè)cve漏洞來(lái)具體再看一下這個(gè)漏洞。

3.4.0版本之前的jQuery存在一個(gè)原型污染漏洞CVE-2019-11358,PoC如下。

//代碼如下,如果從前端接收一個(gè)json內(nèi)容,傳到后端。
//json內(nèi)容:JSON.parse('{"__proto__": {"z": 123}}')

const json1 = ajax();  
jQuery.extend(true, {}, JSON.parse(json1));
console.log( "test" in {} ); // true

jQuery.extend () 函數(shù)用于將一個(gè)或多個(gè)對(duì)象的內(nèi)容合并到目標(biāo)對(duì)象

$.extend( [deep ], target, object1 [, objectN ] )

參數(shù)

描述

deep

可選。 Boolean類(lèi)型 指示是否深度合并對(duì)象,默認(rèn)為false。如果該值為true,且多個(gè)對(duì)象的某個(gè)同名屬性也都是對(duì)象,則該"屬性對(duì)象"的屬性也將進(jìn)行合并。

target

Object類(lèi)型 目標(biāo)對(duì)象,其他對(duì)象的成員屬性將被附加到該對(duì)象上。

object1

可選。 Object類(lèi)型 第一個(gè)被合并的對(duì)象。

objectN

可選。 Object類(lèi)型 第N個(gè)被合并的對(duì)象。

再來(lái)看看實(shí)際的代碼是如何去寫(xiě)入的。

首先下載jQuery,這里下載的是3.3.0版本

https://github.com/jquery/jquery/tree/3.3.0

在src/core.js中文件中可以找到該extend函數(shù)??催^(guò)源碼,可以發(fā)現(xiàn)該函數(shù)的正好符合上面說(shuō)的合并數(shù)據(jù)的概念,那么來(lái)看看它到底會(huì)不會(huì)被污染?

1692168161_64dc6fe1e3ff617f47974.png!small?1692168162655

我們來(lái)動(dòng)態(tài)調(diào)試一下這個(gè)程序:

引入jQuery腳本,并設(shè)置斷點(diǎn),進(jìn)行調(diào)試

1692168167_64dc6fe7b978b4973c2cd.png!small?1692168168393

首先根據(jù)第一個(gè)參數(shù)判斷是否進(jìn)行深度拷貝,然后進(jìn)行第一次循環(huán),取得參數(shù)為_(kāi)_proto__

1692168172_64dc6fecc462985824a7e.png!small?1692168173522

第二次循環(huán),在__proto__中去參數(shù)進(jìn)行賦值

1692168177_64dc6ff18c0335618e4f2.png!small?1692168178185

此時(shí)再看原型已經(jīng)被污染了

1692168182_64dc6ff620c4ded5d0a06.png!small?1692168182716

總結(jié)

js原型鏈污染可以說(shuō)原理并不是太難懂,關(guān)鍵是實(shí)際中如何去利用。關(guān)于這個(gè)漏洞也是看了很多大神的文章,它們的思路真的太厲害了,我還有很多需要學(xué)習(xí)的,跟大家一起共勉。

由于本人水平有限,文章中可能會(huì)出現(xiàn)一些錯(cuò)誤,歡迎各位大佬指正,感激不盡。如果有什么好的想法也歡迎交流,謝謝大家了~~

參考鏈接

https://www.freebuf.com/articles/web/275619.html

https://www.leavesongs.com/PENETRATION/javascript-prototype-pollution-attack.html

https://xz.aliyun.com/t/7025

https://www.freebuf.com/articles/web/264966.html

本文作者:, 轉(zhuǎn)載請(qǐng)注明來(lái)自FreeBuf.COM


新聞標(biāo)題:JavaScript原型鏈污染
文章轉(zhuǎn)載:http://m.5511xx.com/article/cocpjeo.html