- Name : BackdoorCTF 2016
- Website : https://backdoor.sdslabs.co
- Type : Online
- Format : Jeopardy
- CTF Time : link
Recently Chintu made a login service to secure his flag. But we managed to get the authentification logic to be found here. Can you help us to get his flag? Find the login form here.
var express = require('express');
- A computer with an OS (preferably UNIX)
- Internet access
- Take a look at the logic source code.
if (username !== 'chintu')clearly indicates that the username is
if (password === 'complexPasswordWhichContainsManyCharactersWithRandomSuffixeghjrjg')let us believe that the password is
complexPasswordWhichContainsManyCharactersWithRandomSuffixeghjrjgbut it's not. If you try this password you will get this message : Hacker got you! I know my password was leaked, won't give you my flag.
- In fact, that is the else statement that returns the flag.
- So we have to validate the root if statement
if (crypto.pbkdf2Sync(password, salt, iteration, keylength).toString() === hashOfPassword)with another password than
- We can see that
- We'll try to create a PBKDF2 + HMAC hash collision. For more details see the PBKDF2 + HMAC collision explanation part below.
- Enter the collision password
- Here you are.
PBKDF2 + HMAC collision explanation#
Inspired by mathiasbynensbe
PBKDF2 is a widely used method to derive a key.
Minimal arguments are:
- number of iterations
- key length
HMAC has an interesting property: if a supplied key is longer than the block size of the hash function that’s being used, it uses the hash of the key rather than the key itself.
SHA-1 has a block size of 512 bits, which equals 64 bytes.
So in this case, if the supplied key takes up more than 64 bytes, then SHA1(key) is used as the key.
In this challenge password is 65 bytes long:
echo -n 'complexPasswordWhichContainsManyCharactersWithRandomSuffixeghjrjg' | wc -c
Note that the collision password always has a length of 20 characters, because SHA1 hashes always consist of exactly 40 hexadecimal digits representing 20 bytes. One byte, i.e. two hexadecimal digits are used for each character in the colliding password.
Here, how to generate the collision password:
echo -n 'complexPasswordWhichContainsManyCharactersWithRandomSuffixeghjrjg' | sha1sum | xxd -r -p
echodo not output the trailing newline else generated password would be wrong.
xxd- make a hexdump or do the reverse.
-revert: convert hexdump into binary.
-plain: output in postscript continuous hexdump style. Also known as plain hexdump style.
-r -p: Use the combination -r -p to read plain hexadecimal dumps without line number information and without a particular column layout.
That is why
e6~n22k81<[p"k5hhV6* have the same PBKDF2-HMAC-SHA1 hash.
There is an infinity of PBKDF2-HMAC-SHA1 collisions.
While it’s easy to find a collision for any given string larger than 64 bytes (just run the above Bash command), it gets trickier if you want the colliding password to consist of readable ASCII characters only. SHA1 hashes can contain any hexadecimal digits, and converting such a hash back into a string is likely to result in at least one character outside of the printable ASCII range (
To see how to choose a prefix for the colliding password go to [link][mathiasbynensbe.
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. Writeups are an excellent way to share knowledge and help others learn. In Backdoor, challenges are shifted from a contest to the Practice section, where people can continue to attempt them after the contest is over. It would be very unfair to participants if the flags for the problems were easily available in writeups online. Hence, we kindly request to not publish flags of the problems that you solve. Here is an example of an excellent writeup which refrains from giving the complete solution.