The first thing to do with any new app we’re testing is to play with every feature.

Looks like we can view pages and create new ones. Let’s look at one of the pages.

Right off the bat, the simple integer ID catches my eyes. My reflex is of course to enumerate IDs. Changing the 2 for a 1 returns the other page as expected.

Let’s try going higher. 3 Not Found. 4 Forbidden.

An interesting change in behavior, there might be something here. Let’s keep that in mind.

Now let’s try to edit a page.

The URL is now page/edit/{id}. What if we were to try to directly access the forbidden page we found earlier through the edit endpoint?

It worked! We have now discovered our first flag through an IDOR leading to horizontal privilege esacalation using parameter tampering.

Now, seeing those user controlled input fields and save a button, one should automatically think Stored XSS. It says that scripts are not supported, but there are other ways to achieve XSS without a script tag.

Based on the <button>Some button</button> we can assume that HTML tags are allowed. We can write JavaScript code as value of attributes, such as onclick, onerror, and so on.

Let’s add this snippet of code <img src="gonnafail" onerror="alert(document.location)" /> and save.

The image failed loading (as expected) and our XSS seems to be working properly. But we did not receive a flag. As a developer, my reflex is to go inspect the code, to see if I messed something up. And to my surprise, there laid our second flag.

Two flags down, two to go!

Now I want to play with the create page feature.

Again, input fields = XSS. Let’s create a new page with <script>alert(document.location) My new page!</script> as a title.

Well, we tried. But it looks like the developers thought about that one here. Let’s keep checking around! Going back to the home page…

Great! Our script tag is interpreted in the home page and we have just found our third flag.

I kept looking around for the last flag. It seemed like I tried every feature. I took a step back and reminded myself that it is a CTF. We have found many XSS vulnerabilities, so it would be safe to bet that there are other classic vulnerabilities. So I started to look for SQLi by adding a ' at the end of every URL. Once I got to /page/edit/1', the fourth and final flag was given.


Lessons learned

  • Changes are not always visible in the UI, always monitor the source code
  • Always enumerate IDs (and try with a large sample)
  • Pay attention to details, changes in responses or behaviors may lead to something
  • Don’t get discouraged if there’s a protection in one place, chances are there will be a vulnerable implementation elsewhere
  • Don’t get too focused on one type of bug