๐ Micro CMS v2
A detailed write-up of the Web challenge 'Micro CMS v2' from Hacker101 CTF
๐ Challenge Overview
Category Details Additional Info ๐ Event Hacker101 CTF Event Link ๐ฐ Category Web ๐ ๐ Points 9 Out of 9 total โญ Difficulty ๐ก Medium Personal Rating: 4/10 ๐ค Author Unknown Profile ๐ฎ Solves (At the time of flag submission) Unknown solve rate ๐ Date 04-03-2025 Hacker101 CTF ๐ฆพ Solved By mH4ck3r0n3 Team:
๐ฏ Challenge Files & Infrastructure
Provided Files
1
Files: None
๐ Initial Analysis
First Steps
Initially, the website appears as follows:
This is version 2 of the challenge Micro-CMS v1. By clicking on the
Micro-CMS Changelog
page, we are shown what has been changed fromversion 1
:It seems that an authentication system has been introduced for creating and editing pages. In fact, when I try to click on
Edit this page
orCreate a new page
, I am redirected to/login
:It can therefore be assumed that there is an
SQL Injection
vulnerability that allows us to access account notes already present in thedb
. In fact, when trying to submit a'
in theusername
field, I get anInternal Server Error
:This suggests that the query sanitization is not properly handled, and the parameters are directly passed into the query. To understand what type of
SQL Injection
is involved, the first thing to analyze is whether unique errors are returned for theusername
or just for thepassword
. So, I submitusername=admin&password=admin
to see what is returned:It seems that, as we can see, it returns
Unknown user
, which is a unique error for theusername
(to avoid Error Based SQL Injection, generic errors should always be used, such asusername or password ...
to prevent revealing useful information). This means we could try anError Based Blind SQL Injection
to enumerate theusername
and later thepassword
to access the page. There will probably also be a way to perform aTime Based Blind SQL Injection
. These two types of injections use linear brute force to enumerate and dump the database. Anoracle
query is used, which functions as a real oracle that we can ask questions. Let’s take theError Based
as an example. In this case, we ask the oracle, “Is the first letter of the username perhaps ‘a’?” The oracle responds “yes,” so we ask our next question: “Is the second letter of the username ‘a’?” and so on, until we can compose the entire username. We will use the unique error messageUnknown user
for this technique. For each request, we will check if the response contains that error until we successfully guess the entire username, eventually getting a different error, likewrong password
. The same technique is applied forTime Based
, but instead of using visible errors, it uses the response time. The query payload is built in such a way that it inserts a delay, likeSLEEP(5);
. This way, each time we guess a letter,SLEEP(5);
will execute, and we will know itโs the correct letter by calculating the response time. If it’s approximately5 seconds
, we can move on to guessing the next letter. Letโs move on to the exploitation phase.
๐ฌ Vulnerability Analysis
Potential Vulnerabilities
- Error Based Blind SQL Injection
- IDOR
๐ฏ Solution Path
Exploitation Steps
Initial setup
Building an oracle for a
Blind SQL Injection
can be quite a hassle since you have to try and retry until you find the correct payload. Therefore, I used SqlMap since there are no rules prohibiting the use of automated tools. The first thing I did was launch SqlMap:
1
sqlmap "https://b23aa3c6ccd56e4c43848255ee6bbf51.ctf.hacker101.com/login" --dump -data "username=&password=" --risk 3 --level 5 --threads 8
Specifying the
username
andpassword
fields, SqlMap also identified aTime Based Injection
and built the following oracle from the output:Once this was done, sqlmap started dumping the database. I stopped its execution with
CTRL+C
since sqlmap uses a session saving system, creating files so that it resumes from where it left off in the next run. Here is the resulting log:
1
cat /home/mh4ck3r0n3/.local/share/sqlmap/output/b23aa3c6ccd56e4c43848255ee6bbf51.ctf.hacker101.com/log
Let’s move on to the next phase.
Exploitation
As we can see from the log, a
db
calledlevel2
and a tablepages
within it were found. However, I still wanted to investigate further by dumping all thedb
by specifying the flag--dbs
:
1
sqlmap "https://b23aa3c6ccd56e4c43848255ee6bbf51.ctf.hacker101.com/login" -data "username=&password=" --risk 3 --level 5 --threads 8 --dbs
Nothing interesting, the only database that doesn’t seem to be default is
level2
. From the previous output, I also found another table,admins
, giving a total of two tables inlevel2
, namelyadmins
andpages
. I assume thatadmins
contains the users andpages
contains the created pages. So, I performed the dump of the tables one by one:
1
sqlmap "https://b23aa3c6ccd56e4c43848255ee6bbf51.ctf.hacker101.com/login" --dump -data "username=&password=" --risk 3 --level 5 --threads 8 -T admins
As we can see, inside the
admins
table, there was only one user withusername=donald&password=jannet
. After trying to log in with this user, I obtained the first flag.Subsequently, since we are only told that authentication has been added, I assume that the vulnerabilities from the previous challenge are still present. So, I ran the same script for enumerating the pages that I had written for the previous challenge ( enum_pages.py):
It seems that there is another page which is not visible, namely page number
3
. To avoid wasting time, I performed the dump of thepages
table, specifying--where="id=3"
, so that it wouldn’t dump the first two pages:
1
sqlmap "https://b23aa3c6ccd56e4c43848255ee6bbf51.ctf.hacker101.com/login" --dump -data "username=&password=" --risk 3 --level 5 --threads 8 -T pages --where="id=3"
With this, I was able to obtain the second flag, which was apparently hidden in page
3
in the database (screenshot in theFlag Capture
section). Reading through the write-ups at the end of the resolution, it was also possible to access usingusername=' UNION SELECT '123' AS password FROM admins WHERE '1' = '1&password=123
.I caught the last flag almost by accident… always thinking about a possible
IDOR
, I noticed that by changing the page path from/page/1
to/page/edit/1
(just like in the previous challenge), I was redirected to/login
. But then I thought, what if I accessed it using aPOST
instead of aGET
? Since in the previous challenge, thePOST
method was used to modify thetitle
andbody
of the page. So, I made the request withcurl
:
1
curl -X POST https://b23aa3c6ccd56e4c43848255ee6bbf51.ctf.hacker101.com/page/edit/1
By doing so, I obtained the third and final flag.
Flag capture
๐ ๏ธ Exploitation Process
Approach
The automatic exploit for the second flag uses the method found in the write-up I read after solving the challenge, although I also mentioned my own method, and it seems to work. For the remaining two flags, I made a
POST
request to/page/edit/1
for the third flag, and accessed with the credentials extracted from the blind error-based injection for the first, extracting it from the response text using a regex.
๐ฉ Flag Capture
Flag 1Flag 2Flag 3
Proof of Execution
๐ง Tools Used
Tool Purpose Python Exploit SQLMap SQL Injection Testing
๐ก Key Learnings
Time Optimization
- Move step by step with SQLMap, for example, first enumerate the
dbs
, then once you have the information, move on to dumping a specific table that you’re interested in, and so on…- Directly use a
request.txt
file for sqlmap, as you can copy, for example, the/login
request and use it directly to set upsqlmap
.
Skills Improved
- Binary Exploitation
- Reverse Engineering
- Web Exploitation
- Cryptography
- Forensics
- OSINT
- Miscellaneous
๐ References & Resources
Learning Resources
๐ Final Statistics
Metric | Value | Notes |
---|---|---|
Time to Solve | 00:40 | From start to flag |
Global Ranking (At the time of flag submission) | Challenge ranking | |
Points Earned | 9 | Team contribution |
Created: 04-03-2025 โข Last Modified: 04-03-2025 *Author: mH4ck3r0n3 โข Team: *