XSS can be conducted without a user input box. If the page has a Javascript function and a variable such as “username=”” ” then it may be susceptible to XSS if the argument passed into username=”” is not sanitized.
On Mutillidae, at the Password Generator page, there are no input fields, just a button that generates a password for the user “anonymous”. At the top, in the URL we can see that at the end is user=anonymous. If we change the name from anonymous to “joe” we can see that the webpage updates. So while the page doesn’t have an inputs, the URL does which means this may be susceptible to a reflective XSS attack.
First, let’s capture a request via Burp Suite. Clicking “Generate Password” won’t actually send a request as this is a DOM object, so just refreshing the page will capture the request. Sending that to the repeater is next so we don’t have to keep refreshing the page and then turn off the interceptor.
Sending the request via repeater gives back an OK response from the webpage. To see where “joe” is we simply just type “joe” in the search box at the bottom and it shows where joe is located in the response.
As you can see, there is no sanitization.
So the idea is to inject javascript in place of ‘joe” so that it executes. First is to close out the double quote “This password is for joe”, so instead it’s
"This password is for"our malicious input will go here";
Next is to close off the bracket in the ‘try/catch’ statement. Javascript statements end with a semi colon so it’s good practice to end the double quote. Finally, if we close that statement it means we will have an open ‘try’ statement without the necessary ‘catch’ statement, so we have to close that too. So far the request looks like this with our input highlighted in red:
= "This password is for ";}catch(e){};
Next is put in the payload
alert('HACKED')
Script tags aren’t necessary since the entire statement is in a script tag.
The statement looks like this now. Our input is in red.
= "This password is for ";}catch(e){};alert('HACKED')"; }catch(e){
Next is to close out payload with a semi colon and then close out the code after the payload which is the ‘catch’ statement, which is
"; }catch(e){
To close this off, we start by putting in another try statement (since we closed the first one) and then put something simple like
A="
It’s a single double quote because the rest of the statement starts with a double quote, effectively making the variable A=””.
The statement & payload look like this now
= "This password is for ";}catch(e){};alert('HACKED');try{A="";}catch(e){
Sending it to the site and searching for ‘hacked’ shows what the statement looks like.
This seems to be a valid statement so next is to encode the URL. Going to the ‘Encoder’ section in Burp, we can input our payload and it will convert it to URL encoded if you select it on the drop down menu on the side.
Copying and pasting that URL encoded string after “username” in the URL shows we’ve successfully reflective XSS’d in a DOM page.