Clicking on Testing, I was redirected to the attached page.
Testing Page
As we can see, we are shown a page that can also be edited (while from the homepage, we saw that it is possible to add new ones). So, this appears to be a web application that allows users to add and modify pages. Trying to click on Edit Page:
Edit Testing Page
Apparently, it is also possible to write directly in markdown. At this point, I have already noticed several things that might raise concerns. As we can see from the page URL: https://cea60ebc6360b90016ccca3f3d47b5a7.ctf.hacker101.com/page/1, that /page/1 strongly smells like IDOR. I also thought there might be some sort of LFI (Local File Inclusion) or Remote JavaScript Inclusion through Markdown injection (for example, by hosting a js script on my web server and editing the webhook page). However, after trying to add , I noticed that the request was made, but inclusion was not possible due to strict CSP (Content-Security Policy) rules. Later, I considered LFI by exploiting Path Traversal with something like , but it seemed that this was not the right approach. So, I went back to focusing on IDOR.Instead of performing enumeration and discovery manually or using tools like ffuf or gobuster, I directly used a script I wrote in Python to automate the process ( enum_pages.py):
1
python enum_pages.py
Enum Pages
I wrote the script based on the information gathered earlier, namely that so far we know of only two pages: 1 and 2, which correspond to Testing and Markdown Testing, respectively. So, I started the for loop from 3 up to a maximum of 100 pages (although making that many requests wasn’t necessary). Of course, if a page is not found, as we can see, an error code 404 is returned, for example, when making a request to https://cea60ebc6360b90016ccca3f3d47b5a7.ctf.hacker101.com/page/3:
Not Found
So, I used an if inside the for loop to filter only status codes different from 404, to determine if there were any actual pages. (Of course, I could have also done it with an if == 200, but that would require excluding redirects like 302, etc., so this method is much simpler). Now that we understand how the script works, let’s focus on the result. Based on the findings, there is an IDOR: a page (7) exists but is not displayed on the homepage (which also suggests the presence of a Database where pages are stored, meaning we should also test for SQL Injection).Additionally, we receive a 403 Forbidden, meaning we need to figure out how to bypass the 403 to access the page by exploiting the IDOR. Another thing that came to mind is a potential XSS during the creation/editing of a page, though I’m not sure what use it would be, since after checking, there are no cookies to steal. (After bypassing the 403, I also tried other methods, such as using an iframe, and I did a small deep dive, discovering that the CTF hosting is done with AWS. For fun, I even tried enumerating the buckets, but I didn’t find much ^^).
🔬 Vulnerability Analysis
Potential Vulnerabilities
IDOR
SQL Injection
XSS
🎯 Solution Path
Exploitation Steps
Initial setup
To summarize, the potential vulnerabilities we have identified are SQL Injection, XSS, and the increasingly evident IDOR. We now know that visiting https://7a74d0c5389c327f82589980c926c053.ctf.hacker101.com/page/7 results in a Forbidden response, so let’s move on to the next phase to figure out how to bypass it.
Exploitation
In the page edit phase, the previous screenshot did not show the URL, but it includes edit in it: https://7a74d0c5389c327f82589980c926c053.ctf.hacker101.com/page/edit/1. We can try to exploit this to bypass the 403, since in “view” mode, the page returns a 403. However, by switching to “edit” mode (https://7a74d0c5389c327f82589980c926c053.ctf.hacker101.com/page/edit/7), we can successfully bypass the 403 and obtain the first flag.
Now that we’re at it, let’s try exploiting a possible SQL Injection, as I imagine it might be easier to break things in “edit” mode than in “view” mode. So, I try inserting a ' in the URL to see if I get a 500 - Internal Server Error: https://7a74d0c5389c327f82589980c926c053.ctf.hacker101.com/page/edit/'. It turns out that this CTF handles things a bit differently from a typical Jeopardy-style challenge, because simply exploiting the vulnerability in any way grants the flag. Instead of a 500 Error, I got the second flag.
Now, let’s try to obtain an XSS. I tried inserting <h1>Hi</h1> and it seems that HTML injection works. Since we have two fields: title and the body textarea, I test the injection directly on both by inserting a simple alert <script>alert(1)</script> to see how the most basic injection case is handled.
InjectionInjection Page Source
As we can see, both fields handle it, but in the case of the body, the word script is replaced with scrubbed. This can actually be taken as a hint, since the replacement is happening, and as we know, there are other ways to achieve XSS. By pure chance, when I returned to the homepage, I triggered the flag in an alert related to the injection in the title field (apparently, there was no protection there).As we can see by inspecting the page source, the flag is also inserted directly into the page itself.
HomePage Page Source Stored Flag
I imagine that the fourth flag can be found in the injection of the body field. After trying the classic onerror payload: <img src=x onerror="alert(1)">, I got the alert, but this time I didn’t find the flag in it. However, we’ve just seen that the flag is inserted into the HTML of the page itself, so by inspecting the page source, I found the fourth flag.
Body Injection Alert
Flag capture
Manual Flag 1Manual Flag 2Manual Flag 3Manual Flag 4
🛠️ Exploitation Process
Approach
The automated script performs the same operations previously described and extracts the flags from the responses of the GET requests to the page using a regex.
Automated FlagScreenshot of successful exploitation
🔧 Tools Used
Tool
Purpose
Python
Exploit
💡 Key Learnings
Time Optimization
It’s important to try out the vulnerabilities you’ve considered, even if they don’t seem to make sense in that context, like for XSS. This is especially true since this is a Bug Bounty-focused challenge rather than a typical CTF Jeopardy style competition.