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
CVE-2026-76070 — Investigación original y PoC no destructivo para un desbordamiento de búfer de pila pre-autenticación en la contraseña decodificada en Base64 en login.cgi de Netis NC63. | Kitploit
Herramientas/GitHubGitHub/ozcanpng/cve-2026-76070
Seguridad de Sistemas EmbebidosSeguridad IoTAnálisis de VulnerabilidadesExplotaciónIngeniería InversaAnálisis de FirmwareExplotación de Binarios
GitHubozcanpng/cve-2026-76070

CVE-2026-76070

Investigación original y PoC no destructivo para un desbordamiento de búfer de pila pre-autenticación en la contraseña decodificada en Base64 en login.cgi de Netis NC63.

Ver Repositorio
1hace 4 díasAú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

CVE-2026-76070: Desbordamiento de búfer en la pila no autenticado previo a la autenticación mediante la contraseña decodificada en Base64 en el login.cgi de Netis NC63 que conduce a RCE

Investigador: Özcan Ersan (@ozcanpng)

Estado de divulgación

  • CVE: CVE-2026-76070
  • Proveedor: Netis Systems Co., Ltd.
  • Producto: Netis NC63 Wireless AC1200 Router
  • Firmware probado: NC63_V3.0.0.3327
  • Componente afectado: /bin/netis.cgi
  • Endpoint: POST /cgi-bin/login.cgi
  • Parámetro: password codificado en Base64
  • Autenticación: ninguna; la decodificación insegura ocurre antes de la comparación de credenciales
  • Arquitectura: MIPS32r2 little-endian, o32 ABI, uClibc
  • Clase de vulnerabilidad: desbordamiento de búfer en la pila con control de la dirección de retorno guardada
  • Validación: CGI de producción con hash original en un entorno de ejecución aislado en modo usuario de QEMU
  • Estado del registro CVE en la preparación: asignado; detalles del registro CNA pendientes de completar

Resumen ejecutivo

El manejador público de inicio de sesión del firmware Netis NC63 V3.0.0.3327 recupera el parámetro password controlado por el atacante y lo decodifica con la rutina Base64 personalizada FUN_00402bd4. El llamador proporciona un búfer local de pila de 64 bytes, pero no pasa su capacidad al decodificador. El decodificador deriva su trabajo de la entrada codificada y escribe los bytes decodificados sin comprobar el final del destino.

La dirección de retorno MIPS guardada está a 136 bytes del comienzo del búfer decodificado. Las pruebas dinámicas contra el CGI de producción con hash original confirmaron:

  1. un patrón decodificado de 140 bytes de B produce una falla en 0x42424242;
  2. reemplazar el ra guardado con 0x0041a2e0 provoca una segunda entrada observada en el manejador de inicio de sesión, lo que demuestra el control del contador de programa; y
  3. una prueba aislada solo de observación alcanza la llamada directa a system() del binario original con un valor a0 MIPS seleccionado por el atacante. El /bin/sh de reemplazo registró /bin/sh -c NC63_RCE_PROOF y no ejecutó ningún comando.

La PoC pública de este repositorio se detiene deliberadamente en un patrón de fallo. No contiene cadena de retorno, shellcode, comando, shell inversa ni persistencia.

Integridad de los artefactos afectados

root@kitploit:~
193f6a5e2ce65972b1805bf076f8d3521379a8441c8aaeb5ad0ba174bbee0792  netis_NC63_V3.0.0.3327.bin
23faa747b7d2f067aa5431bcc227ceca97a7977cf3e7c372f715cbba57f9209b  squashfs-root/bin/boa
eb298774c27070dc595fefcabb4e8c12a46cb5f4fd08f91c3ca92282c3a289a2  squashfs-root/bin/netis.cgi

La copia de /bin/netis.cgi probada dinámicamente tiene el mismo SHA-256 que el ejecutable extraído del proveedor.

Hash original y de tiempo de ejecución

Superficie de ataque y estado de autenticación

El frontend del proveedor envía la contraseña al endpoint público como Base64:

root@kitploit:~
obj.password = base64encode(utf16to8(password));
request({
    url: "/cgi-bin/login.cgi",
    data: obj
});

El campo HTML usa maxlength="63", pero eso es solo una restricción del lado del navegador. Un cliente HTTP directo puede enviar un valor codificado más grande.

Solicitud del frontend y límite solo del cliente

login.cgi es necesariamente accesible antes de la autenticación. La decodificación insegura ocurre antes de que la contraseña decodificada se compare con la contraseña de administrador configurada. No se requiere una sesión válida, encabezado Cookie, encabezado Authorization ni contraseña correcta.

Trazado de origen a destino

root@kitploit:~
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

Código vulnerable

Pseudocódigo derivado de Ghidra, con nombres normalizados para facilitar la lectura:

root@kitploit:~
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;
}

Manejador de inicio de sesión vulnerable

El decodificador en FUN_00402bd4 recibe solo punteros de destino y origen. Su bucle avanza el puntero de destino y almacena hasta tres bytes decodificados por cada cuatro símbolos Base64. Ninguna comparación comprueba el destino contra decoded + 64.

Bucle de escritura del decodificador Base64 personalizado

Base64 es la transformación de entrada, no el defecto subyacente. La causa raíz es el desajuste entre la longitud decodificada controlada por el atacante y un destino de tamaño fijo cuya capacidad nunca se aplica. Para una entrada normal con relleno, cuatro caracteres codificados representan hasta tres bytes decodificados; por lo tanto, las comprobaciones del lado del servidor deben calcular y validar el tamaño decodificado antes de escribir.

Análisis de corrupción de la pila

FUN_0041a2e0 comienza en 0x0041a2e0 y crea un marco de 0xa8 bytes:

root@kitploit:~
0041a2e0  addiu sp,sp,-168
0041a2e4  sw    ra,164(sp)
0041a2e8  sw    s8,160(sp)
0041a2ec  move  s8,sp

El destino decodificado comienza en s8+0x1c; el s8 guardado y el ra guardado están en s8+0xa0 y s8+0xa4:

root@kitploit:~
decoded[64]  s8+0x1c   decoded offset 0
saved s8     s8+0xa0   decoded offset 132
saved ra     s8+0xa4   decoded offset 136

La distancia exacta de la dirección de retorno es 0xa4 - 0x1c = 0x88, es decir, 136 bytes.

Marco de pila y desplazamiento de ra guardado

Verificación dinámica

Sobrescritura de la dirección de retorno guardada

Un patrón decodificado de 140 bytes de B reemplazó la dirección de retorno guardada de cuatro bytes:

root@kitploit:~
--- SIGSEGV {si_signo=SIGSEGV, si_code=1, si_addr=0x42424242} ---
qemu: uncaught target signal 11 (Segmentation fault)

Fallo en la dirección de retorno seleccionada por el atacante

Control del contador de programa

Una entrada separada de 140 bytes estableció el ra guardado en 0x0041a2e0. El rastreo de CPU de QEMU registró una primera entrada ordinaria del manejador seguida de una segunda entrada con s8=0x41414141 y ra=0x0041a2e0.

Segunda entrada controlada del manejador

Límite de comando solo de observación

El binario original contiene un jal system directo en 0x0041a3cc. En la validación aislada privada, las instrucciones existentes de base fija cargaron un marcador en a0 y alcanzaron esa llamada. Se montó un programa estático de observación sobre /bin/sh; registró los argumentos del intérprete de comandos y no ejecutó nada:

root@kitploit:~
argv[0]=</bin/sh>
argv[1]=<-c>
argv[2]=<NC63_RCE_PROOF>
CONTROLLED_MARKER_REACHED
PASS: attacker-controlled a0 reached system() and /bin/sh argv.
PASS: the guard logged the request and executed no command.

Esto demuestra una primitiva de RCE en la ruta de código de producción aislada. No establece una fiabilidad de explotación idéntica en un router físico bajo su kernel implementado y su configuración de aleatorización de pila.

Contexto de privilegios y endurecimiento del binario

La configuración original de Boa especifica User root, Group root y una ruta CGI que contiene /bin y /web/cgi-bin. El ejecutable de producción es de base fija (0x00400000), no tiene canario de pila ni RELRO, y declara una pila GNU ejecutable con segmentos RWX.

Configuración de privilegios de Boa de producción

Estado de endurecimiento del binario

PoC pública segura

El script incluido usa por defecto el modo de ejecución en seco y solo genera un cuerpo de formulario Base64 que contiene 140 bytes de B después de la decodificación:

root@kitploit:~
python3 poc/poc.py

El envío requiere un objetivo autorizado explícito y --send:

root@kitploit:~
python3 poc/poc.py --target http://192.168.1.1 --send

Enviar el patrón puede hacer fallar el proceso CGI. Úselo solo en un entorno autorizado y desechable. La PoC no implementa la cadena de validación RCE privada.

Impacto

Una explotación exitosa puede ejecutar código o comandos seleccionados por el atacante en el contexto de gestión del router. Con la configuración original de Boa, ese contexto se ejecuta como root. Las consecuencias potenciales incluyen la divulgación de configuración y secretos, la manipulación de DNS/firewall/enrutamiento, la redirección de tráfico, la interrupción del servicio y el compromiso total del dispositivo.

Remediación

  1. Reemplace el decodificador personalizado con una API que acepte la capacidad de destino.
  2. Rechace la entrada cuya longitud decodificada calculada supere los 63 bytes, reservando espacio para un terminador.
  3. Valide la longitud y la sintaxis Base64 en el servidor antes de decodificar.
  4. Audite cada llamador de FUN_00402bd4.
  5. Recompile con canarios de pila, PIE, NX y RELRO.
  6. Ejecute los procesos CGI con privilegios mínimos.

Índice de evidencias

Consulte evidence/README.md para ver las capturas de pantalla y el mapeo de trazados. Los extractos normalizados de Ghidra se encuentran en attachments/decompiled-functions/.

Cronología de divulgación

  • 2026-08-16: descubrimiento y validación aislada del binario de producción completados.
  • Agosto de 2026: se reportó a VulnCheck.
  • 2026-08-20: VulnCheck asignó CVE-2026-76070 y autorizó la divulgación pública.
  • 2026-08-20: se publicó el paquete de divulgación pública.

Referencias

  • CVE-2026-76070
  • VulnCheck
  • Página de soporte de Netis NC63
  • CVE-2026-73673

No se flasheó ningún router físico. No se utilizó ningún comando shell real, shell inversa, persistencia, conexión externa, robo de credenciales ni operación destructiva de firmware.

Descargar herramienta