This lab uses AngularJS in an unusual way where the $eval
function is not available and you will be unable to use any strings in AngularJS.
To solve the lab, perform a attack that escapes the sandbox and executes the alert
function without using the $eval
function.
After accessing the lab, I intercepted the search request, which had an interesting response:
The response contained this script:
I noticed that my input data is being passed as a value to the $scope.query[key]
variable, but the interesting part is this line:
It parses the key
, which in this case is the search parameter, and then evaluates it with $scope.query
. Since this part is parsed, it is where the injection should occur. To confirm this, I added a new parameter to create a new key and tried injecting an AngularJS expression to see if it gets parsed properly:
I added a new parameter called ichyaboy
with the value 6
. Checking the response:
A new key is added. Now, I will inject an Angular expression instead of the ichyaboy
key:
The payload was simply 3+3
, but I had to URL-encode the +
character. Checking the response, I see that it prints the result:
Note: I didn't use {{}}
in the payload to declare an expression because the parse
function treats its argument as an expression, so I typed my payload directly.
The injection of the Angular expression is confirmed, but the main goal is to run JavaScript code that triggers an alert. Simple Angular expressions can't do that due to the AngularJS sandbox. First, I need to escape this sandbox, then go for the XSS.
This payload contains 2 parts:
toString().constructor.prototype.charAt=[].join;
: This part escapes the sandbox by overwriting the charAt
function, which normally parses a single character and passes it to the isIdent
function. By overwriting charAt
, it passes multiple characters instead, causing the isIdent
function to always return true
.
[1,2]|orderBy:toString().constructor.fromCharCode(120,61,97,108,101,114,116,40,49,41)
: This part filters the array [1,2]
using the |
character and the orderBy
function. It constructs the string x=alert(1)
using fromCharCode
to bypass string restrictions. When executed, it looks like:
These steps are necessary to bypass the sandbox filters.
Now, I need to inject this payload into a new parameter to create a new key that will be parsed and executed, resulting in an XSS:
After sending this request, I saw that the lab was solved.
Consulting the XSS from PortSwigger, under "AngularJS sandbox escapes reflected," I found a payload to bypass the sandbox without using strings: