Skip to content
KitploitKITPLOIT
FerramentasExploitsBlog
Log in
Enviar
FerramentasExploitsBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

FeedsContatoPrivacidade© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
CVE-2021-3156-Heap-Based-Buffer-Overflow-in-Sudo-Baron-Samedit- — Análise técnica e desenvolvimento de exploit para CVE-2021-3156, um buffer overflow baseado em heap no Sudo, incluindo três exploits funcionais para escalonamento de privilégios locais nas principais distribuições Linux. | Kitploit
Ferramentas/GitHubGitHub/sornphut/cve-2021-3156-heap-based-buffer-overflow-in-sudo-baron-samedit-
Escalada de PrivilégiosAnálise de VulnerabilidadesExploraçãoTestes de PenetraçãoPapers e PesquisaAprendizado e EducaçãoExploração de Binários
GitHubsornphut/cve-2021-3156-heap-based-buffer-overflow-in-sudo-baron-samedit-

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

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

Análise técnica e desenvolvimento de exploit para CVE-2021-3156, um buffer overflow baseado em heap no Sudo, incluindo três exploits funcionais para escalonamento de privilégios locais nas principais distribuições Linux.

Ver Repositório
23há 1 anoAinda não revisado

Qualys Security Advisory

Baron Samedit: Estouro de buffer baseado em heap no Sudo (CVE-2021-3156)

======================================================================== Conteúdo

Resumo Análise Exploração Agradecimentos Cronologia

======================================================================== Resumo

Descobrimos um estouro de buffer baseado em heap no Sudo (https://www.sudo.ws/). Esta vulnerabilidade:

  • é explorável por qualquer usuário local (usuários normais e usuários do sistema, sudoers e não-sudoers), sem autenticação (ou seja, o invasor não precisa saber a senha do usuário);

  • foi introduzida em julho de 2011 (commit 8255ed69) e afeta todas as versões legadas de 1.8.2 a 1.8.31p2 e todas as versões estáveis de 1.9.0 a 1.9.5p1, em sua configuração padrão.

Desenvolvemos três exploits diferentes para esta vulnerabilidade e obtivemos privilégios totais de root no Ubuntu 20.04 (Sudo 1.8.31), Debian 10 (Sudo 1.8.27) e Fedora 33 (Sudo 1.9.2). Outros sistemas operacionais e distribuições provavelmente também são exploráveis.

======================================================================== Análise

Se o Sudo for executado para rodar um comando no modo "shell" (shell -c comando):

  • seja através da opção -s, que define a flag MODE_SHELL do Sudo;

  • ou através da opção -i, que define as flags MODE_SHELL e MODE_LOGIN_SHELL do Sudo;

então, no início da main() do Sudo, parse_args() reescreve argv (linhas 609-617), concatenando todos os argumentos da linha de comando (linhas 587-595) e escapando todos os metacaracteres com barras invertidas (linhas 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 }

Mais tarde, em sudoers_policy_main(), set_cmnd() concatena os argumentos da linha de comando em um buffer baseado em heap "user_args" (linhas 864-871) e desescapa os metacaracteres (linhas 866-867), "para fins de correspondência e registro do 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 }

Infelizmente, se um argumento da linha de comando termina com um único caractere de barra invertida, então:

  • na linha 866, "from[0]" é o caractere de barra invertida, e "from[1]" é o terminador nulo do argumento (ou seja, não é um caractere de espaço);

  • na linha 867, "from" é incrementado e aponta para o terminador nulo;

  • na linha 868, o terminador nulo é copiado para o buffer "user_args", e "from" é incrementado novamente e aponta para o primeiro caractere após o terminador nulo (ou seja, fora dos limites do argumento);

  • o loop "while" nas linhas 865-869 lê e copia caracteres fora dos limites para o buffer "user_args".

Em outras palavras, set_cmnd() é vulnerável a um estouro de buffer baseado em heap, porque os caracteres fora dos limites que são copiados para o buffer "user_args" não foram incluídos em seu tamanho (calculado nas linhas 852-853).

Em teoria, no entanto, nenhum argumento da linha de comando pode terminar com um único caractere de barra invertida: se MODE_SHELL ou MODE_LOGIN_SHELL estiver definido (linha 858, uma condição necessária para atingir o código vulnerável), então MODE_SHELL está definido (linha 571) e parse_args() já escapou todos os metacaracteres, incluindo barras invertidas (ou seja, escapou cada barra invertida com uma segunda barra invertida).

Na prática, no entanto, o código vulnerável em set_cmnd() e o código de escape em parse_args() são cercados por condições ligeiramente 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)) {

Nossa pergunta, então, é: podemos definir MODE_SHELL e MODE_EDIT ou MODE_CHECK (para atingir o código vulnerável) mas não o MODE_RUN padrão (para evitar o código de escape)?

A resposta, ao que parece, é não: se definirmos MODE_EDIT (opção -e, linha 361) ou MODE_CHECK (opção -l, linhas 423 e 519), então parse_args() remove MODE_SHELL das "valid_flags" (linhas 363 e 424) e sai com um erro se especificarmos uma flag inválida como MODE_SHELL (linhas 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);

Mas encontramos uma brecha: se executarmos o Sudo como "sudoedit" em vez de "sudo", então parse_args() define automaticamente MODE_EDIT (linha 270) mas não redefine "valid_flags", e as "valid_flags" incluem MODE_SHELL por padrão (linhas 127 e 249):

Baixar ferramenta