Data Writeup - Crypto450
Райтап от тиммейта Swani.
Итак, перед нами текст задания и скрипт Data.py
Data.py:
import hashlib
import re
text = 'some message'
#formatKey:YearMonthDayHourMinutesSeconds
#OnlyNumbers
print('give me a key')
Key = input()
data = hashlib.sha256(Key.encode()).hexdigest()
for i in data:
result = re.findall('\d', data)
s = ' '.join([str(i) for i in result])
s = s.replace(' ', '')
lenght = len(s)
EM = s[0:lenght -2:]
for i in text:
m = ord(i)
r = 0
for r in range(0,len(text)):
q = int(EM[r:r+2:])
mes = q + m
if mes > 128:
les = mes - 128
les = chr(les)
r += 2
les = ":".join("{:02x}".format(ord(c)) for c in les)
print (les)
Анализирую скрипт, понимаем, что ключ выглядит следующим образом:
YearMonthDayHourMinutesSeconds
Из текста задания можно предположить, что год = 2056, месяц = 11, день = 12
Но, нам по прежнему неизвестны оставшиеся 6 чисел ключа.
Пробуем запустить скрипт Data.py с произвольными данными, предварительно вставив print
Для текста=’swani’ скрипт выдает 2e321c2924. Замечаем, что в выводе символов ровно в два раза больше, чем в исходном тексте.
Итого:
1) ключ - 20561112XXYYZZ – где XX – число от 0 до 3 (максимум 23 часа). YY и ZZ – числа от 0 до 9 (максимум 59 минут/секунд)
2) Шифротекст – 36 символов = 0d0f1803303b2633363632262d3c35354004
3) Исходный текст – 36/2=18 символов, про которые нам известно: FHQ(RRRRRRRRRRRRR), где R – любой символ.
Подумав пару часиков и перепробовав кучу разных вариантов, в непосильных умственных напряжениях был рожден следующий алгоритм:
1) брутим ключ
2) брутим исходное сообщение
Предположив, что 5 известных символов из исходного текста позволят сбрутить ключ, для начала, был сгенерирован список со всеми возможными ключами:
Key = '20561112'
key1 = []
def perm(n, seq):
for p in itertools.product(seq, repeat=n):
key1.append(("".join(p)))
perm(6, '0123456789')
Дальше проходимся по всему списку ключей, проверяем, что ключ удовлетворяет всем условиям, и вычисляем шифротекст для известных нам символов (FHQ(RRRRRRRRRRRRR)), сверяем его с соответствующим шифротекстом из задания, если все совпадает – то перед нами верный ключ.
Весь скрипт get_key.py:
import hashlib
import re
from itertools import permutations
import itertools
text = 'FHQ(AAAAAAAAAAAAA)'
#formatKey:YearMonthDayHourMinutesSeconds
#OnlyNumbers
print('give me a key')
Key = '20561112'
key1 = []
def perm(n, seq):
for p in itertools.product(seq, repeat=n):
key1.append(("".join(p)))
perm(6, '0123456789')
for key_ in key1:
if int(key_[0]) < 3 and int(key_[1]) < 4 and int(key_[2]) < 6 and int(key_[3]) < 10 and int(key_[4]) < 6 and int(key_[5]) < 10:
key_ = str(Key + str(key_))
if str(key_) == '20561112121212':
print '!!!!!!'
data = hashlib.sha256(key_.encode()).hexdigest()
for i in data:
result = re.findall('\d', data)
s = ' '.join([str(i) for i in result])
s = s.replace(' ', '')
lenght = len(s)
EM = s[0:lenght -2:]
les_res = ''
for lo in range(0,4):
les = ''
i = text[lo]
m = ord(i)
r = 0
for r in range(0,len(text)):
q = int(EM[r:r+2:])
mes = q + m
if mes > 128:
les = mes - 128
les = chr(les)
r += 2
les = ":".join("{:02x}".format(ord(c)) for c in les)
les_res += str(les)
if str(les_res) == '0d0f1803':
les = ''
i = text[len(text)-1]
m = ord(i)
r = 0
for r in range(0,len(text)):
q = int(EM[r:r+2:])
mes = q + m
if mes > 128:
les = mes - 128
les = chr(les)
r += 2
les = ":".join("{:02x}".format(ord(c)) for c in les)
if str(les) == '04':
print key_
print 'done'
Удивившись тому, что вместо одного ключа скрипт выдал
Дальше, зная ключ, мы можем сбрутить исходное сообщение. Берем используемый алфавит:
alph = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890()!@#$_%&*'
и в цикле шифруем каждую букву, тут же сравнивая результат с шифротекстом из задания, таким образом восстанавливаем все сообщение.
Скрипт get_answ.py:
import hashlib
import re
#formatKey:YearMonthDayHourMinutesSeconds
#OnlyNumbers
print('give me a key')
Key = '20561112022005'
res_text = '0d0f1803303b2633363632262d3c35354004'
text_ = ''
alph = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890()!@#$_%&*'
data = hashlib.sha256(Key.encode()).hexdigest()
for i in data:
result = re.findall('\d', data)
s = ' '.join([str(i) for i in result])
s = s.replace(' ', '')
lenght = len(s)
EM = s[0:lenght -2:]
fin = 0
while fin < 18:
prom = ''
for i in alph:
m = ord(i)
r = 0
for r in range(0,18):
q = int(EM[r:r+2:])
mes = q + m
if mes > 128:
les = mes - 128
les = chr(les)
r += 2
les = ":".join("{:02x}".format(ord(c)) for c in les)
if str(les) == str(res_text[fin*2]) + str(res_text[fin*2+1]):
prom += str(i) + ' | '
print prom
print '-------'
fin += 1
print '======='
print 'done'
Получаем ответ:
FLAG: FHQ(it_look_funny)
- Автор: drakylar
- Комментарии: 3
- Просмотры: 2738