Bugcrowd & Vullnerability XSS Challenge 2020

4 years ago 169
BOOK THIS SPACE FOR AD
ARTICLE AD

OfficialBenko

Greetings!
This is my very first write-up. I have been working in this field since April 2020 (about 4 months) and I am fascinated by what this area has to offer.

If you would like to get in touch with me, I would be happy to receive a message on Twitter from you. Also if you enjoyed the write-up, please follow me on Twitter. Thanks a lot and enjoy reading :)

My Twitter: https://twitter.com/BenkoOfficial

This write-up will present the solutions to the five different XSS vulnerabilities in this challenge.

Please follow the creators on Twitter, who have put so much effort into this challenge :)

https://twitter.com/VULLNERAB1337?s=20 (VULLNERABILITY)https://twitter.com/Bugcrowd?s=20 (Bugcrowd)

Let’s get right into it!

This is the first XSS vulnerability I have found. In my opinion, it is also the most obvious and easiest one of all.

After you have successfully registered and then logged in, you will land on the profile page. While browsing the profile page I noticed the parameter “link” in the URL.

Image for post

Image for post

Since the given value of the parameter starts with “user_”, I immediately assumed that the parameter contains a UserID. So I thought that if I want to view another profile, I have to change the user ID. And this appeared:

Image for post

Image for post

As you can see the wrong UserID is reflected in the error message.

So I created a simple payload and appended it to the UserID to see if the input is sanitiesed.

Image for post

Image for post

The payload must be appended to the UserID. The UserID itself should not be removed. A check has been implemented in the Javascript for this as you can see above.

Image for post

Image for post

Image for post

Image for post

BOOM. The input was not sanitized! But why didn’t the XSS Payload trigger an alert?

Image for post

Image for post

This happened because of the Content Security Policy (CSP), which is used to prevent cross-site scripting and other attacks by smuggling data into websites. The CSP is reported to the browser via a response header.

Image for post

Image for post

In this case the CSP has the format: script-src ‘nonce-<base64-value>’. This means that script elements are only allowed if the attribute ‘nonce’ is specified together with its value.

For this I used the <iframe> tag along with the “srcdoc” attribute to create a custom HTML website and insert it into the source code.

Image for post

Image for post

Image for post

Image for post

Iframe successfully added to the DOM.

Now only the Javascript has to be added together with the CSP bypass.

Image for post

Image for post

Image for post

Image for post

Wow! The first XSS vulnerability has just been successfully identified!

As the name suggests, I was able to find the second XSS vulnerability in the “Forgot Password” function. This time it is a bit more challenging than the previous one.

Image for post

Image for post

Image for post

Image for post

You are asked to enter an email. So I entered a random, valid email and was redirected to another page. The following appeared:

Image for post

Image for post

Image for post

Image for post

The entered email was reflected in the URL and on the website! As soon as you change the email in the URL, it was reflected on the site!

So once again I added a simple XSS payload to the email. But now an error message appeared.

Image for post

Image for post

Obviously an email validation has been implemented. Probably using the standard syntax. So I used a search engine to find out more about email validation and its criteria. This is what I learned:

space and special characters "(),:;<>@[\] are allowed with restrictions (they are only allowed inside a quoted string, […]) [https://en.wikipedia.org/wiki/Email_address#Syntax]no spaces are allowed (instead use “/”)

Based on this information I adjusted the payload accordingly and attempted it again.

Image for post

Image for post

Image for post

Image for post

Awesome! The payload did work and the alert has been successfully triggered. The second XSS vulnerability has just been successfully identified!

Github. Some people love it, some hate it and others use it for their XSS. And that is exactly what we are doing now. The 3rd XSS vulnerability has a unique concept and requires more creative approaches. Let’s get started!

After successful login you will be forwarded to the “Devplanet Apply Form”.

Image for post

Image for post

There you enter sample data and send it. Then click on “My Profile”.

Image for post

Image for post

The sample data is reflected on the profile page! You should immediately be aware that this could be a possible entry point for an XSS.

If you take a look at the source code, you will notice the following part.

Image for post

Image for post

The profileLoad function is called in the api.js with two different parameters. The first thing we are interested in is how the values given before are reflected on the page. Therefore we look for the corresponding part in the api.js.

Image for post

Image for post

As you can see all these values are set with the .text() function. But what does this mean for us? Here is a short explanation:

“The text() method sets or returns the text content of the selected elements. When this method is used to return content, it returns the text content of all matched elements (HTML markup will be removed).“ [https://www.w3schools.com/jquery/html_text.asp]

Since the HTML markup is removed, there is no way for us to use this input for an XSS. But haven’t I seen a particularly interesting sentence on the Apply Form page?

“We love to see live examples. Especially GitHub.”

This is it! Let’s take a closer look at how the given github profile is reflected on the page.

Image for post

Image for post

Javascript

Image for post

Image for post

HTML

We can see that the website is loading additional information from the linked github page. The attribute “title” seems to be the only entry point for our XSS in this case.

Image for post

Image for post

Sourcecode on github.com/nahamsec

As you can see, the title of the github page is reflected exactly! So what if I create my own HTML document on Github with a Javascript payload as title? The payload already contained the content security bypass using the ‘nonce’ attribute in the script element.

Image for post

Image for post

With a little “trick” the raw files on Github can be accessed via “github.com” instead of “raw.githubusercontent.com”. We will use this trick here, because we can only manipulate the part after “github.com” in our profile page.

Image for post

Image for post

I updated my profile and this happened….

Image for post

Image for post

Wow! The alert was successfully triggered when I accessed the profile page. The third XSS vulnerability has just been successfully identified!

Oh, my goodness! This was quite difficult. As it turned out, however, it was only the preparation for the final XSS…

Before we start, I have a question for you. When you see a picture of the profile page in a moment. Behind which functionality do you expect no XSS?

Image for post

Image for post

extract from the profile page

Of course a “Logout” function has no XSS. Am I right? NOPE.

As soon as I logged out, I noticed that you are redirected to the homepage via an additional separate page. That’s what it looks like:

Image for post

Image for post

Image for post

Image for post

Not really interesting. So let’s have a look at the source code.

Image for post

Image for post

Oh, that’s new!

What is the purpose of the javascript?

It searches for the parameter “next” in the search bar and stores its value in the variable “get_parameter_next”.The value of the parameter “next” is checked whether it matches a certain pattern (Regex).If it fits, the user is redirected to the page specified in the parameter.

Important! The redirect is done by assigning the value to “window.location.href”. This can be exploited to execute Javascript code.

The default approach for this is: javascript:alert(document.domain);

But this will not work because it does not match the given pattern. A detailed explanation of the pattern would be very extensive. That’s why I try to keep it simple.

The simplified regex: (n)://(x).(x)

(n) = Any letters, numbers and the underscore(x) = Any numbers, letters, signsEverything not in brackets must be present exactly in that order. Everything in brackets does not necessarily have to be present.

If you would like to know more about the pattern you can look at the following resource: https://regexr.com/59po0

Precisely because we want to execute Javascript, we are dependent on “javascript:”. If we also want to match the pattern, we have to start our payload with “javascript://”. Probably you will now think about the following payload:

javascript://alert(document.domain);

Sorry to disappoint you. The payload won’t work. Why not? In Javascript, “//” represents a single line comment and therefore ensures that any subsequent code is ignored by the browser.

In fact, I have never encountered such a problem before and it took me quite a while to find useful information. But then I came across this:

“For a single-line comment, you have to write two forward slashes: // . Anything that goes after // up until a line break is treated as a JavaScript comment and not executed as code.” [https://www.bitdegree.org/learn/javascript-comment]

“This gotta be it. It’s the only way.” — My first thought when I saw this.

A line break can be achieved with “%0a%0d”. So I adjusted the payload and tested it.

Image for post

Image for post

The result: I was forwarded to the homepage.

It took me a long time to realize that the parameter will probably still be decoded. So I tried again. This time with “%250a%250d”.

Image for post

Image for post

Image for post

Image for post

Finally! The fourth XSS vulnerability has just been successfully identified!

Welcome to hell. In my opinion, this was by far the most severe XSS vulnerability. You will soon know why :) Let’s get straight into it!

It is often worthwhile to have a look at the “Robots.txt” of the website. It can be used to determine which areas of a domain may be crawled by a web crawler and which may not. This is useful, as other end points can be listed there, thus extending the scope of the attack. You can often find them at: https://[URL]/robots.txt

Image for post

Image for post

The check seems to have been worth it. We just discovered the URL path to a devloper login. Let’s have a look at it.

Image for post

Image for post

To save you time I have already looked through the sourcecode for you. Except for a clearly outdated jQuery version I haven’t found anything interesting.

Also on the “Forgot Password” page I could not find anything else.

Image for post

Image for post

I ended up trying to use the IDs of the login form elements as parameters and possibly achieve an HTML injection.

Image for post

Image for post

Image for post

Image for post

Image for post

Image for post

And look, it worked! It was now possible to inject any HTML into the source code. Next, I looked to see if a CSP was being used.

Image for post

Image for post

And indeed they did. This CSP means that the specified source in script elements must have the same URL Scheme and Port Number as the page.

The appropriate payload was provided to me at the end of the challenge for this write-up. For the payload the API of the website is used, which provides the user data of the website. Due to the complexity of this payload I would refrain from a more detailed description of the functionality of this payload in this write-up. In this case, I would ask you to examine the payload yourself and, if necessary, to do some research.

Image for post

Image for post

Image for post

Image for post

Congratulations! The last XSS vulnerability of this challenge has just been successfully identified!

I enjoyed this challenge incredibly! It was sometimes a bit nerve-wracking, but as soon as the solution was found, I was extremely proud and pleased. Especially I like this creative approach to this challenge. I hope to be able to solve further challenges of this kind in the future.

Always check for a Content-Security-Police (CSP) in the Response-Header.Check if the input must match a certain format (e.g. email)Check whether you can make use of third party servies (e.g. github).The XSS Payload: javascript://%0a%0dalert(document.domain)

In General:

Try to understand how the application works!When something does not work, find the cause and use it to your advantage!Make notes!
Read Entire Article