It's the day after Christmas; or, depending on your geography, Boxing Day. With the festivities over, you may still find yourself stuck at home and somewhat bored.
Either way; here are three relatively short cryptography challenges, you can use to keep you momentarily occupied. Other than the hints (and some internet searching), you shouldn't require a particularly deep cryptography knowledge to start diving into these challenges. For hints and spoilers, scroll down below the challenges!
The first one is simple enough to explain; here are 5 hashes (from user passwords), crack them:
$2y$10$TYau45etgP4173/zx1usm.uO34TXAld/8e0/jKC5b0jHCqs/MZGBi $2y$10$qQVWugep3jGmh4ZHuHqw8exczy4t8BZ/Jy6H4vnbRiXw.BGwQUrHu $2y$10$DuZ0T/Qieif009SdR5HD5OOiFl/WJaDyCDB/ztWIM.1koiDJrN5eu $2y$10$0ClJ1I7LQxMNva/NwRa5L.4ly3EHB8eFR5CckXpgRRKAQHXvEL5oS $2y$10$LIWMJJgX.Ti9DYrYiaotHuqi34eZ2axl8/i1Cd68GYsYAG02Icwve
HTTP Strict Transport Security
A website works by redirecting its
www. subdomain to a regional subdomain (i.e.
uk.), the site uses HSTS to prevent SSLStrip attacks. You can see cURL requests of the headers from the redirects below, how would you practically go about stripping HTTPS in this example?
$ curl -i http://www.example.com HTTP/1.1 302 Moved Temporarily Server: nginx Date: Tue, 26 Dec 2017 12:26:51 GMT Content-Type: text/html Transfer-Encoding: chunked Connection: keep-alive location: https://uk.example.com/
$ curl -i http://uk.example.com HTTP/1.1 200 OK Server: nginx Content-Type: text/html; charset=UTF-8 Transfer-Encoding: chunked Connection: keep-alive Keep-Alive: timeout=5 Vary: Accept-Encoding Cache-Control: no-cache Date: Tue, 26 Dec 2017 12:26:53 GMT Strict-Transport-Security: max-age=31536000 ...
The following images below are encrypted using AES 256 in CTR mode. Can you work out what the images originally were from?
What kind of hash algorithm has been used here? Given the input is from humans, how would you go about cracking it efficiently?
HTTP Strict Transport Security
All the information you could possibly need on this topic is in the following blog post: Performing & Preventing SSL Stripping: A Plain-English Primer.
From the original images;
2.bmp, were encrypted using a command similar to the one below - the only thing which changed each time the command was run was the file names used:
openssl enc -aes-256-ctr -e -in 1.bmp -out 1_enc.bmp -k SomePassword -iv 0010011 -nosalt
Another hint; both images are from the same source image, each just has different layers of the same original image.
Solutions (Spoiler Alert!)
The hashes start with a
$2y$ identifier, this indicates the hash has been created using BCrypt (
$2*$ usually indicates BCrypt). The hashes also indicate they were generated using a somewhat decent work factor of 10.
Despite the recent implementations of the Argon2 key derivation function, BCrypt is still generally considered secure. Although it's unfeasible to crack BCrypt itself, users have likely not been as security conscious when setting passwords.
Let's try using a password dictionary to try and crack these hashes, I'll start with a small dictionary of just about 10 000 passwords.
Using this password list, we can crack these hashes (the mode number,
3200 represents BCrypt):
hashcat -a 0 -m 3200 hashes.txt ~/Downloads/10_million_password_list_top_10000.txt --force
Despite being on my laptop, it only takes 90 seconds to crack these hashes (the output below is in the format
$2y$10$DuZ0T/Qieif009SdR5HD5OOiFl/WJaDyCDB/ztWIM.1koiDJrN5eu:password1 $2y$10$TYau45etgP4173/zx1usm.uO34TXAld/8e0/jKC5b0jHCqs/MZGBi:password $2y$10$qQVWugep3jGmh4ZHuHqw8exczy4t8BZ/Jy6H4vnbRiXw.BGwQUrHu:hotdog $2y$10$0ClJ1I7LQxMNva/NwRa5L.4ly3EHB8eFR5CckXpgRRKAQHXvEL5oS:88888888 $2y$10$LIWMJJgX.Ti9DYrYiaotHuqi34eZ2axl8/i1Cd68GYsYAG02Icwve:hello123
HTTP Strict Transport Security
The first redirect is performed over plain-text HTTP and doesn't have HSTS enabled, but the redirect goes to a subdomain that does have HSTS enabled.
If we were to try stripping away the HTTPS in the redirect (i.e. forcibly changing HTTPS to HTTP using a Man-in-the-Middle attack), we wouldn't have much luck due to HSTS being enabled on the subdomain we're redirecting to.
Instead, we need to rewrite the
uk. subdomain to point to a subdomain which doesn't have HSTS enabled,
uk_secure. for example. In the worst case, we can simply redirect to an entirely phoney domain. You'll need some degree of DNS interception to do this.
From the phoney subdomain or domain, you can then proxy traffic back to the original domain - all the while acting as a Man-in-the-Middle for any private information crossing the wire.
Generating Encrypted Files
Before we learn to crack this puzzle, let me explain how I set things up.
The original image looked like this:
Prior to encrypting this image, I split them into two distinct parts.
The first image was encrypted with the following command:
openssl enc -aes-256-ctr -e -in 1.bmp -out 1_enc.bmp -k hunter2#security -iv 0010011 -nosalt
Beyond the choice of cipher, there are two important options here:
- -iv - We require OpenSSL to use a specific nonce instead of a dynamic one
- -nosalt - Encryption keys in OpenSSL are salted prior to hashing, this option prevents this from happening
Using a Hex Editor, I added the headers to ensure the encrypted files were correctly rendered as BMP files. This resulted in the files you saw in the challenge above.
Reversing the Encryption
The critical mistake above is that the encryption key and the nonce are identical. Both ciphertexts were generated from identical nonces using identical keys (unsalted before they were hashed).
Additionally, we are using the AES in CTR mode, which vulnerable to the “two-time pad” attack.
We firstly run an XOR operation on the two files:
$ git clone https://github.com/scangeo/xor-files.git $ cd xor-files/source $ gcc xor-files.c -o xor-files $ ./xor-files /some/place/1_enc.bmp /some/place/2_enc.bmp > /some/place/xor.bmp
The next step is to add BMP image headers such that we can display the image:
The resulting image is then inverted (using ImageMagick):
convert xor.bmp -negate xor_invert.bmp
We then obtain the original input:
We hope you've had a relaxing holiday season, and wish you a very happy new year!