
Netis NC63 login.cgi में प्री-ऑथ Base64-डिकोडेड पासवर्ड स्टैक बफ़र ओवरफ़्लो के लिए मूल शोध और PoC
login.cgi में Base64-डिकोडेड पासवर्ड के माध्यम से अनऑथेंटिकेटेड प्री-ऑथ स्टैक बफ़र ओवरफ़्लो जो RCE की ओर ले जाता हैशोधकर्ता: Özcan Ersan (@ozcanpng)
CVE-2026-76070NC63_V3.0.0.3327/bin/netis.cgiPOST /cgi-bin/login.cgipasswordNetis NC63 फ़र्मवेयर V3.0.0.3327 में सार्वजनिक लॉगिन हैंडलर
हमलावर-नियंत्रित password पैरामीटर प्राप्त करता है और उसे कस्टम
Base64 रूटीन FUN_00402bd4 से डिकोड करता है। कॉलर 64-बाइट का स्थानीय स्टैक
बफ़र प्रदान करता है, लेकिन डिकोडर को उसकी क्षमता नहीं देता। डिकोडर अपना
कार्य एन्कोडेड इनपुट से निकालता है और डिकोडेड बाइट्स को गंतव्य के अंत की
जाँच किए बिना लिखता है।
सेव किया गया MIPS रिटर्न एड्रेस डिकोडेड बफ़र की शुरुआत से 136 बाइट दूर है। मूल-हैश प्रोडक्शन CGI के विरुद्ध गतिशील परीक्षणों ने पुष्टि की:
B पैटर्न 0x42424242 पर फ़ॉल्ट उत्पन्न करता है;ra को 0x0041a2e0 से बदलने पर लॉगिन हैंडलर पर दूसरी प्रविष्टि
देखी जाती है, जो प्रोग्राम-काउंटर नियंत्रण सिद्ध करती है; औरsystem() कॉल तक
हमलावर-चयनित MIPS a0 मान के साथ पहुँचता है। प्रतिस्थापित
/bin/sh ने /bin/sh -c NC63_RCE_PROOF लॉग किया और कोई कमांड निष्पादित नहीं की।इस रिपॉज़िटरी में सार्वजनिक PoC जानबूझकर क्रैश पैटर्न पर रुकता है। इसमें
कोई रिटर्न चेन, शेलकोड, कमांड, रिवर्स शेल या पर्सिस्टेंस शामिल नहीं है।
poc/exploit-db/ में अलग से अनुरक्षित RCE स्क्रिप्ट Exploit-DB सबमिशन के लिए
तैयार है और केवल प्रभावित सिस्टमों के अधिकृत परीक्षण के लिए है।
193f6a5e2ce65972b1805bf076f8d3521379a8441c8aaeb5ad0ba174bbee0792 netis_NC63_V3.0.0.3327.bin
23faa747b7d2f067aa5431bcc227ceca97a7977cf3e7c372f715cbba57f9209b squashfs-root/bin/boa
eb298774c27070dc595fefcabb4e8c12a46cb5f4fd08f91c3ca92282c3a289a2 squashfs-root/bin/netis.cgi
The dynamically tested /bin/netis.cgi copy has the same SHA-256 as the
vendor-extracted executable.

The vendor frontend sends the password to the public endpoint as Base64:
obj.password = base64encode(utf16to8(password));
request({
url: "/cgi-bin/login.cgi",
data: obj
});
HTML फ़ील्ड maxlength="63" का उपयोग करता है, लेकिन यह केवल ब्राउज़र-पक्षीय
प्रतिबंध है। एक सीधा HTTP क्लाइंट एक बड़ा एन्कोडेड मान सबमिट कर सकता है।

login.cgi प्रमाणीकरण से पहले अनिवार्य रूप से पहुँच योग्य है। असुरक्षित डिकोड
डिकोड किए गए पासवर्ड की तुलना कॉन्फ़िगर किए गए
व्यवस्थापक पासवर्ड से होने से पहले होता है। किसी वैध सत्र, Cookie हेडर, Authorization हेडर,
या सही पासवर्ड की आवश्यकता नहीं है।
Unauthenticated HTTP client
|
| POST /cgi-bin/login.cgi
| password=<attacker-controlled Base64>
v
/bin/netis.cgi: FUN_0041a2e0
|
| get_request_param("password")
v
FUN_00402bd4(decoded_stack_buffer, encoded_password)
|
| no destination-capacity argument
| decoded output exceeds 64 bytes
v
saved s8 at decoded offset 132
saved ra at decoded offset 136
|
v
attacker-selected MIPS PC
Ghidra-व्युत्पन्न स्यूडोकोड, जिसमें पठनीयता के लिए नाम सामान्यीकृत किए गए हैं:
int login_cgi(void *request)
{
char decoded[64];
char stored[68];
char *password;
memset(decoded, 0, 64);
memset(stored, 0, 64);
password = get_request_param(request, "password");
if (password != NULL)
FUN_00402bd4(decoded, password); /* no capacity argument */
apmib_get(0x15e, stored);
if (strcmp(decoded, stored) == 0)
printf("[\"SUCCESS\"]");
else {
system("echo 0 >/tmp/boa_auth");
printf("[\"%d\"]", 0x15);
}
return 0;
}

FUN_00402bd4 पर डिकोडर केवल गंतव्य और स्रोत पॉइंटर प्राप्त करता है।
इसका लूप गंतव्य पॉइंटर को आगे बढ़ाता है और प्रत्येक चार Base64 प्रतीकों के लिए
अधिकतम तीन डिकोड किए गए बाइट्स संग्रहीत करता है। कोई भी तुलना गंतव्य की
decoded + 64 के विरुद्ध जाँच नहीं करती।

Base64 इनपुट रूपांतरण है, अंतर्निहित दोष नहीं। मूल कारण हमलावर-नियंत्रित डिकोड की गई लंबाई और एक निश्चित आकार के गंतव्य के बीच का मेल न होना है, जिसकी क्षमता कभी लागू नहीं की जाती। सामान्य पैडेड इनपुट के लिए, चार एन्कोडेड अक्षर अधिकतम तीन डिकोड किए गए बाइट्स को दर्शाते हैं; इसलिए सर्वर-साइड जाँचों को लिखने से पहले डिकोड किए गए आकार की गणना और सत्यापन करना चाहिए।
FUN_0041a2e0 0x0041a2e0 पर शुरू होता है और एक 0xa8-बाइट फ्रेम बनाता है:
0041a2e0 addiu sp,sp,-168
0041a2e4 sw ra,164(sp)
0041a2e8 sw s8,160(sp)
0041a2ec move s8,sp
डिकोड किया गया गंतव्य s8+0x1c से शुरू होता है; सहेजे गए s8 और सहेजे गए ra क्रमशः
s8+0xa0 और s8+0xa4 पर हैं:
decoded[64] s8+0x1c decoded offset 0
saved s8 s8+0xa0 decoded offset 132
saved ra s8+0xa4 decoded offset 136
सटीक return-address दूरी 0xa4 - 0x1c = 0x88 है, या 136 बाइट्स।

140-बाइट डिकोड किए गए B पैटर्न ने चार-बाइट saved return address को प्रतिस्थापित कर दिया:
--- SIGSEGV {si_signo=SIGSEGV, si_code=1, si_addr=0x42424242} ---
qemu: uncaught target signal 11 (Segmentation fault)

एक अलग 140-बाइट इनपुट सेट ने ra को 0x0041a2e0 पर सहेजा। QEMU CPU ट्रेसिंग ने एक सामान्य पहली हैंडलर प्रविष्टि दर्ज की, जिसके बाद s8=0x41414141 और ra=0x0041a2e0 के साथ दूसरी प्रविष्टि दर्ज की।
