Cyber Sea Game 2017: addcrypto (50)

We are given a file, encrypt.py, which looks as follows.

import os
from flag import flag

message = os.urandom(8) + flag

cipher = ''
for i in range(0, len(message) - 1):
    cipher += chr((ord(message[i]) + ord(message[i+1]) + ord(message[i+1])) & 0xff)

print cipher.encode('hex')
# 4c8f7236c7b259b4e9b792929f2d59534437394530392a2547645958522d3d3b4e3e412c2f2a47314b604d483849342534413e516673

Each byte of the cipher is in form \((a+2b)\mod{256}\). Since finding \(a\), won't help us at this point because \(b\) will have two solutions, let's try find \(a\) instead. The problem states that the cipher already include the CS2017{<flag>} format, so we can find \(b\) for each byte by deciphering from the back. We assume the first character that we decipher (i.e. the last character of the cipher) is character }. Then, we can calculate \(a\), which will be the next \(b\) for the next character.

Here is the Python script to find the value of flag:

import string

cipher = '4c8f7236c7b259b4e9b792929f2d59534437394530392a2547645958522d3d3b4e3e412c2f2a47314b604d483849342534413e516673'.decode('hex')[::-1]
flag = ['}']
for c in cipher:
    cur = flag[-1]
    flag.append(chr(ord(c) - 2 * ord(cur) & 0xFF))

print(''.join(flag[::-1]))

Flag is: CS2017{original_crypto_often_has_vulnerability}

Related Posts

Cyber Sea Game 2017: rsa-8192 (200)
MeePwn CTF 2017: |\/|/-\T|-| (100)
Capture The Fun: Cyber Sea Game 2017
TUCTF 2017: Crypto Clock (300)
MeePwn CTF 2017: Simpler RSA (100)