OWASP Kathmandu 0x06 CTF

Ams._.Ghimire
6 min readJun 4, 2024

--

Walk-through for ‘Blank’ and ‘Cookies Cookies Everywhere

In this blog, I will be discussing a walk-through of two of the challenges created by Hack@Sec for OWASP Kathmandu 0x06 and my approach to solving them. Although I was not able to solve a few challenges within the allotted time of the CTF, our team, CSRH, secured 2nd place in the challenge.

Let’s proceed with the walk-through.

Cookies Cookies Everywhere

The challenge provided us with a URL where the CTF was hosted. Visiting the URL, I found a simple webpage that had no interactive features and seemed pretty static. There was nothing particularly interesting in the HTML code itself. However, upon checking the storage inspector in my browser, I found a cookie. At first glance, I thought it was a JWT cookie, so I decoded it.

Unfortunately, not every assumption is correct, and it wasn’t a valid JWT. On second thought, the short text in the middle of the cookie hinted at the possibility of it being a Flask session cookie. Let’s break down the structure of a flask cookie.

A Flask session cookie consists of a payload, a timestamp, and a hash of the data. The timestamp value is usually very short, and this led me to think it was a Flask cookie. The main issue with a Flask cookie is that it can be brute-forced to find the secret key used to generate the hash. So, I tried to brute-force the cookie to get the secret key. I used the flask-unsign utility to crack the secret used to sign the Flask session cookie. I used the common wordlist rockyou.txt to brute-force the key.

The tool brute-forced and cracked the secret key used to generate the hash for validity. spiderman was the secret key used to generate the hash. Now, any cookie we create by signing it with the key spiderman is a valid cookie. Next, I created a cookie with the username set to admin and signed it with the key spiderman.

After entering the cookie in the browser and refreshing the page, I got the Flag: OWASP{Session_Cookie_Validation}.

Blank

In this challenge, we were given two URLs. One contained a visit link feature, and the other was provided for testing the payload for exploitation.

At first glance, it was clear that it was some sort of blind XSS challenge where we had to steal the admin’s cookie. So, I started testing random payloads; however, I was unsuccessful in executing the XSS. Any text that we entered through the parameter in the URL was reflected on the page; however, the normal XSS payloads doesn’t execute directly.

While viewing the page’s HTML code, I noticed a <frameset> tag.

The <frameset> element allows us to render multiple HTML parts independently on the webpage. It was widely used in HTML version 4 and is similar to the modern <iframe> tag. The <frameset> tag contains opening and closing tags that acts like a wrapper to hold the <frame> tags. The <frame> tags are used to fetch the actual HTML content externally and render it in different parts within the webpage according to the attributes defined within the tag. I tried to render the <frame> tag by fetching a random GIF from another challenge to test, and it worked!

This was the part where a thought struck, and I realized I could exploit the XSS. The src attribute on the <frame> tag could be manipulated to cause an error, and an event handler onerror could be triggered to execute JavaScript code. Alternatively, we can simply fetch the URL that uses the JavaScript scheme (javascript:) to execute the JavaScript directly from the URL itself. I tried the latter one.

Finally, I was able to cause JavaScript injection on the webpage. Now, I tried to fetch my Burp Collaborator URL to check if it makes an external call.

Monitoring the network tab, I saw it was making a GET request to my collaborator address. Now, I stored a cookie for testing and tried appending it with the collaborator’s URL. This was the part where I failed in the CTF challenge. Simply appending the cookie using the +concatenation operator didn’t work for me, and I got stuck. However, after the CTF was over I later tried using other functions such as the .concat() function to concatenate the cookie with the URL, and it worked.

I entered this payload in the Admin’s Bot Page, and finally got the flag after hundreds of silly concatenation blunders.

The flag was OWASP{make_xss_great_again}.

Alternatively,

In the challenge, we were given a link to a blog as a hint that presented research on frameset injection and referred to how we could trigger XSS within the <frameset>by leveraging CSTI in AngularJS. Firstly, let’s understand what the <noframe> tag is. It simply executes an error handling mechanism to display that block of HTML or any content to be presented if the browser doesn’t support the <frameset> element. It’s like an error message saying, “Sorry, the browser doesn’t support <frameset> ”.

The hint provided info on how we can force the execution of the <noframe> tag even if the browser perfectly supports frames. This may have seemed impossible beforehand, but adding ng-app Directive on the <noframe> tag allows us to run AngularJS templating expressions within the tag. This led to the bypass of <noframe> blockage, and we could leverage CSTI on AngularJS to execute XSS on the browser. The blog itself provided the first skeleton of the payload which was calling an alert function, jailbreaking the <noframe> blockage. So let’s solve the challenge again as intended by the author.

Let’s first execute a simple alert function on the webpage.

As we can see, although the application supported frames, the <noframe> tag was called, and CSTI was executed within the <noframe> tag. Now, as before, let’s append the cookie and send the URL to our Burp Collaborator to grab the admin’s cookie. First, let’s ensure if it fetches our Burp Collaborator’s URL, and it does!

Now, let’s append the cookie again and try to fetch our exploit server address.

I’m not sure why, but like before, the + operator breaks the syntax and doesn’t append the cookie, as no call is made. So, let’s use the .concat() function again to concatenate the URL and the cookie. It finally worked, and the request is made.

Now, finally, let’s enter the URL for the admin bot page to visit.

The challenge is solved! This approach was interesting and highlighted how different services can be used hand in hand to chain severe bugs in real-world scenarios.

Thank you for taking time to read my walk-through :) Happy Hacking!

TG9sLCBZb3Ugc2VlbSBpbnRlcmVzdGVkISBUaGFua3MgZm9yIHJlYWRpbmcgYWxsIHRoZSB3YXkgdG8gdGhlIGVuZCEgOik=

--

--

No responses yet