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
|
#!/usr/bin/env python3
#
# This code is Public Domain.
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
# USE OR PERFORMANCE OF THIS SOFTWARE.
import pikepdf
import multiprocessing
import sys
import pathlib
from datetime import datetime, timedelta
class PwIteratorPLZ:
def __init__(self):
self.plz = 1000
def __iter__(self):
return self
def __next__(self):
plz = self.plz
if plz >= 99999:
raise StopIteration()
self.plz += 1
return f"{plz:05}"
class PwIteratorBirthday:
def __init__(self):
now = datetime.now()
self.date = datetime(year=now.year, month=now.month, day=now.day, hour=12)
self.enddate = self.date - timedelta(days=(120 * 365))
def __iter__(self):
return self
def __next__(self):
date = self.date
if date <= self.enddate:
raise StopIteration()
self.date -= timedelta(days=1)
return f"{date.day:02}.{date.month:02}.{date.year:04}"
def testit(password):
try:
with pikepdf.open(infile, password=password) as pdf:
pdf.save(outfile)
return password
except pikepdf.PasswordError:
return None
except Exception as e:
raise Exception(f"Error processing PDF file: {e}")
infile = pathlib.Path(sys.argv[1])
outfile = infile.with_stem(infile.stem + ".DECRYPTED")
iterators = (
PwIteratorBirthday,
PwIteratorPLZ,
)
for iterator in iterators:
with multiprocessing.Pool() as pool:
for pw in pool.imap(testit, iterator(), 128):
if pw is not None:
pool.terminate()
print(f"The PDF has been decrypted to: {outfile}")
print(f"The password is: {pw}")
sys.exit(0)
print("Password not found :(")
sys.exit(1)
# vim: ts=4 sw=4 expandtab
|