# A delicious soup Crypto Challenge

## A delicious soup(crypto) - Asis Quals 2019

Hi everyone! C: This is a crypto challenge that I liked a lot and I was wanted to do my first post on my blog with this writeup, so finally now I have that :D

## So basically we have…

This flag encrypted:

``````11d.3ilVk_d3CpIO_4nlS.ncnz3e_0S}M_kn5scpm345n3nSe_u_S{iy__4EYLP_aAAall
``````

and this is the code that encrypted that:

``````import random
from flag import flag

def encrypt(msg, perm):
W = len(perm)
while len(msg) % (2*W):
msg += "."
msg = msg[1:] + msg[:1]
msg = msg[0::2] + msg[1::2]
msg = msg[1:] + msg[:1]
res = ""
for j in xrange(0, len(msg), W):
for k in xrange(W):
res += msg[j:j+W][perm[k]]
msg = res
return msg

def encord(msg, perm, l):
for _ in xrange(l):
msg = encrypt(msg, perm)
return msg

W, l = 7, random.randint(0, 1337)
perm = range(W)
random.shuffle(perm)

enc = encord(flag, perm, l)
f = open('flag.enc', 'w')
f.write(enc)
f.close()
``````

We need to reverse this code and create a decrypt function.

## Reversing…

• So, first lets check the initials lines: we have a 0 to 6 random list and a random number between 0 and 1337;
• The encord function call encrypt function L(random number(0,1337)) times;
• On encrypt function, the first while will just add 2 points on encrypted flag;
• The msg[1:] + msg[:1] will put the first char in the end;
• The msg[0::2] + msg[1::2] will split the msg and zip;
• The msg[1:] + msg[:1] will put the first char in the end again;
• The last double for will shuffle the msg with the random list logic.

## Solution…

The weakness of this crypto is that the key(The random list) has 5040 possibilities, so we just need to brute that C:

We can do it with itertools.permutations

## The Jurandir Solver

``````import itertools

def str_perm(flag, p):
res = ""

for j in xrange(0, 70, 7):
for k in xrange(7):
res += flag[j:j+7][p.index(k)]
return res

def shuf(flag):
flag = flag[-1:] + flag[:-1]
new = ""

for i, j in zip(flag[:len(flag)//2], flag[len(flag)//2:]):
new += i+j
flag = new
flag = flag[-1:] + flag[:-1]
return flag

def main():
perm = list(itertools.permutations([0,1,2,3,4,5,6]))

for idx, p in enumerate(perm):
flag = first_flag
print str(idx)+"/5040"

for _ in xrange(1337):
res = str_perm(flag, p)
res = shuf(res)

if res.startswith("ASIS{"):
print res
exit(1)
flag = res

if __name__ == "__main__":
main()
``````

Running the solver, after 805 iterations, we have the flag: ASIS{1n54n3ly_Simpl3_And_d3lic1Ous_5n4ckS_eVEn_l4zY_Pe0pL3_Can_Mak3}

 By: Lucas ~K4L1~ Nathaniel FireShell