Tyrannosaurus Rex - H@cktivityCon CTF

Category: Cryptography
Solves (at time of writing): 241
Description: We found this fossil. Can you reverse time and bring this back to life?

Tyrannosaurus Rex

We are given the following python script:


#!/usr/bin/env python

import base64
import binascii

h = binascii.hexlify
b = base64.b64encode

c = b'37151032694744553d12220a0f584315517477520e2b3c226b5b1e150f5549120e5540230202360f0d20220a376c0067'

def enc(f):
    e = b(f)
    z = []
    i = 0
    while i < len(e):
        z += [ e[i] ^ e[((i + 1) % len(e))]]
        i = i + 1
    c = h(bytearray(z))
    return c
    

We have encoded hex, and the function that encrypted it.

We can start by reversing the first step, unhexlifying the string back into a list of numbers we can loop over.


def dec(c):
    f = []
    for i in binascii.unhexlify(c):
        f.append(i)
    

Now we can take a look at the encryption algorithm.

First of all, the whole string is converted into base64 (line 12).

After that it's simple XOR, it XORS e[i] with e[i+1] into z (lets ignore the % len(e) for now.)

Since XORs reverse function is XOR, to reverse this we can do e[i+1]=e[i]^z to decode the string.

But to do that we'd need at least the first bit of data, the e[0].

Fortunately we know the flag format, and that it always starts with flag{!

So lets base64 encode that and get the first few characters from it.

The base64 representation of flag{ is ZmxhZ3s=, so lets take the Z and convert it into a number with the ord() function in python (90).

If we put everything I just said into a python script, the whole script would look like this:


#!/usr/bin/env python

import base64
import binascii

h = binascii.hexlify
b = base64.b64encode

c = b'37151032694744553d12220a0f584315517477520e2b3c226b5b1e150f5549120e5540230202360f0d20220a376c0067'

def enc(f):
    e = b(f)
    z = []
    i = 0
    while i < len(e):
        z += [ e[i] ^ e[((i + 1) % len(e))]]
        i = i + 1
    c = h(bytearray(z))
    return c

def dec(c):
    f = []
    for i in binascii.unhexlify(c):
        f.append(i)
    e = [90] + [None] * 47

    i=0
    while i < 47:
        e[i+1] = f[i]^e[i]
        i += 1

    n = "".join([chr(i) for i in e])

    return base64.b64decode(n.encode())

print(dec(c))
    

(The length 48 seen in lines 25 and 28 comes from len(f) after the unhexlify)

Run this, and we get b'flag{tyrannosauras_xor_in_reverse}'!

~sw1tchbl4d3, 03/08/2020 (dd/mm/yyyy)