Nog een manier om functies aan te roepen zonder haakjes

Deze payload werkt door de prepareStackTrace-functie van het Error-object te overschrijven om willekeurige functies te genereren. Deze functie wordt gewoonlijk gebruikt om stack traces te formatteren en wordt aangeroepen wanneer het stack-attribuut van een fout wordt geraadpleegd.

De parameters van deze functie zijn de fout en "een gestructureerde weergave van de stack", wat simpelweg een array van codeposities is. Deze functie heeft dezelfde functiesignatuur als de Function-constructor, die wordt gebruikt om JavaScript-functies te genereren, mits het tweede argument geldige JavaScript-code is.

Als we proberen de functie aan te roepen die met deze methode is gegenereerd, krijgen we een syntaxisatiefout. Dit is te verwachten, aangezien een stack trace geen geldige JavaScript-code is, maar een array van codeposities.

Om de payload te laten werken, moeten we de output van de Array.prototype.toString()-functie zodanig beheersen dat deze onze gewenste JavaScript-payload teruggeeft. Dit kan op twee manieren:

  • Ten eerste kunnen we deze simpelweg overschrijven met een constante functie die de payload teruggeeft.
  • Of we kunnen prototype pollution gebruiken om onze payload in een andere functie te smokkelen en vervolgens het Array-prototype te overschrijven. Ik ontdekte dat we in het Error-domein kunnen blijven en de toString-functie daarvan kunnen gebruiken, die gemanipuleerd kan worden door de Object.prototype.message-variabele te vervuilen. Ik ben er zeker van dat er meer manieren zijn om dit te bereiken.

Wanneer we nu alles combineren — de functiegeneratie via de prepareStackTrace-functie en de manier om arrays om te zetten in willekeurige strings — kunnen we willekeurige JavaScript-functies genereren.

Het laatste wat we moeten doen is onze nieuwe functie aanroepen. Gelukkig zijn daar veel manieren voor; ik heb gekozen voor de valueOf-truc. Dit werkt door de standaard valueOf-functie van ons object te overschrijven en deze vervolgens als een primitieve waarde aan te roepen. Als alternatief kunnen we toString gebruiken en het object vervolgens aan een string koppelen (concatenatie).

De uiteindelijke payload is als volgt. Voel je vrij om dit uit te proberen in de browserconsole:

Object.prototype.message='alert\x281337\x29';Array.prototype.toString=Error.prototype.toString;Error.prepareStackTrace = Function;const x = new Error;x.valueOf=x.stack;+x;