Data Writeup - Crypto450

Райтап от тиммейта Swani.

Итак, перед нами текст задания и скрипт Data.py

Data Writeup - Crypto450

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'


Удивившись тому, что вместо одного ключа скрипт выдал херову кучу очень много ключей, несколько из них были проверенны с исходным текстом = ‘swani’, как итог – при всех найденных ключах шифротекст получился одинаковым. Отсюда следует, что для дальнейших действий можно брать любой из полученных ключей.

Дальше, зная ключ, мы можем сбрутить исходное сообщение. Берем используемый алфавит:

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'


Получаем ответ:

Data Writeup - Crypto450


FLAG: FHQ(it_look_funny)скачать dle 10.5фильмы бесплатно

  • Автор: drakylar
  • Комментарии: 3
  • Просмотры: 631

Добавить комментарий

Вы не авторизованы и вам запрещено писать комментарии. Для расширенных возможностей зарегистрируйтесь!
    • Написал: AseN
    • Комментарии: 4
    • 16 октября 2016 15:05
      • Нравится
      • 1
    К слову, таск можно было решить еще проще(без брута) - достаточно было заметить, что выходное значение упирается в конкретный байт входного сообщения(один и тот же), далее можно даже вручную за линейное время ;)
    • Написал: swani
    • Комментарии: 6
    • 21 октября 2016 10:51
      • Нравится
      • 0
    Цитата: AseN
    К слову, таск можно было решить еще проще(без брута) - достаточно было заметить, что выходное значение упирается в конкретный байт входного сообщения(один и тот же), далее можно даже вручную за линейное время ;)

    Это законно вообще?)
    • Написал: AseN
    • Комментарии: 4
    • 21 октября 2016 20:18
      • Нравится
      • 0
    Цитата: swani
    Цитата: AseN
    К слову, таск можно было решить еще проще(без брута) - достаточно было заметить, что выходное значение упирается в конкретный байт входного сообщения(один и тот же), далее можно даже вручную за линейное время ;)

    Это законно вообще?)

    Блин, мне казалось, что именно так и было задумано. По крайней мере, я так и решил этот таск