-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathxor.py
executable file
·86 lines (60 loc) · 2.08 KB
/
xor.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#!/usr/bin/env python3
# encoding: utf-8
"""
A tool designed to accept input and try all possible XOR keys of a given
length on the contents.
Pipe it to grep to avoid spamming your terminal :)
# Usage
python3 xor.py [--length LENGTH] [-x]
where
--length LENGTH set the length of the xor key (>= 1)
-x unhexlify the standard input before xor-ing
# What it does
- Read 1 line of input from stdin
- Unhexlify the input if [-x] flag is passed
- For all possible byte strings of length [--length]:
- XOR the input with the byte string, repeating the key if necessary
- Output a string "{key} -> {xor-output}"
where {key} is the hexlified xor key byte string
and {xor-output} is the hexlified result of xor-ing input and key
# Example
echo "ff00ff00" | python3 xor.py --length 4 -x | grep f00b4r
Examples:
Find strings that start with "X=" and follow with at least 4 digits:
cat file.xor \
| python3 xor.py --length 4 \
| grep -e '-> 583d\(3[[:digit:]]\)\{3,\}'
"""
import argparse
import itertools
import multiprocessing
class Config:
def __init__(self, args):
self.length = args.length
self.hex = args.hex
def parse_args() -> Config:
ap = argparse.ArgumentParser("xor.py", description="Try XOR keys")
ap.add_argument("--length", type=int, default=1)
ap.add_argument("-x", "--hex", action="store_true")
args = ap.parse_args()
return Config(args)
def read_input(cfg: Config) -> bytes:
if cfg.hex:
return bytes.fromhex(input())
else:
return input().encode()
def generate_xor_keys(config: Config):
for k in itertools.product(range(256), repeat=config.length):
yield bytes(k)
def xor(s: bytes, k: bytes) -> bytes:
xored = (s[i] ^ k[i % len(k)] for i in range(len(s)))
return bytes(xored)
def xor_and_print(inp: bytes, k: bytes):
xored = xor(inp, k)
print(f"{k.hex()} -> {xored.hex()}")
if __name__ == '__main__':
args = parse_args()
inp = read_input(args)
iterable = generate_xor_keys(args)
with multiprocessing.Pool() as pool:
pool.map(lambda key: xor_and_print(inp, key), iterable)