~$ Dissecting the KnightCTF Misc challenges!

Posted on Jan. 30th, 2022. | Est. reading time: 5 minutes

Tags:CTFWrite Up


Find Pass Code - 2 (150 points)

This challenge was in the Web category, and relied on knowledge from the first challenge, mainly that it required the userr to append ?source to the URL in order to print out the page's PHP source code.

This yields the following code:

```php require "flag.php"; $old_pass_codes = array("0e215962017", "0e730083352", "0e807097110", "0e840922711"); $old_pass_flag = false; if (isset($_POST["pass_code"]) && !is_array($_POST["pass_code"])) { foreach ($old_pass_codes as $old_pass_code) { if ($_POST["pass_code"] === $old_pass_code) { $old_pass_flag = true; break; } } if ($old_pass_flag) { echo "Sorry ! It's an old pass code."; } else if ($_POST["pass_code"] == md5($_POST["pass_code"])) { echo "KCTF Flag : {$flag}"; } else { echo "Oh....My....God. You entered the wrong pass code."; } } if (isset($_GET["source"])) { print show_source(__FILE__); } ```

The first thing that struck me was the fact that it was comparing the passcode entered against its MD5 hash. However, with one-way hashing functions, that shouldn't be the case (H(X) != X).

However, we can see the $old_pass_codes = array("0e215962017", "0e730083352", "0e807097110", "0e840922711"); array, which piqued my curiosity.

I'd remembered a story on Twitter about magic hashes, habitually preceded by the number 0e. (More here: Magic Hashes)

So I searched for an index of magic hashes until I found this website: 魔术hash on CSDN.

Magic MD5 hashes

There were the 3 first hashes, so I took the fourth: 0e1137126905.

Enter that into the platform and we get the flag: KCTF{ShOuD_wE_cOmPaRe_MD5_LiKe_ThAt__Be_SmArT}.

QR Code from the Future (100 points)


The first step is to de-animate the GIF. For this, we can go to EZGIF or use FFMPEG, like so:

```bash mkdir ./gif-images ffmpeg.exe -i .\QR_Code_From_The_Future.gif -vsync 0 gif-images/%02d.png ```

We can then use zbarimg (from the zbar-tools package) to read the QR codes (zbarimg socket errors can be expected and ignored):

```sh find . -type f -wholename "*/gif-images/*.png" -exec sh -c 'RES=$(zbarimg $0 --raw -q); SUBSTR=$(echo $RES | cut -d':' -f 2); echo -n $SUBSTR;' { } \; > gif_contents 2>/dev/null echo "" >> gif_contents cat gif_contents rm gif_contents ```

FFMPEG takes the image provided with the GIF as input (-i), synchroneously (-vsync 0). It then saves it to gif-images, a directory that needs to exist.

%02 is so we don't have a flag out of order, it is just the number of leading zeros for that.

Find checks all files in the directory gif-images that are PNG files. We feed each of these images to zbarimg which produces a code, which we store, remove the QR-Code: segment preceding it and append it to gif_contents.

This produces the string }pvznalq_bg_pvgngf_zbes_qriybir_gbt_rqbp_ED{SGPX, which, when flipped, gives the string XPGS{DE_pbqr_tbg_ribyirq_sebz_fgngvp_gb_qlanzvp}, which itself is a simple ROT13 encryption.

We get the flag: KCTF{QR_code_got_evolved_from_static_to_dynamic}.