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 |
@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>
Yeah, just wasted time,
only algorithm code 1 and 2 are supported. This PDF uses code 4Who would hook every exception without even trying to filter their severity.