Cyber Sea Game 2017: addcrypto (50)
Wed 29 November 2017 ·
< 1 min read
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}