
I believed I knew all of the methods to name capabilities with out parentheses:
alert`1337`
throw onerror=alert,1337
Operate`x$'alertx281337x29'x```
'alertx281337x29'instanceof[Symbol['hasInstance']]:eval
valueOf=alert;window+''
x=new DOMMatrix;matrix=alert;x.a=1337;location='javascript'+':'+x
// or any DOMXSS sink reminiscent of location=title
On this publish I am going to present you one more stunning manner and provide help to perceive how tagged template strings work. The methods on this publish do not immediately allow exploitation, however they can be utilized to realize a higher understanding of the JavaScript language, offering a basis for evasion of JavaScript sandboxes and WAFs. It began with my publish on Executing non-alphanumeric JavaScript without parentheses. I discovered that you would move strings to tagged templates, tagged templates simply means utilizing a operate prefixed earlier than the template string literal. For instance alert`123`
is a tagged template that calls the alert
operate with 123. My realisation within the earlier publish was you would move a number of arguments to these capabilities with simply strings as the next code demonstrates:
operate x()
alert(arguments[0]);
alert(arguments[1]);
x`x$'ale'+'rt(1)'x`
What occurs right here is all of the strings get added as an array within the first argument and the second argument will get the string alert(1)
however wait why does the string alert(1)
get handed as a second argument to the operate? Nicely, strings are handled in a different way than placeholders, a standard string with out placeholders will get added to the primary argument as an array whereas placeholders will get added as a brand new argument with their kind. This final level is essential, what I did not realise on the time was that placeholders get added as an argument with their kind not as a string! The next code demonstrates this:
operate x()
alert(arguments[0]);
arguments[1]('howdy')
operate y(str)
alert(str);
x`x$yx`
Nice that is cool behaviour, it means we will name capabilities and move a number of arguments with any kind. However we’ve got an issue, when utilizing strings in a tagged template they may at all times be added as the primary argument, thus breaking capabilities that use the primary argument. Our objective right here is to name the operate with an argument we select. As an example we’d need to name setTimeout
as a result of the primary argument accepts a operate or a string and the third argument calls that operate with that worth:
setTimeout(alert, 0, 'I get handed to alert')
Let’s attempt calling setTimeout
:
setTimeout`$alert$0$1`//Uncaught SyntaxError: Sudden token ','
We are able to see what is going on by utilizing a customized operate once more:
operate x()
console.log(arguments);
x`$alert$0$1`
So we will see the primary argument comprises an array of clean strings and one other array on the finish once more filled with clean strings. When setTimeout
converts these arrays right into a string we get a bunch of commas which causes a syntax error. Someway we want the setTimeout
operate to disregard the primary argument, how do you do this? Nicely, you need to use setTimeout.name
as a result of the primary argument would be the array which will get assigned to “this” of the setTimeout
operate and now alert will get handed as the primary argument to the operate however…
setTimeout.name`$alert$0$1`//Unlawful invocation
Rattling since you are now not calling the operate immediately, JavaScript will throw an exception stopping you from calling the operate as a result of “this” is now not a window object. I believed recreation over, then I realised again previously I’ve completed some JS hacking with [].type
and others. They permit you to name capabilities with out the unlawful invocation error:
[].type.name`$alert1337`
You possibly can in fact use different capabilities reminiscent of eval
and different array strategies like map
:
[].map.name`$evalu61lertx281337x29`
I later found that you need to use Replicate
too:
The above makes use of the brand new navigation.navigate
technique in Chrome to trigger a redirection with the payload coming from window.title
. As a way to name navigate
it’s good to present the proper “thisObject” to the operate, that is completed within the second argument to Replicate.apply
. The window.title
is used within the third argument which needs to be an array of arguments despatched to the operate. Utilizing Replicate
strategies set and apply you may assign to just about any object or name any operate!
Conclusion
It is fairly stunning that template strings help this behaviour and browsers permit you to use type and different capabilities on this manner. By hacking JavaScript you may study new and fascinating methods of abusing JavaScript options to provide sudden outcomes.
I hope and sit up for seeing somebody discovering the eighth manner of executing JavaScript with out parentheses!