Let's say you're making a video conferencing software and you need an encryption algorithm, but which one to pick?
There's so many options? Let's just choose the first one we see.
There's no way a real company would do something like that... right?
- Note: This file contains the flag hidden as base64, you could just decode it from there but that's no fun
This is a hosted challenge, meaning you need to communicate with a server that's running
server.py. How do you set this up?
- A: (Recommended) Run the provided dockerfile by running the provided
- B: Try to run the script directly, this only makes sense to do if you don't have
dockerinstalled and don't want to set it up for whatever reason
Welcome to challenge 2, where we'll be jumping straight into a modern encryption algorithm! Now you may think that just because this is a real encryption algorithm that Zoom really did use in their software that this challenge is going to be hard to solve.
But that isn't the case! Cryptography can often times be mathematically unbreakable, but present many flaws and pitfalls when brought to the real world.
So let's take a look at how that can happen
What do you do when you want to make a message secret? The most common solutions use something that's called a block cipher.
What is a block cipher? It's a function that takes 16 bytes and a key, and encrypts it. The standard block cipher, AES, is extremely extremely good at doing this. It's been analyzed and tested to hell and back and no one has been able to break it. How it works is a bit complicated so you don't need to worry about it.
As a quick example. With the key "catscatscatscats"
- The encryption of "mymessageiscool!" is 7560e6979e56348cfe27616e0ca8567b
- The encryption of "mymessageiscool?" is 59acdc0dbe8c2432c673bb05c2034c62
- See how the results are completely different even though the inputs are very similar? That's a security feature of AES!
- AES is secure in that if I gave you just "7560e6979e56348cfe27616e0ca8567b", you would have no idea what my original message was without the key. But if you had the key, you can recover the original message just by running the decryption algorithm
You might be wondering, if we have this perfect block encryption function, how could we possibly try to break any encryption? Didn't you say AES is unbreakable1?
Well let me ask you, you have this function that encrypts 16 bytes exactly, how do you encrypt more? How do you, for example, encrypt 100 bytes?
Block cipher modes are what allows you to do variable size encryption. Let's consider the most simple block cipher mode
Here's how you encrypt a variable number of bytes
- Add bytes to the end of the message in a special format so you know that you should remove it later
- Keep adding bytes until the message is a multiple of 16, this is called "padding"
- Split it into a bunch of 16 byte messages and encrypt them all
- Append it all together, and send it off
This is called Electronic Code Book, or ECB mode for short. It has a few glaring weaknesses, which you'll have to discover to solve the challenge!
- Take a look at this ECB mode visualizer and play around with it, it gives a simple UI for visualizing blocks of a message and the resulting blocks of the plaintext
- What happens when you edit half of a ciphertext? What does it decrypt to? What if you edit more/less of a block?
- What happens if you change the order of blocks?
- What exactly do you have to do to get the flag? What do you need to trick the server into thinking?
- Look at the challenge title! CTF challenges often hide little hints in the challenge titles
- In CTF challenges you should be constantly thinking about what you have control over, and how you can abuse this control. In this setup you have three things you can control
- The username and password you send when you register a user
- The bytes you send to the server when it asks for a token
- What happens if your token is incomplete? Will the server accept it? How badly can you mangle your token and still have the server be ok with it?
- The server uses
input()to get your username and password, so you're limited to normal alphanumeric and punctuation characters, you can't input arbitrary bytes in there. How can you work around this?
What can you do with this? How can you trick the server into encrypting something that you can use?
At least we sure hope so