Skip to content
KitploitKITPLOIT
HerramientasExploitsBlog
Log in
Enviar
HerramientasExploitsBlog
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-2021-3156-Heap-Based-Buffer-Overflow-in-Sudo-Baron-Samedit- — Análisis técnico y desarrollo de exploits para CVE-2021-3156, un desbordamiento de búfer basado en montón en Sudo, incluyendo tres exploits funcionales para escalada local de privilegios en las principales distribuciones de Linux. | Kitploit
Herramientas/GitHubGitHub/sornphut/cve-2021-3156-heap-based-buffer-overflow-in-sudo-baron-samedit-
Escalada de PrivilegiosAnálisis de VulnerabilidadesExplotaciónPruebas de PenetraciónPapers e InvestigaciónAprendizaje y EducaciónExplotación de Binarios
GitHub

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
sornphut/cve-2021-3156-heap-based-buffer-overflow-in-sudo-baron-samedit-

CVE-2021-3156-Heap-Based-Buffer-Overflow-in-Sudo-Baron-Samedit-

Análisis técnico y desarrollo de exploits para CVE-2021-3156, un desbordamiento de búfer basado en montón en Sudo, incluyendo tres exploits funcionales para escalada local de privilegios en las principales distribuciones de Linux.

Ver Repositorio
13hace 1 añoAún no revisado

Aviso de seguridad de Qualys

Baron Samedit: Desbordamiento de búfer basado en montón en Sudo (CVE-2021-3156)

======================================================================== Contenido

Resumen Análisis Explotación Agradecimientos Cronología

======================================================================== Resumen

Descubrimos un desbordamiento de búfer basado en montón en Sudo (https://www.sudo.ws/). Esta vulnerabilidad:

  • es explotable por cualquier usuario local (usuarios normales y usuarios del sistema, sudoers y no sudoers), sin autenticación (es decir, el atacante no necesita conocer la contraseña del usuario);

  • se introdujo en julio de 2011 (commit 8255ed69) y afecta a todas las versiones heredadas de 1.8.2 a 1.8.31p2 y a todas las versiones estables de 1.9.0 a 1.9.5p1, en su configuración predeterminada.

Desarrollamos tres exploits diferentes para esta vulnerabilidad y obtuvimos privilegios de root completos en Ubuntu 20.04 (Sudo 1.8.31), Debian 10 (Sudo 1.8.27) y Fedora 33 (Sudo 1.9.2). Otros sistemas operativos y distribuciones probablemente también sean explotables.

======================================================================== Análisis

Si se ejecuta Sudo para lanzar un comando en modo "shell" (shell -c comando):

  • ya sea mediante la opción -s, que establece el flag MODE_SHELL de Sudo;

  • o mediante la opción -i, que establece los flags MODE_SHELL y MODE_LOGIN_SHELL de Sudo;

entonces, al comienzo de main() de Sudo, parse_args() reescribe argv (líneas 609-617), concatenando todos los argumentos de la línea de comandos (líneas 587-595) y escapando todos los metacaracteres con barras invertidas (líneas 590-591):


571 if (ISSET(mode, MODE_RUN) && ISSET(flags, MODE_SHELL)) { 572 char **av, *cmnd = NULL; 573 int ac = 1; ... 581 cmnd = dst = reallocarray(NULL, cmnd_size, 2); ... 587 for (av = argv; *av != NULL; av++) { 588 for (src = *av; src != '\0'; src++) { 589 / quote potential meta characters */ 590 if (!isalnum((unsigned char)*src) && *src != '_' && *src != '-' && *src != '$') 591 *dst++ = '\'; 592 *dst++ = *src; 593 } 594 dst++ = ' '; 595 } ... 600 ac += 2; / -c cmnd */ ... 603 av = reallocarray(NULL, ac + 1, sizeof(char *)); ... 609 av[0] = (char )user_details.shell; / plugin may override shell */ 610 if (cmnd != NULL) { 611 av[1] = "-c"; 612 av[2] = cmnd; 613 } 614 av[ac] = NULL; 615 616 argv = av; 617 argc = ac; 618 }

Más adelante, en sudoers_policy_main(), set_cmnd() concatena los argumentos de la línea de comandos en un búfer basado en montón "user_args" (líneas 864-871) y desescapa los metacaracteres (líneas 866-867), "para fines de coincidencia y registro de sudoers":


819 if (sudo_mode & (MODE_RUN | MODE_EDIT | MODE_CHECK)) { ... 852 for (size = 0, av = NewArgv + 1; *av; av++) 853 size += strlen(*av) + 1; 854 if (size == 0 || (user_args = malloc(size)) == NULL) { ... 857 } 858 if (ISSET(sudo_mode, MODE_SHELL|MODE_LOGIN_SHELL)) { ... 864 for (to = user_args, av = NewArgv + 1; (from = *av); av++) { 865 while (*from) { 866 if (from[0] == '\' && !isspace((unsigned char)from[1])) 867 from++; 868 *to++ = *from++; 869 } 870 *to++ = ' '; 871 } ... 884 } ... 886 }

Desafortunadamente, si un argumento de la línea de comandos termina con un solo carácter de barra invertida, entonces:

  • en la línea 866, "from[0]" es el carácter de barra invertida, y "from[1]" es el terminador nulo del argumento (es decir, no es un carácter de espacio);

  • en la línea 867, "from" se incrementa y apunta al terminador nulo;

  • en la línea 868, el terminador nulo se copia al búfer "user_args", y "from" se incrementa de nuevo y apunta al primer carácter después del terminador nulo (es decir, fuera de los límites del argumento);

  • el bucle "while" en las líneas 865-869 lee y copia caracteres fuera de los límites al búfer "user_args".

En otras palabras, set_cmnd() es vulnerable a un desbordamiento de búfer basado en montón, porque los caracteres fuera de los límites que se copian al búfer "user_args" no se incluyeron en su tamaño (calculado en las líneas 852-853).

En teoría, sin embargo, ningún argumento de la línea de comandos puede terminar con un solo carácter de barra invertida: si MODE_SHELL o MODE_LOGIN_SHELL está establecido (línea 858, una condición necesaria para alcanzar el código vulnerable), entonces MODE_SHELL se establece (línea 571) y parse_args() ya escapó todos los metacaracteres, incluidas las barras invertidas (es decir, escapó cada barra invertida con una segunda barra invertida).

En la práctica, sin embargo, el código vulnerable en set_cmnd() y el código de escape en parse_args() están rodeados por condiciones ligeramente diferentes:


819 if (sudo_mode & (MODE_RUN | MODE_EDIT | MODE_CHECK)) { ... 858 if (ISSET(sudo_mode, MODE_SHELL|MODE_LOGIN_SHELL)) {

versus:


571 if (ISSET(mode, MODE_RUN) && ISSET(flags, MODE_SHELL)) {

Nuestra pregunta, entonces, es: ¿podemos establecer MODE_SHELL y ya sea MODE_EDIT o MODE_CHECK (para alcanzar el código vulnerable) pero no el MODE_RUN predeterminado (para evitar el código de escape)?

La respuesta, al parecer, es no: si establecemos MODE_EDIT (opción -e, línea 361) o MODE_CHECK (opción -l, líneas 423 y 519), entonces parse_args() elimina MODE_SHELL de los "valid_flags" (líneas 363 y 424) y sale con un error si especificamos un flag no válido como MODE_SHELL (líneas 532-533):


358 case 'e': ... 361 mode = MODE_EDIT; 362 sudo_settings[ARG_SUDOEDIT].value = "true"; 363 valid_flags = MODE_NONINTERACTIVE; 364 break; ... 416 case 'l': ... 423 mode = MODE_LIST; 424 valid_flags = MODE_NONINTERACTIVE|MODE_LONG_LIST; 425 break; ... 518 if (argc > 0 && mode == MODE_LIST) 519 mode = MODE_CHECK; ... 532 if ((flags & valid_flags) != flags) 533 usage(1);

Pero encontramos una escapatoria: si ejecutamos Sudo como "sudoedit" en lugar de "sudo", entonces parse_args() establece automáticamente MODE_EDIT (línea 270) pero no restablece los "valid_flags", y los "valid_flags" incluyen MODE_SHELL de forma predeterminada (líneas 127 y 249):

Descargar herramienta