“Capture the flag: reversing the passwords (Solutions)”

Aug 9, 2017

Step 1 - Recovering the corrupted data

According to the doc, the following stream is corrupted:

7b 0a 20 a0 22 65 76 e5
6e 74 22 ba 20 22 70 e1
73 73 77 ef 72 64 5f e3
68 61 6e e7 65 22 2c 8a
20 20 22 f5 73 65 72 ee
61 6d 65 a2 3a 20 22 e2
63 6f 6c ec 69 6e 22 ac
0a 20 20 a2 6f 6c 64 df
70 61 73 f3 77 6f 72 e4
22 3a 20 a2 3a 5c 78 c3
37 5c 78 c6 34 5c 6e dc
78 41 46 a9 29 37 43 dc
78 31 35 dc 78 44 30 dc
78 46 33 dc 78 44 45 e9
55 3b 22 ac 0a 20 20 a2
6e 65 77 df 70 61 73 f3
77 6f 72 e4 22 3a 20 a2
39 5c 78 c6 41 5c 78 b9
39 5c 78 c3 41 5c 78 c5
44 5c 78 c6 32 58 53 c7
5c 78 44 c4 2d 5c 78 c3
32 5c 78 b8 45 7a 48 eb
22 2c 0a a0 20 22 74 e9
6d 65 73 f4 61 6d 70 a2
3a 20 31 b5 30 31 38 b5
38 38 36 b0 30 30 30 8a
7d 0a

Running xxd -r -p we can see that individual characters are readable and some are not.


The readable ones help us figure out what we need to change and bit-by-bit, while playing around we start noticing a clear pattern.

 hex(0xE5 ^ 0x80)

Admittedly, figuring out the pattern took a bit of trial and error, but eventually I constructed the following:

  "event": "password_change",
  "username": "bcollin",
  "old_password": ":\xC7\xF4\n\xAF))7C\x15\xD0\xF3\xDEiU;",
  "new_password": "9\xFA\x)9\xCA\xED\xF2XSG\xDD-\xC2\x8EzHk",
  "timestamp": 1501858860000

What I found out later (I will explain this in more detail later) is that the username and the timestamp were only really there to verify the data after I had fixed it.

Step 2 - Gibberish to hash

The old_password hash was already escaped, so I could make it readable as follows:


The second one required a bit more work, but eventually I got there:


The doc states that a hashing algorithm was used to make recovery harder. By measuring the length of the hashes we can assume that MD5 was used to store the passwords, which we will later see is an insecure method to store passwords.


Step 3 - “Reversing” the hashes

This is the part where I needed Jobert’s help. There were two vital moments that allowed me to figure out the solution. As you may know reversing a hash in a technological sense is impossible, since hashing algorithms are one-way functions. In order to get to the passwords you would need to crack the hashes first. I attempted this to no avail. Trust me, I tried everything. Aside from running cracking software, I hashed every single word in the doc and looked up keywords to find more keywords that could be linked to the password. This is where I started looking up Barry Collin and trying to figure out a possible hint. Yes, I assumed this CTF would be another Cicada 3301! Finally, after hours of hard work, one simple little mistake by Jobert made me focus on something else and slowly get to the solution: Jobert accidentally got Barry’s name wrong and called him Brian.


This is when I jumped back to the “reversing” aspect of things. This was the final moment when Jobert helped me with a final hint.


This was the lightbulb moment. I did not have to crack the hashes as is, I had to literally reverse the strings:

 old_password = '3ac7f40aaf2929374315d0f3de69553b'[::-1]
 new_password = '39fa99caedf2585347dd2dc28e7a486b'[::-1]

Step 4 - Cracking the hashes

Now finally, the fun part!

The old_password hash was md5(md5).

$ python pybozocrack.py -s b35596ed3f0d5134739292faa04f7ca3
$ python pybozocrack.py -s 2a9d119df47ff993b662a8ef36f9ea20

The new_password required the use of Crackstation:

b684a7e82cd2dd7435852fdeac99af93 - md5(md5) - thisiscrazy

What did I learn?

The most secure method of password storage, which will keep hackers busy is simply reversing an MD5 hash. 😛

Support my work

If you enjoy reading my write-ups and would like to support my work, please take a moment to read up about the Froglife group and consider donating to help save frog lives.

🐸 Learn more