Skip to content
KitploitKITPLOIT
أدواتالمدونة
إرسال
أدواتالمدونة
إرسال

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

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

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

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
CVE-2021-34730 — Cisco RV110w UPnP تجاوز سعة المكدس | Kitploit
أدوات/GitHubGitHub/badmonkey7/cve-2021-34730
أمان الأنظمة المدمجةأمان إنترنت الأشياءتحليل الثغرات الأمنيةالاستغلالالهندسة العكسيةمصممي الأخطاءأمن الشبكاتاختراق الأجهزةتحليل البرامج الثابتةاستغلال الملفات الثنائية
GitHubbadmonkey7/cve-2021-34730

CVE-2021-34730

287منذ 4 سنواتتمت المراجعة من قبل Kitploit

الأكثر شعبية

عرض الكل →

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

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

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

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

Cisco RV110w UPnP تجاوز سعة المكدس

عرض المستودع

تحليل Cisco RV110W UPnP 0day

مقدمة

في الآونة الأخيرة، أصبح UPnP شائعًا، ولدي جهاز Cisco RV110W. في أغسطس 2021، أعلنت شركة Cisco رسميًا عن ثغرة يوم الصفر (0day) في سلسلة RV الخاصة بـ UPnP، لكن التفاصيل المحددة لم تُنشر. لذا أردت استخدام الجهاز لتصحيح واكتشاف هذه الثغرة. يمكن الاطلاع على الإعلان الرسمي للثغرة على الموقع الرسمي.

التحضيرات

أولاً، قم بتحديث البرنامج الثابت إلى أحدث إصدار 1.2.2.8. بعد ذلك، التحدي هو كيفية تصحيح الثغرة وتحديد موقعها. أولاً، حل مشكلة التصحيح، المهمة الأولى هي الحصول على شل الجهاز، لكن أحدث إصدار من البرنامج الثابت لا يوفر واجهة تصحيح. لقد حصلت على صلاحيات تصحيح أحدث إصدار من البرنامج الثابت باستخدام منفذ UART وتعديل حزمة البرنامج الثابت. الطريقة المحددة مذكورة في مقال سابق تصحيح أجهزة التوجيه - الحصول على شل.

التحضير للتصحيح

Cisco RV110W يعتمد على بنية mipsel، لذا نحتاج أولاً إلى إيجاد خادم gdb مناسب. يمكننا تجميعه بأنفسنا أو استخدام نسخة مجمعة من قبل الآخرين. هنا أوصي بـ gdb-static-cross.

تحديد موقع الثغرة

يشير الإعلان الرسمي إلى أن الثغرة موجودة في خدمة UPnP. أولاً، ادخل إلى لوحة الإدارة الخلفية، وفي الإعدادات الأساسية لجدار الحماية (Basic Settings) قم بتفعيل إعدادات UPnP.

Untitled

ثم قم بمسح المنافذ باستخدام nmap، ولم يتم العثور على منفذ UPnP، لكن الاختبار أظهر أن UPnP مفتوح بالفعل.

Untitled

هنا استخدمت UPnPy لاختبار الثغرة واستغلالها.

root@kitploit:~
import socket
msg = \
    b'M-SEARCH * HTTP/1.1\r\n' \
    b'HOST:239.255.255.250:1900\r\n' \
    b'ST:upnp:rootdevice\r\n' \
    b'MX:2\r\n' \
    b'MAN:"ssdp:discover"\r\n' \
    b'\r\n'

# Set up UDP socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
s.bind((b"192.168.2.100",23333)) #本机IP
s.settimeout(2)
s.sendto(msg, (b'239.255.255.250', 1900))
addr = ('192.168.2.1', 1900) # 网关IP
try:
    while True:
        data, addr = s.recvfrom(65507)
        print(addr,data)

except socket.timeout:
    pass

لقد وجدت أنه تم بالفعل الحصول على استجابة UPnP، وأن هناك عملية UPnP مقابلة في عمليات الجهاز.

Untitled

تحليل الخدمة

UPnP هو معيار بروتوكول عام، ومعظم الشركات المصنعة تطبقه وفقًا للمعيار، أي أن العديد من الإجراءات (actions) متطابقة، ولكن من الضروري أيضًا تحليل الخدمات التي يوفرها الجهاز لتسهيل تحديد الثغرة واستغلالها. تم استخدام UPnPy أيضًا لجمع المعلومات.

root@kitploit:~
import upnpy
import socket

import requests
from upnpy.ssdp.SSDPDevice import SSDPDevice
msg = \
    b'M-SEARCH * HTTP/1.1\r\n' \
    b'HOST:239.255.255.250:1900\r\n' \
    b'ST:upnp:rootdevice\r\n' \
    b'MX:2\r\n' \
    b'MAN:"ssdp:discover"\r\n' \
    b'\r\n'

# Set up UDP socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
s.bind((b"192.168.2.100",23333))
s.settimeout(2)
s.sendto(msg, (b'239.255.255.250', 1900))
addr = ('192.168.2.1', 1900)
data = b""
try:
    while True:
        data, addr = s.recvfrom(65507)
        print(addr,data)
except socket.timeout:
    pass

# data = b'HTTP/1.1 200 OK\r\nCache-Control: max-age=120\r\nDate: Fri, 01 Jan 2010 00:44:16 GMT\r\nExt: \r\nLocation: http://192.168.2.1:1780/InternetGatewayDevice.xml\r\nServer: POSIX UPnP/1.0 linux/5.70.48.16\r\nST: upnp:rootdevice\r\nUSN: uuid:31474a87-67ea-dae4-2f73-f157fb06d22b::upnp:rootdevice\r\n\r\n'
# data = b'HTTP/1.1 200 OK\r\nCache-Control: max-age=3600\r\nST: upnp:rootdevice\r\nUSN: uuid:824ff22b-8c7d-41c5-a131-8c3bad401726::upnp:rootdevice\r\nEXT:\r\nServer:  Unspecified, UPnP/1.0, Unspecified\r\nLocation: http://192.168.3.1:56688/rootDesc.xml\r\n\r\n'

device = SSDPDevice(addr, data.decode())
services = device.get_services()

services_id = [services[i].id.split(":")[-1] for i in range(len(services))]

for id in services_id:
    service = device[id]
    actions = service.get_actions()
    for action in actions:
        for argument in action.arguments:
            print(id,action.name,argument.name)

يمكن الحصول على سلسلة من معلومات الخدمة، جزء منها كما يلي:

root@kitploit:~
WANIPConn1 AddPortMapping NewRemoteHost
WANIPConn1 AddPortMapping NewExternalPort
WANIPConn1 AddPortMapping NewProtocol
WANIPConn1 AddPortMapping NewInternalPort
WANIPConn1 AddPortMapping NewInternalClient
WANIPConn1 AddPortMapping NewEnabled
WANIPConn1 AddPortMapping NewPortMappingDescription
WANIPConn1 AddPortMapping NewLeaseDuration
WANIPConn1 DeletePortMapping NewRemoteHost
WANIPConn1 DeletePortMapping NewExternalPort
WANIPConn1 DeletePortMapping NewProtocol
WANIPConn1 GetExternalIPAddress NewExternalIPAddress

يمكن تصنيف هذه الخدمات تقريبًا إلى خدمات من نوع get وخدمات من نوع set، بالإضافة إلى عدد قليل من خدمات الحذف (delete). نظرًا لأن أحد الأهداف الرئيسية لـ UPnP هو تعريض الأجهزة الداخلية للأجهزة الخارجية، يتطلب ذلك بعض التهيئة (مثل إعادة توجيه المنافذ). وبما أن التهيئة مطلوبة، فإن معلمات التهيئة والمعلومات ضرورية، وهذه المعلمات هي في الواقع معلمات خدمات set.

تحديد موقع الخدمة

نظرًا لأن الشركة المصنعة لم تنفذ جميع الخدمات، نحتاج إلى إجراء هندسة عكسية للبرنامج الثابت بأنفسنا. أولاً، حدد موقع upnp_mainloop.

Untitled

جميع منطق المعالجة يتم تنفيذه في upnp_dispatch. بعد المتابعة والتحليل، تم العثور على أجزاء معالجة طلبات SSDP و HTTP.

Untitled

يتوافق ssdp_process مع طلبات البحث M-Search أثناء العنونة، ويتوافق upnp_http_process مع معالجة طلبات HTTP. نظرًا لأن استدعاءات الخدمة العادية تكون عبر طلبات HTTP، فمن المحتمل أن upnp_http_process يحتوي على ثغرة. مثال على استدعاء الخدمة موضح في الشكل أدناه.

Untitled

في upnp_http_process، يتم استدعاء upnp_http_fsm_emgine.

Untitled

بعد المتابعة والتحليل، تم العثور على تنفيذ عدة دوال في off_45ab80.

Untitled

تتضمن هذه الدوال وظائف التهيئة وتحليل رأس البروتوكول، وآخر دالة هي upnp_http_fsm_dispatch، ويُعتقد أنها تنفذ دالة الخدمة المقابلة.

Untitled

بعد متابعة upnp_http_fsm_dispatch، تم العثور على استدعاء لدوال، لكن الاستدعاء يعتمد على a1 و a2، ولا يمكن تحديد الدالة المحددة التي يتم استدعاؤها، لذا يلزم التصحيح الديناميكي.

Untitled

إذا كان طلبًا عاديًا لعنونة SSDP، فسيتم استدعاء SUB_405B34 و description_process. وإذا كان طلبًا متعلقًا بالخدمة، فسيتم استدعاء soap_process. داخل soap_process، بناءً على معلومات رأس الطلب، يتم استدعاء query_process أو action_process.

Untitled

نركز بشكل أساسي على action_process. بناءً على رأس طلب استدعاء الخدمة، يُعتقد أن soap_control داخل action_process يتوافق مع استدعاء الخدمة.

Untitled

داخل soap_control، لا يزال التصحيح الديناميكي مطلوبًا لتحديد معلومات الدالة المحددة.

أخيرًا، من خلال التصحيح الديناميكي، تم تحديد أن sub_414C28 يتوافق مع إجراء AddPortMapping، وسلسلة استدعاء الدوال هي:

root@kitploit:~
sub_414c28->upnp_portmap_add->upnp_osl_nat_config->strcpy(stack overflow)

ومع ذلك، في upnp_portmap_add، تم التحقق من عنوان واجهة WAN الخاصة بالجهاز. نظرًا لعدم تكوين واجهة WAN أثناء الاختبار، تم تعيين عنوان IP لواجهة WAN مباشرة باستخدام nvram.

Untitled

عند حدوث تجاوز سعة المكدس، يجب التحكم في تدفق البرنامج للوصول إلى المربع الأحمر، لأن دالة المربع الأزرق ستصل إلى المكدس المتجاوز مما يؤدي إلى تعطل البرنامج قبل تنفيذ RCE. لذلك، يجب التحكم في قيمة *(a2+11) لتكون 0، ولحسن الحظ، هذه القيمة قابلة للتحكم.

Untitled

استغلال الثغرة

نظرًا لأن أحدث إصدار من البرنامج الثابت لا يحتوي على telnetd، يمكن إرسال شل عائدة (reverse shell) ثم تحميل utelnetd يدويًا، ثم تشغيل telnet.

display-exploit.gif

راجع طرق إرسال الشل العائدة

تنزيل الأداة