The concept of a one-time pad was a fundamental core to early cryptography. Basically, a phrase is memorized by the various parties and when a message is sent, it is shifted with that phrase for each step. For example, if the phrase is apple
and the message is i like them
, then we add a
to i
to get j
and so on to eventually receive the encoded message.
More recently, a lot of malware engineers and bad software engineers used XORing to perform the same activity. Where the vulnerability lies and where we can create scripts to be useful is where the same key has been used multiple times. If multiple ascii-based strings have been XORed with the same ascii-based strings, we can brute the strings at the same time by XORing all of them with ascii values character by character.
The following script will take a list of XORed values from a file and brute them character by character.
Put a list of XORed phrases in a file. Place that file in the same folder as your script (or don't; it just makes it marginally easier if you do).
The script should look something like this:
import sys import string f = open("ciphers.txt", "r") MSGS = f.readlines() def strxor(a, b): if len(a) > len(b): return "".join([chr(ord(x) ^ ord(y)) for (x, y) in zip(a[:len(b)], b)]) else: return "".join([chr(ord(x) ^ ord(y)) for (x, y) in zip(a, b[:len(a)])]) def encrypt(key, msg): c = strxor(key, msg) return c for msg in MSGS: for value in string.ascii_letters: for value2 in string.ascii_letters: for value3 in string.ascii_letters: key = value+value2+value3 answer = encrypt(msg, key) print answer[3:]
This script is pretty straightforward. We open a file with the XORed values in them and split it by lines:
f = open("ciphers.txt", "r") MSGS = f.readlines()
We shamelessly use the industry standard XOR
python. Basically, this function equates two strings to the same length and XOR
them together:
def strxor(a, b): if len(a) > len(b): return "".join([chr(ord(x) ^ ord(y)) for (x, y) in zip(a[:len(b)], b)]) else: return "".join([chr(ord(x) ^ ord(y)) for (x, y) in zip(a, b[:len(a)])]) def encrypt(key, msg): c = strxor(key, msg) return c
We then run through all ascii values three times to get all the combinations from aaa
to zzz
for each line in the ciphers.txt
file. We assign the value of the ascii loops to the key each time:
for msg in MSGS: for value in string.ascii_letters: for value2 in string.ascii_letters: for value3 in string.ascii_letters: key = value+value2+value3
We then encrypt the line with the generated key and print it out. We can pipe this a file with ease, as we've shown throughout the module already:
answer = encrypt(msg, key) print answer[3:]