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.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
CVE-2021-4034 — Artigo detalhado e exploit de prova de conceito para CVE-2021-4034 (PolKit pkexec escalada de privilégio local), incluindo um ambiente Docker lab para análise prática e depuração. | Kitploit
Ferramentas/GitHubGitHub/chenaotian/cve-2021-4034
Escalada de PrivilégiosAnálise de VulnerabilidadesExploraçãoTestes de PenetraçãoAprendizado e EducaçãoExploração de BináriosLabs e Prática
GitHubchenaotian/cve-2021-4034

CVE-2021-4034

Artigo detalhado e exploit de prova de conceito para CVE-2021-4034 (PolKit pkexec escalada de privilégio local), incluindo um ambiente Docker lab para análise prática e depuração.

Ver Repositório
12316há 4 anosAinda não revisado

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-4034 Análise de escalonamento de privilégio local do PolKit

[toc]

Introdução à vulnerabilidade

ID da vulnerabilidade: CVE-2021-4034

Pontuação da vulnerabilidade:

Produto vulnerável: linux PolKit (pkexec)

Escopo de impacto: afeta versões de 2009 até o presente (atualmente 0.105) Referência http://its.dlut.edu.cn/info/1054/78309.htm

Condições de exploração: linux local; pkexec é um arquivo suid com permissão de execução

Obtenção do código-fonte: apt source policykit-1

​ ou https://launchpad.net/ubuntu/bionic/+package/policykit-1

Ambiente docker

Ambiente docker: chenaotian/cve-2021-4034

Docker que eu montei, fornece:

  1. pkexec compilado por mim mesmo, depurável com código-fonte
  2. glibc com símbolos de depuração (parece não servir para muito)
  3. gdb e plugins gdb pwngdb & pwndbg (parece desnecessário)
  4. exploit no ambiente de depuração

Tudo está no diretório /root/:

image-20220126183638493

  • O diretório exp é onde estão o exp e o run.sh; pode-se usar su test para mudar para o usuário test e executar
  • glibc-2.27 é o diretório do código-fonte do glibc, provavelmente não será necessário, mas útil para depuração com gdb quando necessário
  • polkit-0.105 é o pacote de código-fonte do policykit

Iniciar docker:

docker run -d -ti --rm -h cvedebug --name cvedebug --cap-add=SYS_PTRACE chenaotian/cve-2021-4034:latest /bin/bash

Testar exploit:

cd ~/exp/CVE-2021-4034/
./run.sh
su test
./exp
whoami

Princípio da vulnerabilidade

O produto onde a vulnerabilidade ocorre é o comando pkexec do polkit. pkexec é semelhante ao sudo, uma ferramenta que permite executar comandos como outro usuário (normalmente root). Pode-se verificar o pacote ao qual pkexec pertence com o comando dpkg:

dpkg -S /usr/bin/pkexec

image-20220126152839307

Em seguida, obter o pacote fonte (também está no meu docker), depois compilar uma versão depurável a partir do pacote fonte para facilitar a depuração.

Ponto de ativação da vulnerabilidade

O princípio de ativação da vulnerabilidade é muito simples

/polkit-0.105/src/programs/pkexec.c : 386 main

int
main (int argc, char *argv[])
{
    
  ··· ···
  ··· ···
      
  /* 这段的意思就是,循环遍历用户输入参数,根据输入的不同参数设置值
   * 但问题在于,他循环遍历的起点是1,没有考虑用户没有输入任何参数的情况
   */
  for (n = 1; n < (guint) argc; n++) 
    {
      if (strcmp (argv[n], "--help") == 0)
        {
          opt_show_help = TRUE;
        }
      ··· ···
      else //如果是无法识别的参数则跳出循环,这里意味着该参数是想要执行的命令
        {
          break;
        }
    }

  ··· ···

  g_assert (argv[argc] == NULL);
  path = g_strdup (argv[n]); //获取执行命令具体字符串
  if (path == NULL)
    {
      ···
    }
  if (path[0] != '/')
    {
      /* g_find_program_in_path() is not suspectible to attacks via the environment */
      //该函数会根据PATH环境变量寻找要执行命令的绝对地址
      s = g_find_program_in_path (path); 
      if (s == NULL)
        {
          ···
        }
      g_free (path);
      argv[n] = path = s;//把获取到的绝对地址修改回命令行参数
    }
  ··· ···
  ··· ···

Análise dos meus comentários no código:

  1. Primeiro, a função main define algumas variáveis com base nos argumentos da linha de comando do usuário, mas o valor inicial do loop for é 1, o que significa que ele assume que pelo menos um argumento será fornecido (o comando a ser executado por pkexec).
  2. Se um argumento que não começa com -- for encontrado, ele é considerado o comando a ser executado, e o loop é interrompido para prosseguir com a lógica seguinte.
  3. Chama a função g_find_program_in_path para buscar o caminho absoluto do comando. Esta função usa a variável de ambiente PATH para localizar o caminho absoluto do argumento (comando). Por exemplo, se cat for passado, retorna /bin/cat.
  4. Escreve o caminho absoluto retornado de volta na posição do argumento da linha de comando. (Pode ser entendido como a conversão do comando para o caminho absoluto do arquivo correspondente.)

Ainda é fácil de entender, mas o problema é:

  1. Quando um binário linux é executado, os argumentos da linha de comando argv[] e as variáveis de ambiente environ[] são colocados no final da pilha, e argv[] e environ[] são contíguos. O último item de argv[] é null.
  2. Se o pkexec for iniciado pela linha de comando sem nenhum argumento adicional, argv[0] será "pkexec" e argv[1] será \x00, sem problemas. Mas se for iniciado pela função execve sem argumentos adicionais, argv[0] será \x00 e argv[1] apontará para a variável de ambiente! Ao ler argv[1], será feita uma leitura fora dos limites de environ[0].

Quando iniciado diretamente pela linha de comando, argc é 1 e argv[0] é o caminho do pkexec:

image-20220126162616203

Iniciando pkexec com a função execve, argc é 0:

image-20220126162804529

O que isso causa? Quando iniciado com execve sem argumentos adicionais, o comprimento de argv[] é 0, então argv[1] é environ[0]. Assim, a lógica analisada acima se torna: obter o valor da primeira variável de ambiente e procurar seu caminho absoluto na variável PATH. Se encontrado, escrever de volta na primeira variável de ambiente. Então o método de exploração é o seguinte:

Exploração da vulnerabilidade

Primeiramente, é importante deixar claro que pkexec é um arquivo privilegiado (suid):

image-20220126161324831

Como usar variáveis de ambiente para fazer algo em um arquivo privilegiado? Primeiro, um pequeno detalhe:

Um pequeno detalhe

O vinculador dinâmico do linux ld-linux-x86-64.so.2 limpa variáveis de ambiente sensíveis durante a execução de programas privilegiados:

glibc-2.27/elf/dl-support.c : 307

void
_dl_non_dynamic_init (void)
{
  ··· ···
  ··· ···

  if (__libc_enable_secure) //特权模式的情况下
    {
      static const char unsecure_envvars[] =
	UNSECURE_ENVVARS
#ifdef EXTRA_UNSECURE_ENVVARS
	EXTRA_UNSECURE_ENVVARS
#endif
	;
      const char *cp = unsecure_envvars;

      //循环将危险环境变量列表中的环境变量全部清空(unset)
      while (cp < unsecure_envvars + sizeof (unsecure_envvars)) 
	{
	  __unsetenv (cp);
	  cp = (const char *) __rawmemchr (cp, '\0') + 1;
	}

#if !HAVE_TUNABLES
      if (__access ("/etc/suid-debug", F_OK) != 0)
	__unsetenv ("MALLOC_CHECK_");
#endif
    }
··· ···
··· ···
}

A lista de variáveis de ambiente perigosas UNSECURE_ENVVARS é definida como:

glibc-2.27/sysdeps/generic/unsecvars.h : 10

#define GLIBC_TUNABLES_ENVVAR "GLIBC_TUNABLES\0"
#define UNSECURE_ENVVARS \
  "GCONV_PATH\0"							      \
  "GETCONF_DIR\0"							      \
  GLIBC_TUNABLES_ENVVAR							      \
  "HOSTALIASES\0"							      \
  "LD_AUDIT\0"								      \
  "LD_DEBUG\0"								      \
  "LD_DEBUG_OUTPUT\0"							      \
  "LD_DYNAMIC_WEAK\0"							      \
  "LD_HWCAP_MASK\0"							      \
  "LD_LIBRARY_PATH\0"							      \
  "LD_ORIGIN_PATH\0"							      \
  "LD_PRELOAD\0"							      \
  "LD_PROFILE\0"							      \
  "LD_SHOW_AUXV\0"							      \
  "LD_USE_LOAD_BIAS\0"							      \
  "LOCALDOMAIN\0"							      \
  "LOCPATH\0"								      \
  "MALLOC_TRACE\0"							      \
  "NIS_PATH\0"								      \
  "NLSPATH\0"								      \
  "RESOLV_HOST_CONF\0"							      \
  "RES_OPTIONS\0"							      \
  "TMPDIR\0"								      \
  "TZDIR\0"
Baixar ferramenta