CryptoCTF 2019 Writeup: Decode Me

August 11, 2019
ctf crypto

This is short writeup on the Decode Me challenge of the first CryptoCTF.

The following string has to be decoded into a flag somehow:

D: mb xwhvxw mlnX 4X6AhPLAR4eupSRJ6FLt8AgE6JsLdBRxq57L8IeMyBRHp6IGsmgFIB5E :ztey xam lb lbaH

The first thing that comes to mind is that some sort of substitution cipher was being used in the first place. A cipher of this kind is the Caesar cipher which is also known as ROT. Fiddling around with this cipher and a key of 7 yields:

K: ti edoced tsuE 4E6HoWSHY4lbwZYQ6MSa8HnL6QzSkIYex57S8PlTfIYOw6PNztnMPI5L :galf eht si sihO

And reversed:

Ohis is the flag: L5IPMntzNP6wOYIfTlP8S75xeYIkSzQ6LnH8aSM6QYZwbl4YHSWoH6E4 Eust decode it :K

The odd thing is that some characters, the O in Ohis, the E in Eust and the smiley and the end of the line seem broken. Playing around with other keys and ciphers like Affine cipher or Vigenère didn’t work. Also just decoding the alleged flag with Base64 and other encodings didn’t produce anything useful.

While trying to fix the corrupted characters, it has been observed that with a ROT key of 12, the corrupted characters seem to be included correctly in the plaintext when merging it with the result with key 7:

Tmnx nx ymj kqfl: Q5NURsyeSU6bTDNkYqU8X75cjDNpXeV6QsM8fXR6VDEbgq4DMXBtM6J4 Jzxy ijhtij ny :P

Base64 decoding this prints:

CTF̞INL3db<_\3i]zB<}tzT1pm3x%

This at least starts with the CTF string…

The assumption that has been made is that the alleged flag is encoded with Base64. It’s known that all flags start with the CCTF{ string in this particular CTF, so Base64 encoding this prints: Q0NURns= as reference. Therefore the encoded flag has to start with this string or a substring of it.

The decryption result with key 12 starts with Q5NUR which is quite similar to the string that’s being searched for. Let’s line up both decryption results:

L5IPMntzNP6wOYIfTlP8S75xeYIkSzQ6LnH8aSM6QYZwbl4YHSWoH6E4 (key 7)
Q5NURsyeSU6bTDNkYqU8X75cjDNpXeV6QsM8fXR6VDEbgq4DMXBtM6J4 (key 12)

It was striking that the numbers weren’t rotated when decrypting the string with CyberChef. According to the reference above, the second character has to be a zero but it’s a five. So I’ve decided to just add 5 to every number that’s present in the second decryption result (second line in the listing above):

Q0NURsyeSU1bTDNkYqU3X20cjDNpXeV1QsM3fXR1VDEbgq9DMXBtM1J9

And Base64-decoded:

CCTF̞IM[L3db7_m3i]uB7}tuT11pm3R}

Looks better but not good enough.

An additional thing to notice is that they string decrypted with 7 has all lowercase characters correct. The 12 one has all uppercase characters correct - the T, J and P. So the idea was to merge these strings together: Use the lowercase characters from the 7 one, the uppercase ones from the 12 string and also rotate the numbers as shown before. This yields:

Q0NURntzSU1wTDNfYlU3X20xeDNkXzV1QnM3aXR1VDEwbl9DMXBoM1J9

And Base64-decoded:

CCTF{sIMpL3_bU7_m1x3d_5uBs7ituT10n_C1ph3R}

What to take away from this? I don’t know. Maybe that

Base64Encode(CCTF{) = Q0NURns=
Base64Decode(Q0NURnt=) = CCTF{

So this means that there are various inputs for Base64 decoding that decode to the same string.

Dynamic Instrumentation: Frida And r2frida For Noobs

September 13, 2019
radare2 r2 frida r2frida ctf reverse-engineering

r2con 2019 CTF Writeups

September 2, 2019
r2 radare2 ctf reverse-engineering

ROP On x64: What's ret2csu Again?

August 29, 2019
exploiting rop radare2 r2 ctf ret2csu