DEV Community

DaNeil C
DaNeil C

Posted on • Updated on

Hacker101 CTF - Micro-CMS v2

More and more CTFs!!!!

Recently I've started diving into CTFs and trying my hand at some Bug Bounties. This means that I will need to be writing reports with any bug I find and want to practice. So, here I go.

  • CTF Name: Micro-CMS v2
  • Resource: Hacker101 CTF
  • Difficulty: Moderate
  • Number of Flags: 3

Note::: NO, I won't be posting my found FLAGS, but I will be posting the methods I used.


  • Hint: Regular users can only see public pages, Getting admin access might require a more perfect union
  • Acquired By: This one seriously too me two days. I spent time reading over how people handled it and nothing really made since until today. SO, if you try to log in as 'admin' and a few different passwords you get back "404 Not Found". This is where throwing in some SQL helps. At this point I tried admin ' and got back Alt Text. This is interesting and all. It tells me that I am on the right track but I don't have the correct format. The hint is about a union so I think I need a SQL UNION of some kind. From here I used the string 'UNION SELECT '123' AS password FROM admins WHERE '1' = '1' and came back with errors. If you read the last line of the image above each time you try a different SQL string, it changes. For me, this is where I got stuck. Nothing seemed to work and all of the videos showed Burp Suite or it just working and nothing made since to me. It seemed like they were doing something that wasnt being shown but it was really just bad videos and lack of my own knowledge of what was happening. It took me about half a day more to really nail down how to use Burp for this and get it working. So let me explain it.
    • To use Burp here we need to access the page with the proxy running on the site. From here I could see my string in the Proxy tab and HERE is where you need to sent it to the Repeater. Once in the repeater you can refine the SQL sting and for me I found out that I needed to get rid of my last '. I was able to have 'UNION SELECT '123' AS password FROM admins WHERE '1' = '1 as the username and the password was the 123 without quotes. This produced the proper response in Burp. From here I was able to take this new working SQL string to the real site and log in. Now navigate back to the hope page and the "Private Page" is there with the key. ehhh I'm tired now but I have two more to do. Alt Text
  • Thoughts: Pay attention to your quotes. Sometimes more is not better.


  • Hint: What actions could you perform as a regular user on the last level, which you can't now?
  • Acquired By: Utilizing CURL in the command line made this way easier than Burp Suite. Alt Text As you can see you will need to change the specific URL to your specific instance path but it was as easy as this.
    • FYI for Curl the following tags are added and here is what they mean.
    • -v, --verbose Make the operation more talkative
    • -X, --request Specify request command to use
    • POST forces the URL as a POST request rather than the GET that it is normally.
  • Thoughts: If I thought the previous flag had confusing walk throughs this one was WAY worse. I attempted so many Burp Proxy and Repeaters and nothing was proving responsive... until I found one that went into the CLI and used Curl.
    • I am also not entirely sure what this does. I get that I can force a different request to the API than it is expecting and get a different response but I am not sure how this is practical... I will have to play with this more.


  • Hint: Credentials are secret, flags are secret. Coincidence?
  • Acquired By: This took some fancy SQL that I would never have guessed... How is this a medium difficulty? Anyway... First we need to apply username=foo' OR (select 1 from(select count(*),concat((select (select (SELECT concat(0x7e,0x27,cast(admins.username as char),0x27,0x7e) FROM `level2`.admins LIMIT 0,1) ) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a) AND '1' = '1 this string to the username. wow. It produces for me Alt Text. I need traci. Then I need another crazy string username=foo' OR (select 1 from(select count(*),concat((select (select (SELECT concat(0x7e,0x27,cast(admins.password as char),0x27,0x7e) FROM `level2`.admins LIMIT 0,1) ) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a) AND '1' = '1 to produce Alt Text and again I need to pay attention to the Duplicate Entry of "Larissa". (I assume that these will be different for anyone and either way you should do this yourself to see the results as they appear on your system). This means that for me my secret credentials are traci with a password of larissa and then the key appears.
  • Thoughts: A lot of people used Burp Suite to get this one but I had a lot of difficulty figuring out exactly they were doing do I went this rout with SQL, though admittedly I am not entirely sure what it is doing. I can tell that it is concatenating the admin password and getting information from "level 1" (wherever that is) and limiting the the returned value from the information_schema.tables group... I can guess that it is designed to pull information from each part of the table to find a hidden log in and its associated password but I will have to do more research as to how. If you know more about this I would love to get your input.


Happy Hacking

Please Note that I am still learning. If something that I have stated is incorrect please let me know. I would love to learn more about what I may not understand fully.

Top comments (15)

suther profile image
Samuel Suther

Thank's @DaNail Coulthard for your Articles. I'm also started with Hacker101.
It's a pleasure to read your experiences with the course.

I even stuck on Flag 1, but with a little help from the Community I solved it in Burp Suite.

You can do it as following: Start a Request to the "edit"-Page and send the request to the "repeater". Be aware, that you have no cookies in your firefox from a current or previous login! (⇐ Thats was the Magic-Point for me!... if you have a cookie in your Headers, you got a "Bad Request"-Result).
In RAW or Headers-Tab change GET with POST. Then you got your Flag.

caffiendkitten profile image
DaNeil C

Hey Samuel.
Thanks for this different approaches to the v1 and v2 flags.
Great to learn more options of way to get flags

carlosm99 profile image

Bro I keep having Bad Request-Result even if I clean the cookies.
Can someone please help me.

Thank you in advanced!

carlosm99 profile image

I just found the solution it's a bit embarrassing heheh but anyways. When removing the cookies it ask's if you want to remove the cookies of today, hour ago, two hour ago and so on... etc. The option I choose is to remove all.

matthiaskoch profile image
matthias koch • Edited

Hello! Also a newbe, started today and played with your login hack and did this:

  1. Login with your hack.
  2. take the login entry in burp to the repeater
  3. change Line1 to POST .../page/edit/2
  4. got my second Flag without session cookie ;)
matthiaskoch profile image
matthias koch

and get the third Flag with your SQL Code. The first one for Username and the second for password.
I don't understand how it works, but maybe later..

antonjiang profile image

Hi DaNeil,
I started doing CTFs yesterday, complete noob. Learned a lot from ur post. I did some research and learned SQL basics, some double SQL injection techniques. I think ur FLAG 2 worked like this: its an Error Based SQL injection. The intention is to produce some error that will leak information about the database, the count(), floor(rand()*2) a ... group by a will produce that KeyError because the interaction between group by(aggregation) and count(). Since we can see the error, we could add some information about the database in the concat(), which will become the key and produce KeyError and then gets displayed. The information we wanted simply came from information_schema. Then its basically iteration through the database.

winterstarr profile image
winterstarr • Edited

I used a different method for Flag 2.

I used comparisons for the username and password substrings and then found them letter by letter.

The main idea is that you can use a comparison in the username and if it is true, you will get one error ("Invalid password") and if it is false you will get another ("unknown user"). So you can keep giving it comparisons and check the error result to find if it is true or not.

For example:

username=' OR 1=1;- -&password=

is true and therefore it passes the username check but fails the password check, resulting in "Invalid password"


username=' OR 1=2;- -&password=

is false and therefore fails the username check, resulting in "Unknown user".

So beginning by solving the username, I start with:

username=' OR Ascii(substring(username,1,1)) > 109;- -

(Ascii(substring(n,n)) returns the ascii character code of the nth character in the string)

If the first letter of the username ascii code is greater than 109 (which is the letter m), then the comparison will be true and it will tell me "Invalid password" as the error. Now I can try:

username=' OR Ascii(substring(username,1,1)) > 115;- -

If the character is not greater 115 (the letter s) the comparison will be false and it will give the "Unknown user" error instead. Now I know the the letter is greater than m and not greater than s, therefore it is between n and s.

You continue these comparisons until you find the exact letter. Then you move onto the next character

username=' OR Ascii(substring(username,2,2)) > 109;- -

Now you're checking if the second character is greater than 109 (m).

Once you find a character that equals 0, you know you have hit the end of the string.

You repeat the same process for password:

username=' OR Ascii(substring(password,1,1)) > 109;- -

I used Burp Suite for this to manually do it, but I'm sure you could write a script that did this faster using a binary search for each letter and just checking whether the response has "Invalid password" or "Unknown user" in it.

danbradster profile image

Flag1: I don't have burp so used an easier method. Go to the edit page, leave it open. Open a new tab (same URL), log out. In the edit page, hit save. Done.

That way, you're submitting an edit form without being logged in as admin, but it still works.

malcolmstill profile image
Malcolm Still


Thank you for your article, I also didn't like that answer and wanted to come up with something simpler (to me). For that I went with a timing attack.

I've written it up on my blog

malcolmstill profile image
Malcolm Still

I rewrote my solution as I realised I don't need to use SLEEP.

See my follow up

bharatt13770141 profile image
Bharat_Thapa.php • Edited

on flag 1 what was the hint about? what does it mean by saying "What actions could you perform as a regular user on the last level, which you can't now?"

caffiendkitten profile image
DaNeil C

I assumed that it was talking about how a regular users can only view pages but an admin can edit them and that is why the flag is on /page/edit/2.

danbradster profile image

It's saying that logged out users should not be able to edit pages, but in fact, if you can simulate the right POST request, it'll still go through, even when logged out.

__the_watcher profile image
The Watcher

This was so helpful. I just got lost on the last flag. can anyone help me

Some comments may only be visible to logged-in visitors. Sign in to view all comments.