Files
crypto2025/long-secret-message/attack.py
2025-04-27 19:24:27 +02:00

212 lines
4.5 KiB
Python

#!/usr/bin/env python3
import numpy
from string import *
with open("./hacker-manifesto.enc") as f:
lines = f.readlines()
for i in range(len(lines)):
lines[i] = bytes.fromhex(lines[i])
#shortest_line = min(lines,key=len)
#min_len = len(shortest_line)
longest_line = max(lines, key=len)
max_len = len(longest_line)
candidates_list = []
CHARACTER_FREQ = {
'a': 0.0651738, 'b': 0.0124248, 'c': 0.0217339, 'd': 0.0349835, 'e': 0.1041442, 'f': 0.0197881, 'g': 0.0158610,
'h': 0.0492888, 'i': 0.0558094, 'j': 0.0009033, 'k': 0.0050529, 'l': 0.0331490, 'm': 0.0202124, 'n': 0.0564513,
'o': 0.0596302, 'p': 0.0137645, 'q': 0.0008606, 'r': 0.0497563, 's': 0.0515760, 't': 0.0729357, 'u': 0.0225134,
'v': 0.0082903, 'w': 0.0171272, 'x': 0.0013692, 'y': 0.0145984, 'z': 0.0007836, ' ': 0.1918182
} # ','
for byte_to_guess in range(max_len):
#print(f"Byte num:{byte_to_guess}")
counters = numpy.zeros(256,dtype=float)
for guessed_byte in range(256):
for line in lines:
#print(f"Now line: {line}")
#line = bytes.fromhex(line)
if byte_to_guess >= len(line):
continue
if chr(line[byte_to_guess] ^ guessed_byte) in printable:
counters[guessed_byte] += CHARACTER_FREQ.get(chr(line[byte_to_guess] ^ guessed_byte).lower(),0)
max_match = max(counters)
match_list = [(counters[i],i) for i in range(256)]
ordered_match_list=sorted(match_list, reverse=True)
candidates = []
#for pair in ordered_match_list:
# if pair[0] < max_match * .95:
# break
# candidates.append(pair)
candidates_list.append(ordered_match_list)
keystream = bytearray()
for x in candidates_list:
keystream += x[0][1].to_bytes(1,byteorder='big')
from Cryptodome.Util.strxor import strxor
dec = keystream[0] ^ lines[0][0]
mask = dec ^ ord('T')
keystream[0] = keystream[0] ^ mask
dec1 = keystream[1] ^ lines[0][1]
mask = dec1 ^ ord('h')
keystream[1] = keystream[1] ^ mask
dec2 = keystream[2] ^ lines[0][2]
mask = dec2 ^ ord('i')
keystream[2] = keystream[2] ^ mask
dec3 = keystream[3] ^ lines[0][3]
mask = dec3 ^ ord('s')
keystream[3] = keystream[3] ^ mask
dec5 = keystream[5] ^ lines[0][5]
mask = dec5 ^ ord('i')
keystream[5] = keystream[5] ^ mask
pos=28
dec = keystream[pos] ^ lines[0][pos]
mask = dec ^ ord('o')
keystream[pos] = keystream[pos] ^ mask
l=4
pos=17
dec = keystream[pos] ^ lines[4][pos]
mask = dec ^ ord('s')
keystream[pos] = keystream[pos] ^ mask
l=4
pos=20
dec = keystream[pos] ^ lines[l][pos]
mask = dec ^ ord('w')
keystream[pos] = keystream[pos] ^ mask
l=1
pos=34
dec = keystream[pos] ^ lines[l][pos]
mask = dec ^ ord(' ')
keystream[pos] = keystream[pos] ^ mask
l=1
pos=36
dec = keystream[pos] ^ lines[l][pos]
mask = dec ^ ord(' ')
keystream[pos] = keystream[pos] ^ mask
l=1
pos=37
dec = keystream[pos] ^ lines[l][pos]
mask = dec ^ ord('s')
keystream[pos] = keystream[pos] ^ mask
l=1
pos=38
dec = keystream[pos] ^ lines[l][pos]
mask = dec ^ ord('e')
keystream[pos] = keystream[pos] ^ mask
l=1
pos=40
dec = keystream[pos] ^ lines[l][pos]
mask = dec ^ ord('v')
keystream[pos] = keystream[pos] ^ mask
l=2
pos=49
dec = keystream[pos] ^ lines[l][pos]
mask = dec ^ ord('r')
keystream[pos] = keystream[pos] ^ mask
l=2
pos=53
dec = keystream[pos] ^ lines[l][pos]
mask = dec ^ ord('b')
keystream[pos] = keystream[pos] ^ mask
l=2
pos=42
dec = keystream[pos] ^ lines[l][pos]
mask = dec ^ ord('w')
keystream[pos] = keystream[pos] ^ mask
l=2
pos=43
dec = keystream[pos] ^ lines[l][pos]
mask = dec ^ ord('a')
keystream[pos] = keystream[pos] ^ mask
l=2
pos=45
dec = keystream[pos] ^ lines[l][pos]
mask = dec ^ ord('n')
keystream[pos] = keystream[pos] ^ mask
l=0
pos=46
dec = keystream[pos] ^ lines[l][pos]
mask = dec ^ ord('o')
keystream[pos] = keystream[pos] ^ mask
l=1
pos=57
dec = keystream[pos] ^ lines[l][pos]
mask = dec ^ ord('t')
keystream[pos] = keystream[pos] ^ mask
l=1
pos=58
dec = keystream[pos] ^ lines[l][pos]
mask = dec ^ ord('i')
keystream[pos] = keystream[pos] ^ mask
l=1
pos=59
dec = keystream[pos] ^ lines[l][pos]
mask = dec ^ ord('n')
keystream[pos] = keystream[pos] ^ mask
l=1
pos=64
dec = keystream[pos] ^ lines[l][pos]
mask = dec ^ ord('t')
keystream[pos] = keystream[pos] ^ mask
l=1
pos=65
dec = keystream[pos] ^ lines[l][pos]
mask = dec ^ ord('h')
keystream[pos] = keystream[pos] ^ mask
l=1
pos=67
dec = keystream[pos] ^ lines[l][pos]
mask = dec ^ ord('u')
keystream[pos] = keystream[pos] ^ mask
for line in lines:
l = min(len(keystream),len(line))
print(strxor(line[:l],keystream[:l]))