We are given the following Python code which encrypts two messages with the SAME KEY in AES Counter mode, we know of the the plaintexts.
from Crypto.Cipher import AES from Crypto.Util import Counter import os KEY = os.urandom(16) def encrypt(plaintext): cipher = AES.new(KEY, AES.MODE_CTR, counter=Counter.new(128)) ciphertext = cipher.encrypt(plaintext) return ciphertext.hex() test = b"No right of private conversation was enumerated in the Constitution. I don't suppose it occurred to anyone at the time that it could be prevented." print(encrypt(test)) with open('flag.txt', 'rb') as f: flag = f.read().strip() print(encrypt(flag))
Because the key is reused, it is actually fairly easy to decrypt the flag. (See here for someone who knows what they're on about, and a program to do it, but I'm going to do it in CyberChef.) If you're interested, it's called a known-plaintext attack.
Succinctly, because the key is reused in Counter mode:
But, we know
c2. So, we can work out the key as xor is commutative (a xor b == c, a xor c == b, etc.).
We then just need to xor this key with
c2 to get
p2 and the flag!
This can be shown as:
This is done in thisXOR(%7B'option':'UTF8','string':'No%20right%20of%20private%20conversation%20was%20enumerated%20in%20the%20Constitution.%20I%20don%5C't%20suppose%20it%20occurred%20to%20anyone%20at%20the%20time%20that%20it%20could%20be%20prevented.'%7D,'Standard',false)XOR(%7B'option':'Hex','string':'4b6f25623a2d3b3833a8405557e7e83257d360a054c2ea'%7D,'Standard',false)&input=NDY0ODUxNTIyODM4NjAzOTI2ZjQ0MjJhNGNhNmQ4MWIwMmYzNTFiNDU0ZTZmOTY4YTMyNGZjYzc3ZGEzMGNmOTc5ZWVjNTdjODY3NWRlM2JiOTJmNmMyMTczMDYwNzA2NjIyNjc4MGE4ZDQ1MzlmY2Y2N2Y5ZjU1ODlkMTUwYTZjNzg2NzE0MGI1YTYzZGUyOTcxZGMyMDlmNDgwYzI3MDg4MjE5NGYyODgxNjdlZDkxMGI2NGNmNjI3ZWE2MzkyNDU2ZmExYjY0OGFmZDBiMjM5YjU5NjUyYmFlZGM1OTVkNGY4NzYzNGNmN2VjNDI2MmY4Yzk1ODFkN2Y1NmRjNmY4MzZjZmU2OTY1MThjZTQzNGVmNDYxNjQzMWQ0ZDFiMzYxYw) recipe, and the flag is