Tokyo Western 2017 - My Simple Cipher -Write up
This my first cipher system. Can you break it?
my-simple-cipher.7z
We are given 2 files Encrypted.txt and cipher.py
Now we take a look at cipher.py file to see how the flag is encrypted
#!/usr/bin/python2
import sys
import random
key = sys.argv[1]
flag = '**CENSORED**'
assert len(key) == 13
assert max([ord(char) for char in key]) < 128
assert max([ord(char) for char in flag]) < 128
message = flag + "|" + key
encrypted = chr(random.randint(0, 128))
for i in range(0, len(message)):
encrypted += chr((ord(message[i]) + ord(key[i % len(key)]) + ord(encrypted[i])) % 128)
print(encrypted.encode('hex'))
Okay, after take a look, we know that:
1. len(key) = 13 and they should be in range(32,128) as well as the flag
2. len(flag) = 21
encrypted = chr(random.randint(0, 128)) and then
for i in range(0, len(message)):
encrypted += chr((ord(message[i]) + ord(key[i % len(key)]) + ord(encrypted[i])) % 128)
okay, so encrypted[0] = chr(random.randint(0,128)) = chr(124)
and then the encryption goes like
encrypted[i+1] = chr( ((ord(message[i] + ord(key[i % 13]) + ord(encrypted[i]) ) % 128 )
We can use known-plaintext attack to recover the key
I assume that the unknown characters in message is 'a'
So message = 'TWCTF{' + 'a'*14 + '}' + '|' + 'a'*13
It mean that we can recover the first-Sixth letters of flag by bruting from range(32,128)
from binascii import *
encrypted = unhexlify(format(int(open('encrypted.txt','r').read(),16),'x'))
plain ='TWCTF{'
key = ''
for i in range(0,6):
for char in range(32,128):
if encrypted[i+1] == chr( ((ord(plain[i]) + char) + ord(encrypted[i]) ) %128) :
key+= chr(char)
print key
Note that message[i] = encrypted[i+1]
okay , key = 'ENJ0YH'
we know that message = flag + '|' + key
-> message = 'TWCTF{' + 'a'*14 + '}' + '|' + 'ENJ0YH' + 'a'*7
message.index('}') = 20 % 13 = 7 -> we brute and get key[7] character
message.index('|') = 21 % 13 = 8 -> we brute and get key[8] character
message.index('E') = 22 % 13 = 9 -> we brute and get key[9] character
message.index('N') = 23 % 13 = 10-> we brute and get key[10] character
message.index('J') = 24 % 13 = 11 -> we brute and get key[11] character
message.index('0') = 25 % 13 == 12 -> we brutue and get key[12] character
Note that message[i] = encrypted[i+1]
Okay, so the only letter that we dont know is at index 6 , but we know that it is '0' or 'O' , i use 'O' and luckily, it is the missing letter
key = 'ENJ0YHOLIDAY!'
We got the key, we got the flag :D
flag: TWCTF{Crypto-is-fun!}
my-simple-cipher.7z
We are given 2 files Encrypted.txt and cipher.py
Now we take a look at cipher.py file to see how the flag is encrypted
#!/usr/bin/python2
import sys
import random
key = sys.argv[1]
flag = '**CENSORED**'
assert len(key) == 13
assert max([ord(char) for char in key]) < 128
assert max([ord(char) for char in flag]) < 128
message = flag + "|" + key
encrypted = chr(random.randint(0, 128))
for i in range(0, len(message)):
encrypted += chr((ord(message[i]) + ord(key[i % len(key)]) + ord(encrypted[i])) % 128)
print(encrypted.encode('hex'))
Okay, after take a look, we know that:
1. len(key) = 13 and they should be in range(32,128) as well as the flag
2. len(flag) = 21
encrypted = chr(random.randint(0, 128)) and then
for i in range(0, len(message)):
encrypted += chr((ord(message[i]) + ord(key[i % len(key)]) + ord(encrypted[i])) % 128)
okay, so encrypted[0] = chr(random.randint(0,128)) = chr(124)
and then the encryption goes like
encrypted[i+1] = chr( ((ord(message[i] + ord(key[i % 13]) + ord(encrypted[i]) ) % 128 )
We can use known-plaintext attack to recover the key
I assume that the unknown characters in message is 'a'
So message = 'TWCTF{' + 'a'*14 + '}' + '|' + 'a'*13
It mean that we can recover the first-Sixth letters of flag by bruting from range(32,128)
from binascii import *
encrypted = unhexlify(format(int(open('encrypted.txt','r').read(),16),'x'))
plain ='TWCTF{'
key = ''
for i in range(0,6):
for char in range(32,128):
if encrypted[i+1] == chr( ((ord(plain[i]) + char) + ord(encrypted[i]) ) %128) :
key+= chr(char)
print key
Note that message[i] = encrypted[i+1]
okay , key = 'ENJ0YH'
we know that message = flag + '|' + key
-> message = 'TWCTF{' + 'a'*14 + '}' + '|' + 'ENJ0YH' + 'a'*7
message.index('}') = 20 % 13 = 7 -> we brute and get key[7] character
message.index('|') = 21 % 13 = 8 -> we brute and get key[8] character
message.index('E') = 22 % 13 = 9 -> we brute and get key[9] character
message.index('N') = 23 % 13 = 10-> we brute and get key[10] character
message.index('J') = 24 % 13 = 11 -> we brute and get key[11] character
message.index('0') = 25 % 13 == 12 -> we brutue and get key[12] character
Note that message[i] = encrypted[i+1]
Okay, so the only letter that we dont know is at index 6 , but we know that it is '0' or 'O' , i use 'O' and luckily, it is the missing letter
key = 'ENJ0YHOLIDAY!'
We got the key, we got the flag :D
flag: TWCTF{Crypto-is-fun!}
Nhận xét
Đăng nhận xét