Fancy Caesar Cipher
Challenge:
We RSA encrypted the flag, but forgot to save the private key. Is it possible to recover the flag without it?
Solution:
The challenge consisted of a Python script that utilized RSA to encrypt the flag and write the public key and ciphertext to the fancy_caesar.out file.
I reviewed the Python script and spotted one critical weakness within the encrypt()
function:
def encrypt(e, n, m):
return [((ord(c) ** e) % n) for c in m]
The for c in m
loop means the script is encrypting a single character at a time, which makes a brute-force attack against the ciphertext fairly trivial. I wrote a simple Python script to perform the following steps:
- Load the Public Key and ciphertext from fancy_caesar.out
- Create a lookup table containing every printable character along with its encrypted version, using the provided public key
- Parse the ciphertext one character at a time, find the associated plaintext via the lookup table and append the plaintext to the flag string
import re
from ast import literal_eval
with open("fancy_Caesar_Cipher.out") as f:
chall = f.read()
m = re.match(r'Generated key:\s+(?P<e>\d+)\s+(?P<n>\d+)\s+Encrypted flag:\s+(?P<c>[\[\]0-9,\s]+)', chall)
n = int(m.group('n'))
e = int(m.group('e'))
ciphertext = literal_eval(m.group('c'))
public_key = (e, n)
# Build a lookup table of encrypted printable chars
table = {}
for i in range(32, 127):
table[pow(i, public_key[0], public_key[1])] = chr(i)
# Loop through each character in the cipher text; get the plaintext from the lookup table and append it to 'flag'
flag = ""
for c in ciphertext:
if c in table:
flag += table[c]
print(flag)
Running my solution produced a partial flag, but the contents weren't readable:
$ python3 ./solve_fancy_caesar_cipher.py
flag{phwd_iodj_lv_phwd}
This appeared to be an additional layer of encryption on the flag, and this is where the reference to Caesar Cipher in the challenge name made sense. I dropped the flag into CyberChef and used the ROT-13 operation to cycle through the various alphabet shifts until something readable appeared after a shift of 23.
This completed the challenge with a final flag of flag{meta_flag_is_meta}
Leave a comment