- Name : BackdoorCTF 2017
- Website : backdoor.sdslabs.co
- Type : Online
- Format : Jeopardy
- CTF Time : link
100 - THE-WALL - Web
Night king needs the secret flag to destroy the wall. Help night king get flag from LordCommander(admin) so that army of dead can kill the living
Let's see this page:
$ curl http://184.108.40.206/WALL/login.html:
We have a simple login form and author of the challenge provides us the source of
Of course parameter taken by
index.php are the same as those in the form:
An important note is that the server compute the md5 of the sent password, so passwords must be stored in md5 in the database.
They are kind enought to provide us the structure of the table:
But we can see that our input pass trough a filer:
So we won't be able to use
UNI%0bON, etc... didn't work).
The injectable SQL query is (quite basic):
And finally we have the authentication part:
We know that LordCommander is the admin user and we need his password to get the flag.
As we don't have results displayed but only authentication errors this will be a boolean-based blind SQli a.k.a. error-based blind SQL injection.
We can use HackBar or BurpSuite to send our SQL payload in POST.
A true query like
life=LordCommander' AND 1=1-- -&soul=b will return an error like
Wrong identity for : LordCommander. But a false query like
life=LordCommander' AND 1=2-- -&soul=b will return
No such person exists.
But I'm a little lazy tonight so I will use sqlmap to dump the database:
Using various online md5 cracker and crackstation I managed to crack
DragonBlood in md5 but didn't find anything for the two others.
Targaryen is just a normal user and we need the password of the admin.
The important part is here:
This is not a strict equality
=== and we know that PHP have some flaw.
So I used PHP Magic Tricks: Type Juggling.
For Type Juggling:
When comparing a string to a number, PHP will attempt to convert the string to a number then perform a numeric comparison.
- TRUE: "0000" == int(0)
- TRUE: "0e12" == int(0)
- TRUE: "1abc" == int(1)
- TRUE: "0abc" == int(0)
- TRUE: "abc" == int(0)
It gets weirder... If PHP decides that both operands look like numbers, even if they are actually strings, it will convert them both and perform a numeric comparison:
- TRUE: "0e12345" == "0e54321"
- TRUE: "0e12345" <= "1"
- TRUE: "0e12345" == "0"
- TRUE: "0xF" == "15"
Here the equality is between two string so we can't use something like
md5('DHINSE') == '0e5600142234d0ede950b3d30d7c7727'.
This time md5db won't help. What we need here is a md5 hash with only numbers because LordCommander password hash is
0e565041023046045310587974628079 so if we manage to get one both stings will be converted to numbers and PHP will do a numeric comparison.
I found on whitehatsec.com the md5 magic hash (
md5('240610708') == '0e462097431906509019562988736854'). We can log in with
240610708 and get the flag.
Since Backdoor is an always-online CTF platform, and not a one time contest, we kindly request you to not publish flags for the challenges in your writeups.
Bonus: If you searched for
0e565041023046045310587974628079 on google there was only one match: a pastbin containing
0e565041023046045310587974628079:MyWatchIsOver. But of course this is a troll because (
md5('MyWatchIsOver') == '0afa34c220d2abce41debe1bb010d987').