rgbCTF-2020

CTF Writeup - https://ctf.rgbsec.xyz/

Home Other writeups of rgbCTF-2020
14 July 2020

RubikCBC

by raghul-rajasekar

I implemented this really cool Rubiks CBC encryption algorithm and tested it on a document with my flag in it, but my dog ate my hard drive so I couldn’t decrypt the file :(

Luckily I backed up the encrypted file. Can you recover my data?

Files:

Solution

We are provided with the encrypted document and a README.txt file with the following information:


scramble("F", "OOOOOOOOOYYYWWWGGGBBBYYYWWWGGGBBBYYYWWWGGGBBBRRRRRRRRR") => "OOOOOOYYYYYRWWWOGGBBBYYRWWWOGGBBBYYRWWWOGGBBBGGGRRRRRR"

==============================================================

IV = "ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuv"
SCRAMBLE = D R2 F2 D B2 D2 R2 B2 D L2 D' R D B L2 B' L' R' B' F2 R2 D R2 B2 R2 D L2 D2 F2 R2 F' D' B2 D' B U B' L R' D'

==============================================================

This shows a sample use of the scramble function, an IV of length 54 and a series of moves typical for a Rubik’s cube algorithm. From the length of the strings, we can guess that each character corresponds to one of the 54 small squares on a Rubik’s cube. The given sample shows us the effect of turning the front face of one such Rubik’s cube clockwise (refer to https://ruwix.com/the-rubiks-cube/notation/ for a primer on the notation used for Rubik’s cubes). From the sample, I figured out that the mapping from string to Rubik’s cube is:

Mapping

Now, since we are given an IV and a series of moves, and also since the title of the challenge mentions “CBC”, the steps to decrypt the document are fairly clear:

The implementation of the scramble function was the hardest part, which is shown here:

 def scramble(move, cube): 
    rounds = 1 
    if len(move) > 1: 
        if move[1] == '\'': 
            rounds = 3 
        elif move[1] == '2': 
            rounds = 2 
    U = [20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9] 
    U1 = [0, 1, 2, 5, 8, 7, 6, 3] 
    D = [33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44] 
    D1 = [45, 46, 47, 50, 53, 52, 51, 48] 
    L = [0, 3, 6, 12, 24, 36, 45, 48, 51, 44, 32, 20] 
    L1 = [9, 10, 11, 23, 35, 34, 33, 21] 
    R = [53, 50, 47, 38, 26, 14, 8, 5, 2, 18, 30, 42] 
    R1 = [15, 16, 17, 29, 41, 40, 39, 27] 
    F = [6, 7, 8, 15, 27, 39, 47, 46, 45, 35, 23, 11] 
    F1 = [12, 13, 14, 26, 38, 37, 36, 24] 
    B = [2, 1, 0, 9, 21, 33, 51, 52, 53, 41, 29, 17] 
    B1 = [18, 19, 20, 32, 44, 43, 42, 30] 
    if move[0] == 'U': 
        old = U 
        old1 = U1 
    elif move[0] == 'D': 
        old = D 
        old1 = D1 
    elif move[0] == 'L': 
        old = L 
        old1 = L1 
    elif move[0] == 'R': 
        old = R 
        old1 = R1 
    elif move[0] == 'F': 
        old = F 
        old1 = F1 
    elif move[0] == 'B': 
        old = B 
        old1 = B1 
    else: 
        return 
    new = old[-rounds*3:] + old[:-rounds*3] 
    new1 = old1[-rounds*2:] + old1[:-rounds*2] 
    new = [cube[i] for i in new] 
    new1 = [cube[i] for i in new1] 
    cube = list(cube) 
    for i, c in zip(old, new): 
        cube[i] = c 
    for i, c in zip(old1, new1): 
        cube[i] = c 
    return ''.join(cube)

On deciphering the document, it turned out to be a PDF file with a QR code in it (which kind of seemed to be the theme of the whole CTF). Scanning it gives the flag.

Flag

rgbCTF{!IP_over_Avian_Carriers_with_QoS!}
tags: