This is a small tool using Tinyscript and pypdf or pikepdf to bruteforce the password of a PDF given an alphabet (defaults to printables) and a length (default is 8).
$ pip install pypdf tinyscript
$ tsm pdf-password-bruteforcer
This is a small tool using Tinyscript and pypdf or pikepdf to bruteforce the password of a PDF given an alphabet (defaults to printables) and a length (default is 8).
$ pip install pypdf tinyscript
$ tsm pdf-password-bruteforcer
#!/usr/bin/python3 | |
from tinyscript import * | |
try: | |
import pikepdf | |
BACKEND = "pikepdf" | |
except ImportError: | |
import pypdf | |
BACKEND = "pypdf" | |
__author__ = "Alexandre D'Hondt" | |
__version__ = "1.4" | |
__copyright__ = ("A. D'Hondt", 2020) | |
__license__ = "gpl-3.0" | |
__examples__ = ["secret.pdf -p '[a-z0-9]{5}'"] | |
__doc__ = """ | |
*PDF Password Bruteforcer* allows to execute a bruteforce attack on a given PDF file, | |
setting a regular expression pattern for the target password. | |
""" | |
BANNER_FONT = "tombstone" | |
BANNER_STYLE = {'fgcolor': "lolcat"} | |
def bruteforce_pdf_password(path, regex): | |
if BACKEND == "pypdf": | |
with open(path, 'rb') as f: | |
reader = pypdf.PdfReader(f) | |
for p in ts.bruteforce_re(regex): | |
logger.debug(p) | |
try: | |
reader.decrypt(p) | |
len(reader.pages) | |
logger.success("FOUND: " + p) | |
return True | |
except pypdf.errors.FileNotDecryptedError: | |
pass | |
except Exception as e: | |
logger.exception(e) | |
break | |
else: | |
for p in ts.bruteforce_re(regex): | |
logger.debug(p) | |
try: | |
with pikepdf.open(path, password=p) as f: | |
logger.success("FOUND: " + p) | |
return True | |
except pikepdf._qpdf.PasswordError: | |
pass | |
except Exception as e: | |
logger.exception(e) | |
break | |
return False | |
if __name__ == '__main__': | |
parser.add_argument("file", type=ts.file_exists, help="encrypted PDF file") | |
parser.add_argument("-p", "--pattern", default="^[0-9a-zA-Z!-_]{1,8}", help="password pattern") | |
initialize(add_time=True, noargs_action="demo", action_at_interrupt="confirm") | |
logger.info("Starting PDF password bruteforce...") | |
logger.handlers[-1].terminator = "" | |
if not bruteforce_pdf_password(args.file, args.pattern): | |
logger.failure("Password not found") |
H4sICGaOFGIAA3Rlc3QucGRmAK2UTWgUSRTHPXmowx5EArIRSiSSBLLV1d3T0y1jdrUnk406JmbG | |
LxI/qrurk44zXWNNzZK4iiCCiHgQRQ+CelAPKnrwEEFQxEsOSlAPgt78APHiVd1dd2t6xt7OTlxz | |
sOlLv/q/V7//q3rdMZTN9eCfdNDx8tXsU4ChApkzAUEmA1BxqkIhsokgJTYG0BAZo1WoSsUw6O0F | |
NPQipZpM2RB4VTii1TU7vxSI8gCyWS0UECdTtWSqzUJBQ1GFerQDKo7Xyg5MNT/iSgAN0yqrcVey | |
RHlDnLkFKqDRUG4fdCaoKxprA2UFpr8Ay1dW4HKPpglkc1ZZxybhiCK/McQSOU+9gMyNJYD1JPBG | |
Go6Jcaim64qq4JSUweW1EzsubOleu/jo51s/w/yaw5XJk+1nNp94fhvVizRUMK5nNOuNIHkMEBXp | |
pIASWtq0d8ai9NwulRgvVIhLodkwsYmUaT1JAahQc0TUqKgEQL/SYGy83nOUC0qCcrlPrkQEzVKX | |
eTQ+oGbLANoWeNKQlBfypLoXWo0N1gWiOkS5zcoVFta7Z8berYT118f2/9hzr/hDfj6jZtMDytLf | |
Apf2czIVr6X+3983TcTUCwTd3b34lydL3x3fNR+o9RWYJHiz5XnyPVu+QHh+d++SlXD9/SPzwWMl | |
ST8IO2+O+v6BmQH983Lv7Ko7E8Pnz13paxsYDT/92f/Hg33jL95Xu+RMwB7NUnQ5WFCLsVFBkNAj | |
3ANoC+wcdaYfXr0+c2rrQ2X5m0dt9uNF/3lkma1QjYmxaibHBs/5reSZl5UdgZ1BZvXrfQcPnZl9 | |
69p/s7ZDXfWJpEQELPyqQE67V3MlYGcfP3BJqe05fnpabb+m5VZ8zM4u+/DBkJpiIEoy++nHUeei | |
3T347K8bhd+7EjyTnPpADrcKlPiBRiqlpaAP4xiW9zJaCf+NGUZLDKutOk1RW2KGrrXqzFadjq3W | |
3HlY0qbeErPSLXvgOXyCk6BEOWj8HEOfweho5JT1hS6fqsiLqzS+B7JwJOOmTFf3PExV00o7xE87 | |
HtYdxzB9zXIc0+rNYJ9SVfFVzTStFHFNz6CKmtIlsTSMidUrb/wwY7Juo2wh2E/rjY8uNOEiOgqs | |
Gibo6OgbzIF/AMArx2CPBgAA |
Hi @Paulemeister !
Thank you for reporting this.
I have made some changes to the bruteforce_re
function recently (when I figured out itertools.product2
caused an issue with concatenated ranges, e.g. [a-bA-B]
; this caused to generate the combinations of [a-b]
and [A-B]
).
Can you tell me if you use one of the latest versions of Tinyscript (>=1.24.13), please ?
Edit: I tested your use case ; it works as expected.
logger.handlers[-1].terminator = ""
.$ pdf-password-bruteforce -v test2.pdf -p "[A-Z]{2}"
[...]
12:34:56 [INFO] Starting PDF password bruteforce...
12:34:56 [SUCCESS] FOUND: AB
Btw, I am on Linux, but that shouldn't really matter with python. My tinyscript version is 1.24.14. Thanks for the quick response
I narrowed it down to PyPDF2. It isn't maintained since 2018. I went step by step with the python shell and got this error:
NotImplementedError: only algorithm code 1 and 2 are supported
So maybe i just gotta use pikepdf
@Paulemeister
You can try with version 1.3 ; it now supports pikepdf
as the backend for handling the input PDF.
tinyscript can't be installed on macos, win10 and ubuntu due to old pathlib dependency, see dhondta/python-tinyscript#24
Works fine on linux mint, thank you, now perhaps I'll get a result :D
i can't install , any help? i tried to install pip install PyPDF2 tinyscript
and i open gitbassh aswell and i tried
Caique@DESKTOP-BIOQSQO MINGW64 ~
$ pip install PyPDF2 tinyscript
Requirement already satisfied: PyPDF2 in c:\users\caique\appdata\local\programs\python\python39\lib\site-packages (2.11.2)
Collecting tinyscript
Using cached tinyscript-1.26.13.tar.gz (131 kB)
Preparing metadata (setup.py) ... error
error: subprocess-exited-with-error
× python setup.py egg_info did not run successfully.
│ exit code: 1
╰─> [12 lines of output]
Traceback (most recent call last):
File "", line 2, in
File "", line 14, in
File "c:\users\caique\appdata\local\programs\python\python39\lib\site-packages\setuptools_init_.py", line 12, in
from setuptools.extension import Extension
File "c:\users\caique\appdata\local\programs\python\python39\lib\site-packages\setuptools\extension.py", line 7, in
from setuptools.dist import _get_unpatched
File "c:\users\caique\appdata\local\programs\python\python39\lib\site-packages\setuptools\dist.py", line 16, in
import pkg_resources
File "c:\users\caique\appdata\local\programs\python\python39\lib\site-packages\pkg_resources.py", line 1479, in
register_loader_type(importlib_bootstrap.SourceFileLoader, DefaultProvider)
AttributeError: module 'importlib._bootstrap' has no attribute 'SourceFileLoader'
[end of output]
note: This error originates from a subprocess, and is likely not a problem with pip.
error: metadata-generation-failed
× Encountered error while generating package metadata.
╰─> See above for output.
note: This is an issue with the package mentioned above, not pip.
hint: See above for details.
Caique@DESKTOP-BIOQSQO MINGW64 ~
$
inn pip insstall
S C:\Users\Caique> pip install PyPDF2 tinyscript
Requirement already satisfied: PyPDF2 in c:\users\caique\appdata\local\programs\python\python39\lib\site-packages (2.11.2)
Collecting tinyscript
Using cached tinyscript-1.26.13.tar.gz (131 kB)
Preparing metadata (setup.py) ... error
error: subprocess-exited-with-error
× python setup.py egg_info did not run successfully.
│ exit code: 1
╰─> [12 lines of output]
Traceback (most recent call last):
File "", line 2, in
File "", line 14, in
File "c:\users\caique\appdata\local\programs\python\python39\lib\site-packages\setuptools_init_.py", line 12, in
from setuptools.extension import Extension
File "c:\users\caique\appdata\local\programs\python\python39\lib\site-packages\setuptools\extension.py", line 7, in
from setuptools.dist import _get_unpatched
File "c:\users\caique\appdata\local\programs\python\python39\lib\site-packages\setuptools\dist.py", line 16, in
import pkg_resources
File "c:\users\caique\appdata\local\programs\python\python39\lib\site-packages\pkg_resources.py", line 1479, in
register_loader_type(importlib_bootstrap.SourceFileLoader, DefaultProvider)
AttributeError: module 'importlib._bootstrap' has no attribute 'SourceFileLoader'
[end of output]
note: This error originates from a subprocess, and is likely not a problem with pip.
error: metadata-generation-failed
× Encountered error while generating package metadata.
╰─> See above for output.
note: This is an issue with the package mentioned above, not pip.
hint: See above for details.
PS C:\Users\Caique>
Hi @caiquediass
Did you pip install --upgrade setuptools
?
Yeah, just wasted time, only algorithm code 1 and 2 are supported. This PDF uses code 4
Who would hook every exception without even trying to filter their severity.
@enela This should be fixed with using pypdf
and the pypdf.errors.FileNotDecryptedError
exception.
As a warning for other users tinyscript
has an incredible number of dependencies so you may want to use a dedicated environment when installing it.
Here's a little dockerfile if anyone wants it. Just need to put the script in the same folder as this Dockerfile
# Build
FROM centos:7.9.2009
# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
ENV APP_HOME=/app
WORKDIR $APP_HOME
# install system dependencies
RUN yum update -y && \
yum install -y gcc python3 python3-pip python3-devel
RUN pip3 install --upgrade pip
# Install reqs and copy over files from context
COPY . $APP_HOME
RUN chmod +x $APP_HOME/*
RUN pip3 install pypdf tinyscript
docker build -t pdftool .
docker run --rm -it pdftool /bin/bash
>> python3 pdf-password-bruteforcer.py <filename>
Either I have brain-rot or the patterns don't work. Even testing a pdf with password "AB" and using the pattern "^[A-Z]{2}" doesn't work. Also the verbose output is very inconsistent. Sometimes the tried passwords are on new lines, sometimes it gets replaced on the same line. Thanks for the work though. Plus the help only shows with --help and not -h. and the help has the old alphabet/length stuff in it, which was removed