English [MMA 2015] [Crypto/Warmup – Smart Cipher System] Write Up

Description

Decrypt 4 flags.

Resolution

 

#1 – crypt2.cgi

We started to encode the letter “A”, and “B” and we got:

A: 2a
B: 2b

Encoding value is the previous one + 1, so we deduced it was a simple Caesar cipher alternative with a shift of +23.
This is the PHP code we used:

$a = '36 36 2a 64 4b 4b 4a 21 1e 4b 1f 20 1f 21 4d 4b 1b 1d 19 4f 21 4c 1d 4a 4e 1c 4c 1b 22 4f 22 22 1b 21 4c 20 1d 4f 1f 4c 4a 19 22 1a 66';
$b = explode(' ', $a);
foreach ($b as $c) echo chr(hexdec($c)+23);

Flag is : MMA{bba85b6768db240f8c4ae3c29f9928c74f6ca091}

#2 – crypt4.cgi

We observed (like the Caesar above) the encoded string starts with the same character repeated 2 times.
It can be the “MM” part, as the flag should be something like “MMA{…}”.
Let’s try some encoding tests:

A: 83
B: 2c
ABC: 83 2c 1a

This time it was a mono alphabetic substitution cipher !
For solving it quickly we can write a little script to POST every letter of a defined charset and analyze the encoded response.
Charset was a mixalpha-numeric + “{” and “}” : “ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789{}”.
We got the following table:

A= 83    G= a0    M= e3    S= ed    Y= cb    e= 4d    k= 7f    q= a3    w= f5    2= 23    8= 07
B= 2c    H= 52    N= 2f    T= 20    Z= be    f= 33    l= 50    r= 40    x= bc    3= c3    9= 12
C= 1a    I= 3b    O= 84    U= fc    a= ef    g= 85    m= 3c    s= 8f    y= b6    4= 18    {= 21
D= 1b    J= d6    P= 53    V= b1    b= aa    h= 45    n= 9f    t= 92    z= da    5= 96    }= ff
E= 6e    K= b3    Q= d1    W= 5b    c= fb    i= f9    o= a8    u= 9d    0= 04    6= 05
F= 5a    L= 29    R= 00    X= 6a    d= 43    j= 02    p= 51    v= 38    1= c7    7= 9a

Flag is : MMA{f52da776412888170f282a9105d2240061c45dad}

#3 – crypt5.cgi

We first observed when we typed a unique letter, the result given by the script is the letter  (XOR) 1.
For example with the letter “A”, the result was “40”.
A in binary is 01000001, 1 in binary is 00000001 .
01000001 00000001 = 01000000, 40 in hexadecimal.

For the letter “B”, the result was “43”.
B in binary is 01000010, 1 in binary is 00000001 .
01000010 00000001 = 01000011, 43 in hexadecimal.

When there are 2 identical letters, the result is the letter 2, followed by 00.
For example with the letter “A”, the result was “43 00”.
A in binary is 01000001, 2 in binary is 00000010.
01000001 00000010 = 01000011, 43 in hexadecimal.

We deduced the script XOR the first letter with the message length and then XOR the next letter with the previous one.

Another example with the string “abcde” whose length is 5:
“abcde” in binary is 01100100 00000011 00000001 00000111 00000001
first letter 5 = 01100001 = a
then 00000011 01100001 = 01100010 = b
then 00000001 01100010 = 01100011 = c
etc …
We obtained:
MMA{e75fd59d2c9f9c227d28ff412c3fea3787c1fe73}

#4 – crypt6.cgi

This coding was not easy to understand.
What we observed is for each letter of clear text, there was a letter in the crypted one which depends uniquely of the clear one, even if they’re not at the same position.

Examples :

A    -> 28          (A egals 28)
AB   -> 28 84       (A is still 28)
ABC  -> 84 28 0d    (A is still 28, B still 84)
ABCD -> 84 0d 28 22 (A is still 28, B still 84, C still 0d)

etc…

If we pass the message MMA{AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA} (we might think the answer is formed on this pattern), we can affirm that the ciphered letters corresponding to MMA{} will be right placed compared with cipher.

Let’s try :

MMA{AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA} -> 82 a9 82 28 82 0a 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 a9 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 f6 82 82 82 82 fa

And if we compare cipher and result we have

82 a9 82 28 82 0a 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 a9 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 f6 82 82 82 82 fa
62 a9 6c 28 0e 33 31 c6 68 cd 66 66 59 46 cc 53 0c 98 31 65 c6 35 c9 a9 60 4e 37 b0 33 46 0d 60 46 26 66 33 cc e6 a9 f6 6c 07 2b 23 af
.. a9 .. 28 .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. a9 .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. f6 .. .. .. .. ..

4 letters out of 5 might be MMA{

Now let’s try to test every letter/number possible at first position : MMA{[a-f][0-9]AAA….A}

MMA{aAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA} -> 82 a9 82 28 82 0b 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 a9 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 f6 82 82 82 82 fa
MMA{bAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA} -> 82 a9 82 28 82 13 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 a9 82 05 82 82 82 82 82 82 82 82 82 82 82 82 82 f6 82 82 82 82 fa
MMA{cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA} -> 82 a9 82 28 82 1b 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 a9 82 0a 82 82 82 82 82 82 82 82 82 82 82 82 82 f6 82 82 82 82 fa
MMA{dAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA} -> 82 a9 82 28 82 23 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 a9 82 14 82 82 82 82 82 82 82 82 82 82 82 82 82 f6 82 82 82 82 fa
MMA{eAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA} -> 82 a9 82 28 82 2b 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 a9 82 28 82 82 82 82 82 82 82 82 82 82 82 82 82 f6 82 82 82 82 fa
MMA{fAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA} -> 82 a9 82 28 82 33 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 a9 82 50 82 82 82 82 82 82 82 82 82 82 82 82 82 f6 82 82 82 82 fa
MMA{0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA} -> 82 a9 82 28 82 81 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 a9 82 41 82 82 82 82 82 82 82 82 82 82 82 82 82 f6 82 82 82 82 fa
MMA{1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA} -> 82 a9 82 28 82 89 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 a9 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 f6 82 82 82 82 fa
...
MMA{9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA} -> 82 a9 82 28 82 c9 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 a9 82 82 82 82 82 82 82 82 82 82 82 82 82 82 82 f6 82 82 82 82 fa

We observe that 2 columns are modified (the 6th and the 26th), one “regularly” (the 6th). The 6th ciphered byte is 0x33, and 0x33 is present at 6th columns for the letter “f”, so we deduce f is the first letter of the flag.

So, a (little) bruteforce can be done in order to determine letter by letter which one is modified in the cipher and which letter corresponds to the letter at right position in the message we must decrypt.

Here is a little block of Python code in order to manually bruteforce every letter :


c = pycurl.Curl()
c.setopt(c.URL, 'http://bow.chal.mmactf.link/~scs/crypt6.cgi')
c.setopt(c.WRITEFUNCTION, body.store)

print('. => 62 a9 6c 28 0e 33 31 c6 68 cd 66 66 59 46 cc 53 0c 98 31 65 c6 35 c9 a9 60 4e 37 b0 33 46 0d 60 46 26 66 33 cc e6 a9 f6 6c 07 2b 23 af')
print()
s = 'MMA{f9cf7a3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA}'
cur = 10
for i in list(range(48,58)) + list(range(97,103)) :
  s = s[:cur]+chr(i)+s[cur+1:]
  c.setopt(c.POSTFIELDS,urlencode({'s': s}))
  c.perform()
  matches = re.search('</h1>


(.*)<form',body.contents) print(chr(i)+' => '+matches.group(1))
  body.clear()

We obtained, after 40 manual iterations on the previous code :
MMA{f9cf7a3ddd5710e85116814fef01c907f4df35ce}

2 thoughts on “[MMA 2015] [Crypto/Warmup – Smart Cipher System] Write Up”

Leave a Reply to Raizen Cancel reply

Your email address will not be published. Required fields are marked *