# TAMUctf 18 - DESpicable me

by dp1
March 1, 2018

Looks like Gru needs a new encryption scheme to facilitate his communication with the criminal council.

Larry came up with a modified DES algorithm that he is pretty proud of…but this is Larry we are talking about.

Make sure you can actually decrypt the message.

Below is an encrypted communication between Gru and Larry used to test the algorithm. They used the following to encrypt the message.

`larrycrypt -R 4 -K "V3c70R" -m message`

Encrypted Bits: 000101 000000 100111 011001 101110 011101 001110 101111 010001 101111 110000 001001 110010 111011 110111 010001 000100 101011 100010 100010 000001 010100 001111 010010 111110 001110 000111

Being a reversing challenge, I first tried actually reversing it. Crypto algorithms are kind of boring when reversing though, especially unknown ones, so we moved on to other means to get to the flag. I made some assumptions that looked reasonable and made a bruteforce possible:

• that the encryption of each group of three input bytes was only dependent on previous bytes
• that after the first triplet that produces three output bytes all others would produce four
• that in each triplet other than the first the first character influenced the first output byte, the first and the second the second output byte, all three the full four byte output

Note that the solution is not necessarily unique when considering a prefix of the flag.

We had already obtained the first three bytes (`Gig`) with a bit of guessing, so with these considerations in mind, I wrote (not without some effort, I had to change my assumptions a few times) a bruteforce that in less than 15 minutes got us the flag:

``````import subprocess
import string
import random

alpha = [x for x in string.printable]
random.shuffle(alpha)

# Target string, without the first three octects which were bruteforced separately
target = '011001 101110 011101 001110 101111 010001 101111 110000 001001 110010 111011 110111 010001 000100 101011 100010 100010 000001 010100 001111 010010 111110 001110 000111'
target = target.split(' ')

def findThree(base):
global target
if len(target) < 4:
#print "At least four output bytes are required"
return []

first = []
for ch in alpha:
if ch == '"' or ch == '`': continue
out = subprocess.check_output('./larrycrypt -R 4 -K V3c70R -m "' + base + ch + 'aa"', shell=True).strip()
if out.split(' ')[-4] == target:
first.append(ch)
if len(first) == 0:
return []
# print "Possible first chars:", first
target = target[1:]

second = []
for f in first:
for ch in alpha:
if ch == '"' or ch == '`': continue
out = subprocess.check_output('./larrycrypt -R 4 -K V3c70R -m "' + base + f + ch + 'a"', shell=True).strip()
if out.split(' ')[-3] == target:
second.append(f + ch)
if len(second) == 0:
return []
# print "Possible two byte prefixes:", second
target = target[1:]

third = []
for s in second:
#print base + s
for ch in alpha:
if ch == '"' or ch == '`' or ch == '\\': continue
out = subprocess.check_output('./larrycrypt -R 4 -K V3c70R -m "' + base + s + ch + '"', shell=True).strip()
if out.split(' ')[-2] == target and out.split(' ')[-1] == target:
third.append(base + s + ch)
# print "Possible outputs:", third
return third

start = ['Gig']
while len(target) > 0:
out = []
for e in start:
t_target = target
out += findThree(e)
target = t_target

start = out
target = target[4:]
print out

print [x for x in out if x[-1] == '}']
``````

Which gave me `GigEm{I7's5ofLUFfy:)}"` as the flag.

``````dario@PC:~/desktop/ctf/tamu18/rev200\$ time python t1.py