pdfcrackを使ってパスワード付きPDFを解析する

はじめに

パスワード付きPDFを解析するコマンドがあるらしいとのことで使用してみる。
昔ダウンロードしたけど、パスワードがわからないIPAの成績照会のPDFとかあるのでそれも試してみる。 長そうなのでやめました。

環境

Windows 10 Professional
WSL2 - (Ubuntu22.04 LTS)
pdftk - pdftk port to java 3.2.2 a Handy Tool for Manipulating PDF Documents
pdfcrack version 0.19

準備

パスワード付きのPDFを用意する。

↓コマンドラインでできるらしいので準備する。

$ sudo apt-get install pdftk

Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
  alsa-topology-conf alsa-ucm-conf ca-certificates-java default-jre-headless java-common libapache-pom-java libasound2
  libasound2-data libbcprov-java libcommons-lang3-java libcommons-parent-java openjdk-11-jre-headless pdftk-java
Suggested packages:
  default-jre libasound2-plugins alsa-utils libbcprov-java-doc libcommons-lang3-java-doc fonts-dejavu-extra
  fonts-ipafont-gothic fonts-ipafont-mincho fonts-wqy-microhei | fonts-wqy-zenhei fonts-indic
The following NEW packages will be installed:
  alsa-topology-conf alsa-ucm-conf ca-certificates-java default-jre-headless java-common libapache-pom-java libasound2
  libasound2-data libbcprov-java libcommons-lang3-java libcommons-parent-java openjdk-11-jre-headless pdftk pdftk-java
0 upgraded, 14 newly installed, 0 to remove and 12 not upgraded.
Need to get 47.0 MB of archives.
After this operation, 180 MB of additional disk space will be used.
Do you want to continue? [Y/n] y

pdftk というのは PDFを加工するコマンドラインツール郡らしい。
poppler-utils と似ているやつかな
でも pdftk の方はめっちゃ古そう

何パターン化に分けて解析できるか試してみるので、複数ファイル用意する。

pdftk qrencode.pdf output secret1.pdf user_pw 1234
pdftk qrencode.pdf output secret2.pdf user_pw 12345
pdftk qrencode.pdf output secret3.pdf user_pw 123456
pdftk qrencode.pdf output secret4.pdf user_pw 1234567

※ブルートフォースで解析するらしいのであまり時間かからないくらいの桁数にしておく…。

pdfcrackのインストール

$ sudo apt-get install pdfcrack

pdfcrackコマンドを使ってパスワードを解析する

インストールが完了したら使い方を見てみる。

PDFCRACK(1)                                                                                             General Commands Manual                                                                                             PDFCRACK(1)

NAME
       pdfcrack - Password recovery tool for PDF-files

SYNOPSIS
       pdfcrack [ -f ] FILE [OPTION]...

DESCRIPTION
       PDFCrack is a tool for recovering passwords and content from PDF-files.

       If aborted with Ctrl-C or by receiving a SIGINT signal, pdfcrack will automatically save current position. The position will be saved in a file called savedstate.sav in current working directory.

       Mandatory arguments for long options are mandatory for short options too.

OPTIONS
       -b, --bench
              perform benchmark and exit

       -c, --charset=STRING
              Use the characters in STRING as charset

       -w, --wordlist=FILE
              Use FILE as source of passwords to try

       -n, --minpw=INTEGER
              Skip trying passwords shorter than INTEGER

       -m, --maxpw=INTEGER
              Stop when reaching this INTEGER passwordlength

       -l, --loadstate=FILE
              Continue from the state saved in FILE

       -o, --owner
              Work with the ownerpassword

       -u, --user
              Work with the userpassword (default)

       -p, --password=STRING
              Give userpassword to speed up breaking ownerpassword (implies -o)

       -q, --quiet
              Run quietly

       -s, --permutate
              Try permutating the passwords (currently only supports switching first character to uppercase)

       -v, --version
              Print version and exit

REPORTING BUGS
       Via e-mail to Henning Noren <confusion42@users.sourceforge.net> or report on project page at http://pdfcrack.sourceforge.net/

AUTHOR
       Henning Noren

COPYRIGHT
       Copyright © 2009 Henning Noren <confusion42@users.sourceforge.net>
       This is free software.  You may redistribute copies of it under the terms of the GNU General Public License <http://www.gnu.org/licenses/gpl.html>.  There is NO WARRANTY, to the extent permitted by law.

User Commands                                                                                                February 2009                                                                                                  PDFCRACK(1)
pdfcrack -f [ファイル]

で一番簡単に解析できるらしい。
オプション(条件)を付けるとおそらく解析が早くなる。
まずは、基本コマンドでやってみる。

$ pdfcrack -f secret1.pdf
PDF version 1.4
Security Handler: Standard
V: 2
R: 3
P: -3904
Length: 128
Encrypted Metadata: True
FileID: 38533b37ac18caf19a7fe39061aaaa39
U: 1c71bb32295aa522e20d6f95a9fca96e00000000000000000000000000000000
O: c48f001fdc79a030d718df5dbbdaad81d1f6fedec4a7b5cd980d64139edfcb7e
Average Speed: 49740.4 w/s. Current Word: 'sWjd'
Average Speed: 49676.4 w/s. Current Word: '7ouh'
Average Speed: 50056.7 w/s. Current Word: 'qQGl'
Average Speed: 49088.3 w/s. Current Word: 'nfOp'
Average Speed: 49028.4 w/s. Current Word: 'ZkVt'
Average Speed: 49059.6 w/s. Current Word: 'EA2x'
Average Speed: 49832.3 w/s. Current Word: 'ARdC'
Average Speed: 48662.0 w/s. Current Word: '02iG'
Average Speed: 49053.4 w/s. Current Word: 'GgqK'
Average Speed: 49446.2 w/s. Current Word: '5wzO'
Average Speed: 49473.4 w/s. Current Word: 'fWIS'
Average Speed: 49835.1 w/s. Current Word: '5dUW'
Average Speed: 49805.1 w/s. Current Word: 'em50'
found user-password: '1234'

できてますね…。 3分~5分くらいかかったのかな。
4桁だとまあまあ早いですね、何もしていないと長く感じたけど。

これって、ASCIIコード表の制御文字以外の文字列を総当りで探しているという感じなのかな。
ASCIIコード表: https://www.k-cube.co.jp/wakaba/server/ascii_code.html となると、 61文字?くらい だと 226,981通りを試している感じですかね。
まあ1~3文字で順々にやっていると思うので、 61 + 61^2 + 61^3 + 61^4 ですかね。 もう少し早くなるように文字種と文字数を限定してみる。

数字だけ + 桁数は4桁でやる。

$ pdfcrack -c 1234567890 -n 4 -f secret1.pdf
PDF version 1.4
Security Handler: Standard
V: 2
R: 3
P: -3904
Length: 128
Encrypted Metadata: True
FileID: 38533b37ac18caf19a7fe39061aaaa39
U: 1c71bb32295aa522e20d6f95a9fca96e00000000000000000000000000000000
O: c48f001fdc79a030d718df5dbbdaad81d1f6fedec4a7b5cd980d64139edfcb7e
found user-password: '1234'

え~一瞬で終わりました。

桁数指定だけにしておいてみるとどうなるか。

$ pdfcrack -n 4 -f secret1.pdf
PDF version 1.4
Security Handler: Standard
V: 2
R: 3
P: -3904
Length: 128
Encrypted Metadata: True
FileID: 38533b37ac18caf19a7fe39061aaaa39
U: 1c71bb32295aa522e20d6f95a9fca96e00000000000000000000000000000000
O: c48f001fdc79a030d718df5dbbdaad81d1f6fedec4a7b5cd980d64139edfcb7e
Average Speed: 48427.9 w/s. Current Word: '47de'
Average Speed: 48344.8 w/s. Current Word: 'bFhi'
Average Speed: 48062.9 w/s. Current Word: 'lJjm'
Average Speed: 48000.2 w/s. Current Word: 'gtlq'
Average Speed: 48023.8 w/s. Current Word: 'Oknu'
Average Speed: 47731.1 w/s. Current Word: 'WFny'
Average Speed: 47733.0 w/s. Current Word: 'G1nC'
Average Speed: 48011.7 w/s. Current Word: 'jPpG'
Average Speed: 47945.5 w/s. Current Word: 'BhrK'
Average Speed: 48654.3 w/s. Current Word: 'xqwO'
Average Speed: 46284.5 w/s. Current Word: '1epS'
Average Speed: 47960.8 w/s. Current Word: 'fMqW'
Average Speed: 48046.1 w/s. Current Word: 'ZKs0'
Average Speed: 47693.2 w/s. Current Word: 'UTs4'
found user-password: '1234'

何も指定なしの場合とあまり変わらず

さて、文字セットだけだとどうなるか。

$ pdfcrack -c 1234567890 -f secret1.pdf
PDF version 1.4
Security Handler: Standard
V: 2
R: 3
P: -3904
Length: 128
Encrypted Metadata: True
FileID: 38533b37ac18caf19a7fe39061aaaa39
U: 1c71bb32295aa522e20d6f95a9fca96e00000000000000000000000000000000
O: c48f001fdc79a030d718df5dbbdaad81d1f6fedec4a7b5cd980d64139edfcb7e
found user-password: '1234'

こちらも数字+4桁と同じ一瞬ですね。
当然ですが、計算量がかなり異なるからこうなっているのでしょう。
数字セットだと 10^1 + 10^2 + 10^3 + 10^4の通りだが、そうでない場合は、61^1 + 61^2 + 61^3 + 61^4 になる。

4桁より大きい桁数については、やっぱり実行しないことにした。長そうなので。
↓文字セットありの場合だけ試してみた。

$ pdfcrack -c 1234567890 -f secret2.pdf
PDF version 1.4
Security Handler: Standard
V: 2
R: 3
P: -3904
Length: 128
Encrypted Metadata: True
FileID: 22fb14942fd5b6c31f09c2e6a2191194
U: 2c9614c42edfa5cb20aad715007f579d00000000000000000000000000000000
O: 173764629e9066beb26f0debc7d0a71e40d386243bc28435cc9835f7bf552943
found user-password: '12345'
$ pdfcrack -c 1234567890 -f secret3.pdf
PDF version 1.4
Security Handler: Standard
V: 2
R: 3
P: -3904
Length: 128
Encrypted Metadata: True
FileID: fe9a337175d357694a1c511b3169f74f
U: 117e61fbd8f6c173da8b5199411affc400000000000000000000000000000000
O: c431fab9cc5ef7b59c244b61b745f71ac5ba427b1b9102da468e77127f1e69d6
found user-password: '123456'
$ pdfcrack -c 1234567890 -f secret4.pdf
PDF version 1.4
Security Handler: Standard
V: 2
R: 3
P: -3904
Length: 128
Encrypted Metadata: True
FileID: 360cb92bf2b2884c0396541bb8e2905c
U: 487baf3d912bc741490cf47a9cc8f17500000000000000000000000000000000
O: 78f12d9e4a28bd5883c16f3ae707a7c11b3dbc228635deff4af940c5dfffccde
Average Speed: 47540.7 w/s. Current Word: '418049'
Average Speed: 48124.7 w/s. Current Word: '7023191'
Average Speed: 48294.4 w/s. Current Word: '5919782'
Average Speed: 47308.2 w/s. Current Word: '8535283'
Average Speed: 48059.3 w/s. Current Word: '4456874'
Average Speed: 49028.2 w/s. Current Word: '9006675'
Average Speed: 47904.8 w/s. Current Word: '4015276'
found user-password: '1234567'

6桁から7桁になったら一気に遅くなった。
指数関数的にあがるからこれ以上は微妙そうですね。(それでも早いほうだが)
AtCoderなどの競技プログラミングのサイトでも 10^6 までの計算量がACになるのはそういうのが理由なのだろうか。
ちなみにこれを見た限りだと、文字コード順などで解析しているようではないみたい。
このあたり調べてみると面白そうだ。

参考

おわりに

pdfcrackでパスワード解析について学んだ。
イケナイことをしている感じがして良い。
悪用は厳禁ですね。
自分が所有しているPDFだけに使いましょう。

Hugo で構築されています。
テーマ StackJimmy によって設計されています。