Reflected XSS into HTML context with most tags and attributes blocked

3 months ago 70
BOOK THIS SPACE FOR AD
ARTICLE AD

Marduk I Am

Lab description: This lab contains a reflected XSS vulnerability in the search functionality but uses a web application firewall (WAF) to protect against common XSS vectors. To solve the lab, perform a cross-site scripting attack that bypasses the WAF and calls the ‘print()’ function.

Note: Your solution must not require any user interaction. Manually causing ‘print()’ to be called in your own browser will not solve the lab.Note: I am going to be using Burp Suite Community Edition to help solve this lab. Burp Suite is a software security application used for penetration testing of web applications. There are both free and a paid versions of the software available.

This looks like a fun one. We’re going to be bypassing our first web application firewall (WAF), using Portswigger’s exploit server to craft an <iframe> payload, and we are going to be using Burp Intruder for the first time. Lets go!

Access the lab. You will be brought to the simple blog page. This time the page has a search feature that is vulnerable. We just have to find out how.

From the description, we know that our blog page has improved its security features with the addition of a WAF. The WAF is going to filter, monitor, and block certain HTTP traffic to and from the web service. Traffic like cross-site scripting attacks.

Let’s try one out . Add the following <img> tag to the search bar and press ‘Search’:

<!-- Simple XSS payload that tries to load an image from a non-existent source producing a pop-up window -->
<img src='x' onerror='alert(1)'>

Take note of the exploit server we will be using later.

Screenshot of blog page with “<img src=’x’ onerror=’alert(1)’>” in the search bar. Also pointing out exploit server for future use.

Look what happens. We get a JSON response stating “Tag is not allowed”.

JSON response “Tag is not allowed”.

It is telling us our <img> tag is not allowed. However, it does not mean ALL tags are not allowed. Try searching for an empty set of angle brackets ‘<>’ to see what happens.

 “0 search results for ‘<>’”

They went through! To see if there are any other tags that go through, we can manually search for individual tags like <h1>, <p>, or <script>, but that is extremely time consuming.

This is where Burp Intruder comes in. Burp Intruder can cycle through all the HTML tags in a matter of seconds. A couple of minutes if you are using the Community Edition. The Community Edition automatically throttles your request speed. This precaution ensures responsible testing without overloading the target web server.

Open Burp and under the ‘Target’ tab, find our original search query in the left column containing our target tree.

You may need to add 400 responses to the filter in order to see our original search string. Check the box next to 4xx in the ‘Filter by status code’ box.

Settings window arrow pointing to box that needs to be checked.

Right click on the original search string and select ‘Send to Intruder’. The ‘Intruder’ tab should light up orange letting you know your request was successfully sent.

Click on the Intruder tab.

You’ll notice your original GET request at the bottom. The encoded search string is highlighted in yellow. Since we know our blog page will accept angle brackets ‘<>’, replace your encoded search string with ‘<>’.

With your cursor in the middle of the angle brackets, on the far right click ‘Add§’.

The top line of your GET request should look like:

<!-- The '§' acts as a placeholder for all the payloads Burp is going to cycle through -->
GET /?search=<§> HTTP/2

Now, for the payloads. Portswigger provides us with a XSS Cheat Sheet to help us with this step.

On the lab description page, click on the ‘Solutions’ tab and click on the provided link (#6 as of this publication).

On the XSS Cheat Sheet, click on ‘Copy tags to clipboard’. All of those tags are now saved.

Go back over to Burp Intruder and click the ‘Payloads’ tab.

In the ‘Payloads settings [Simple list]’ section click the ‘Paste’ button.

‘Payloads settings [Simple list]’ section with arrow pointing to the paste button.

If you had your own custom list you wanted to use, this is where you would add it.

From here, click back over to the ‘Positions’ tab.

Click the orange ‘Start Attack’ button (If you’re using the Community Edition, click ‘OK’ on the next pop-up window as well).

Screenshot of our attack with red rectangle highlighting our 200 responses.

When your attack is completed, click on ‘Status codes’ to sort by status codes. We are looking for the 200’s. These are tags that will go through. The 400’s obviously will not.

From the search results, we now know that if we search for ‘<body>’ on blog page it will go through. Let’s try it.

Search result for ‘<body>’ is 0 search results for ‘’
It went through!

The lab description states ‘Your solution must not require any user interaction’, so within the <body> tag we need an attribute like ‘onload’ that will not require user interaction.

If we try to search for the following what will happen?

<!-- When the body of the page loads, a pop-up alert window with a message of '1' will appear -->
<body onload='alert(1)'>

We get a JSON response again.

JSON response of “Attribute is not allowed”

Familiar message, however, notice how it says ‘Attribute’ instead of ‘Tag’ is not allowed. Of course it wouldn’t be that easy.

Since ‘onload’ is not allowed, we need to repeat our actions in Burp Intruder to find out what attributes, or events, will actually go through.

On the Burp ‘Intruder’ tab, add ‘body’ and the encoded version of the space character, ‘%20’, to your GET request. Also, instead of ‘alert(1)’ we need another arbitrary value. We will just use ‘=1’. It should look like the following:

<!-- Mistakenly I tried this without the '=1' and I got the same results -->
GET /?search=<body%20§=1> HTTP/2

Now head back to the XSS Cheat Sheet. This time we need to copy all of the events to our clipboard. Click ‘Copy events to clipboard’.

Back to Burp again and click on the ‘Payloads’ tab. This time we need to clear out our first list with the ‘Clear’ button. Then click ‘Paste’ to add all of our copied events.

Click ‘Clear’, then ‘Paste’.

Click back on the ‘Positions’ tab then the orange ‘Start Attack’ button.

When the attack is complete, sort by the ‘Status codes’ again to see the 200's.

Burp Intruder results highlighting the 200 responses.
We’re going to test ‘onresize’.

All of our 200 responses require some form of user interaction in order to trigger our ‘alert()’ function.

For demonstration purposes, we can test if we can get one of the 200 responses from Burp to go through by adding the following to the search bar on our blog page and pressing ‘Search’.

<body onresize='alert(1)'>
Search results for “<body onresize=’alert(1)’>” is “0 search results for ‘’”

It went through! But no pop-up window.

Minimize your browser window.

There it is!

There’s our pop-up window. This does not solve the lab though. In order to do that we need to call the ‘print()’ function and we need to have it in an <iframe>.

An <iframe> (inline frame) is an HTML element used to embed another document or webpage within the current HTML document. It allows you to display content from one source (e.g., a web page or media file) within a designated area of another HTML document.

Think of an <iframe> like a ‘picture in picture’ TV.

Solution:

Click on the ‘Solution’ tab on the lab description page. Scroll down to find the <iframe> needed for the next step.

<!-- Replace 'YOUR-LAB-ID' with the lab ID from your URL -->
<iframe src="https://YOUR-LAB-ID.web-security-academy.net/?search=%22%3E%3Cbody%20onresize=print()%3E" onload=this.style.width='100px'>
<!-- Should look like: -->
<iframe src="https://0a8c00b1033c44b280a517eb000a0051.web-security-academy.net/?search=%22%3E%3Cbody%20onresize=print()%3E" onload=this.style.width='100px'>

Once the <iframe> is copied, click on ‘Go to exploit server’. Scroll down and paste the <iframe> in the ‘Body’ section.

Screenshot of exploit server with <iframe> payload pasted in the Body
Note: Don’t forget to change ‘YOUR-LAB-ID’.

Notice our search query in the <iframe>.

<!-- Original -->
?search=%22%3E%3Cbody%20onresize=print()%3E" onload=this.style.width='100px'
<!-- Unencoded -->
?search="><body onresize=print()> onload=this.style.width='100px'

Our search query also has the ‘onload’ event contained in it, so it will automatically resize the user’s window and trigger the ‘print()’ function.

We tried the ‘onload’ event contained in a <body> tag earlier, but that did not work. However, being ‘smuggled’ in an <iframe>, it will work.

Click on ‘View exploit’ to see our payload in action.

It worked!

Click ‘Cancel’ then your back button to return to exploit server page.

From here just ‘Store’ the exploit then click ‘Deliver exploit to victim’ to solve the lab.

Congratulations! Another one down! Keep up the good work!

Read Entire Article