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:

  1. Load the Public Key and ciphertext from fancy_caesar.out
  2. Create a lookup table containing every printable character along with its encrypted version, using the provided public key
  3. 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.

alt

This completed the challenge with a final flag of flag{meta_flag_is_meta}

Published:

Updated:

Leave a comment