Skip to content
KitploitKITPLOIT
StrumentiExploitsBlog
Log in
Invia
StrumentiExploitsBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

FeedContattoPrivacy© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
Strumenti/GitHubGitHub/sornphut/cve-2021-3156-heap-based-buffer-overflow-in-sudo-baron-samedit-
Escalation di PrivilegiAnalisi delle VulnerabilitàExploitPenetration TestingPaper e RicercaApprendimento e FormazioneBinary Exploitation
GitHubsornphut/cve-2021-3156-heap-based-buffer-overflow-in-sudo-baron-samedit-

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

Analisi tecnica e sviluppo di exploit per CVE-2021-3156, un heap-based buffer overflow in Sudo, inclusi tre exploit funzionanti per l'escalation locale dei privilegi sulle principali distribuzioni Linux.

Vedi Repository
131 anno faNon ancora revisionato

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

Qualys Security Advisory

Baron Samedit: buffer overflow basato su heap in Sudo (CVE-2021-3156)

======================================================================== Indice

Sommario Analisi Sfruttamento Riconoscimenti Cronologia

======================================================================== Sommario

Abbiamo scoperto un buffer overflow basato su heap in Sudo (https://www.sudo.ws/). Questa vulnerabilità:

  • è sfruttabile da qualsiasi utente locale (utenti normali e utenti di sistema, sudoers e non sudoers), senza autenticazione (cioè l'attaccante non ha bisogno di conoscere la password dell'utente);

  • è stata introdotta nel luglio 2011 (commit 8255ed69) e interessa tutte le versioni legacy dalla 1.8.2 alla 1.8.31p2 e tutte le versioni stabili dalla 1.9.0 alla 1.9.5p1, nella loro configurazione predefinita.

Abbiamo sviluppato tre exploit diversi per questa vulnerabilità e ottenuto privilegi di root completi su Ubuntu 20.04 (Sudo 1.8.31), Debian 10 (Sudo 1.8.27) e Fedora 33 (Sudo 1.9.2). Probabilmente anche altri sistemi operativi e distribuzioni sono sfruttabili.

======================================================================== Analisi

Se Sudo viene eseguito per lanciare un comando in modalità "shell" (shell -c command):

  • tramite l'opzione -s, che imposta il flag MODE_SHELL di Sudo;

  • oppure tramite l'opzione -i, che imposta i flag MODE_SHELL e MODE_LOGIN_SHELL di Sudo;

allora, all'inizio della funzione main() di Sudo, parse_args() riscrive argv (righe 609-617), concatenando tutti gli argomenti della riga di comando (righe 587-595) e facendo l'escaping di tutti i metacaratteri con backslash (righe 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 }

Successivamente, in sudoers_policy_main(), set_cmnd() concatena gli argomenti della riga di comando in un buffer basato su heap "user_args" (righe 864-871) e rimuove l'escaping dei metacaratteri (righe 866-867), "per scopi di corrispondenza e registrazione 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 }

Purtroppo, se un argomento della riga di comando termina con un singolo carattere backslash, allora:

  • alla riga 866, "from[0]" è il carattere backslash e "from[1]" è il terminatore nullo dell'argomento (cioè non un carattere spazio);

  • alla riga 867, "from" viene incrementato e punta al terminatore nullo;

  • alla riga 868, il terminatore nullo viene copiato nel buffer "user_args" e "from" viene incrementato di nuovo e punta al primo carattere dopo il terminatore nullo (cioè fuori dai limiti dell'argomento);

  • il ciclo "while" alle righe 865-869 legge e copia caratteri fuori dai limiti nel buffer "user_args".

In altre parole, set_cmnd() è vulnerabile a un buffer overflow basato su heap, perché i caratteri fuori dai limiti copiati nel buffer "user_args" non erano inclusi nella sua dimensione (calcolata alle righe 852-853).

In teoria, tuttavia, nessun argomento della riga di comando può terminare con un singolo carattere backslash: se MODE_SHELL o MODE_LOGIN_SHELL è impostato (riga 858, condizione necessaria per raggiungere il codice vulnerabile), allora MODE_SHELL è impostato (riga 571) e parse_args() ha già effettuato l'escaping di tutti i metacaratteri, inclusi i backslash (cioè ha fatto l'escaping di ogni singolo backslash con un secondo backslash).

In pratica, però, il codice vulnerabile in set_cmnd() e il codice di escaping in parse_args() sono circondati da condizioni leggermente diverse:


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)) {

La nostra domanda, quindi, è: possiamo impostare MODE_SHELL e MODE_EDIT o MODE_CHECK (per raggiungere il codice vulnerabile) ma non il MODE_RUN predefinito (per evitare il codice di escaping)?

La risposta, a quanto pare, è no: se impostiamo MODE_EDIT (opzione -e, riga 361) o MODE_CHECK (opzione -l, righe 423 e 519), allora parse_args() rimuove MODE_SHELL dai "valid_flags" (righe 363 e 424) ed esce con un errore se specifichiamo un flag non valido come MODE_SHELL (righe 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);

Ma abbiamo trovato una scappatoia: se eseguiamo Sudo come "sudoedit" invece di "sudo", allora parse_args() imposta automaticamente MODE_EDIT (riga 270) ma non reimposta "valid_flags", e i "valid_flags" includono MODE_SHELL per impostazione predefinita (righe 127 e 249):

Scarica lo strumento