## Inroduction

TAMU CTF 2018 - LarryCrypt

## Description

A binary executable called larrycrypt was provided.

./larrycrypt -R 4 -K “V3c70R” flag

## Writeup

We tried some input for the `larrycrypt`

binary and we noticed that it was always using `Mu`

as key, no matter what was the `-K`

parameter. It was likely some bug, but then the SimpleDES challenge we just solved came to our minds.

The binary was using the same key as the other challenge’s example. So we thought it was using the same algorithm, but it wasn’t the case.

Larrycrypt was using 6bit blocks for the ciphertext. The first block of ciphertext was the same as SimpleDES’s first 6bit of cyphertext when using the same key and the same number of rounds. With some more reverse engineering we figured out that larrycrypt was taking the first 12 bits of plaintext, splitting them into `L0`

and `R0`

, performing the round function and printing only the resulting `L1`

. So they were using the same round function.

But then the sequence changes, we take the `R`

output from the round function and use it as `L`

for the next round along with the next block of ciphertext.

This image shows an example on 3 blocks of data, the output cypertext is made of `cypher0`

, `cypher1`

. `L2`

won’t be printed

To decrypt this we need to bruteforce all the possible 6bit last blocks (`L2`

in the image), decrypt all the blocks and check if the plaintext is good use the previous des pyhton script and the bruteforce the plain text

## Scripts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

import simple_des
class SimplerDES(simple_des.SimpleDES):
def encrypt(self, data):
if len(data[0]) == 8:
data = simple_des.to_twelve(data)
result = []
for block in data:
a,b = self.split_block(block)
result.extend([a,b])
data = result
result = []
self.schedule_key(len(data))
Lr = data[0]
for i in range(0,len(data)-1):
Rr = data[i+1]
for r in range(self.rounds):
sk = self.subkeys[i][r]
Lr, Rr = self.round(sk, Lr, Rr)
result.append(Lr)
Lr = Rr
return result
def decrypt(self, data, last):
self.invert_key(len(data))
result = []
Lr = last
for i in range(len(data),0,-1):
i -=1 # hotfix
Rr = data[i]
for r in range(self.rounds):
sk = self.subkeys[i][r]
Lr, Rr = self.round(sk, Lr, Rr)
result.append(Lr)
Lr = Rr
result.reverse()
return result
import itertools
#fi = open('flags.txt','w')
ciphertext = ['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']
key = simple_des.ascii_to_bin("Mu")
f = SimplerDES(key, rounds=4)
for i in itertools.product('01', repeat=6):
decrypted = f.decrypt(ciphertext, ''.join(i))
l = ''.join(decrypted)
#fi.write(l+'\n')
if simple_des.bin_to_ascii(l[-8:]) == '}':
l = '010001'+l # fix the starting G :D
print(simple_des.bin_to_ascii(l))
#fi.close()