SUID, SGID e Sticky Bits no Linux: Guia Completo com Exemplos

Permissões especiais como SUID, SGID e Sticky Bits oferecem um controle granular sobre executáveis e diretórios no Linux. Este artigo explora seus benefícios e potenciais armadilhas.

Já em Operação

A segurança em sistemas operacionais multiusuário é um desafio complexo. O armazenamento de senhas é um bom exemplo. Para que o sistema possa comparar a senha digitada com a senha armazenada, elas devem ser acessíveis. No entanto, senhas são informações muito sensíveis que precisam de proteção.

No Linux, as senhas são protegidas por criptografia e por limitar o acesso ao arquivo que as contém apenas ao usuário root. Mas isso levanta a questão: como usuários sem privilégios de root podem alterar suas senhas?

Elevando o Status

Normalmente, programas e comandos no Linux herdam as permissões do usuário que os inicia. O comando `passwd`, quando executado pelo root, opera com privilégios de root, acessando o arquivo `/etc/shadow` onde as senhas são armazenadas.

O cenário ideal seria permitir que qualquer usuário executasse o comando `passwd`, mantendo seus privilégios de root, permitindo que cada usuário altere sua própria senha.

O bit Set User ID (SUID) possibilita isso, executando programas com as permissões do proprietário do arquivo, em vez das permissões do usuário que os inicia.

Elevando o Status do Programa

Ainda assim, é crucial impedir que um usuário interfira na senha de outro. Embora o SUID permita que aplicativos rodem com privilégios temporários, a segurança completa depende do próprio programa `passwd`, não do sistema operacional ou do SUID em si.

Programas com privilégios elevados podem apresentar riscos se não forem projetados com segurança em mente desde o início. Isso significa que a segurança precisa ser uma consideração fundamental, não uma adição posterior. Projetos de código aberto oferecem a vantagem de permitir a inspeção do código-fonte e análises de segurança por especialistas. O código do programa `passwd`, por exemplo, contém verificações para determinar se o usuário é root, ajustando o comportamento do programa com base nisso.

Por exemplo, o root pode alterar qualquer senha, então o programa ignora as verificações usuais sobre quais senhas o usuário tem permissão para alterar.

Com comandos e utilitários principais do Linux, você pode ter confiança em sua segurança, pois o código foi exaustivamente revisado. Contudo, é sempre possível que existam vulnerabilidades desconhecidas. No entanto, correções e atualizações costumam ser lançadas rapidamente para resolver qualquer problema de segurança recém-descoberto.

Com softwares de terceiros, especialmente aqueles que não são de código aberto, é crucial ter cautela ao usar o SUID. Isso não significa que não se deva usar, mas que é essencial garantir que o sistema não seja colocado em risco. É fundamental evitar elevar os privilégios de um programa que não gerencia adequadamente a si mesmo e a quem o executa.

Comandos Linux que utilizam SUID

Diversos comandos do Linux usam o bit SUID para conceder privilégios elevados quando executados por um usuário comum, incluindo:

ls -l /bin/su
ls -l /bin/ping
ls -l /bin/mount
ls -l /bin/umount
ls -l /usr/bin/passwd

Os nomes dos arquivos aparecem em vermelho, indicando que o bit SUID está ativo.

As permissões de um arquivo ou diretório são representadas por três grupos de três caracteres: `rwx`, que significam ler, escrever e executar. A ausência de uma letra é indicada por um hífen (-). Esses três grupos se referem ao proprietário do arquivo, membros do grupo do arquivo e outros usuários. Quando o bit SUID está definido, um “s” ocupa a posição de permissão de execução do proprietário.

Um “S” maiúsculo indica que o bit SUID está definido, mas o arquivo não possui permissões de execução.

Vamos exemplificar. O usuário `dave` executa o comando `passwd`:

passwd

O comando solicita a nova senha de `dave`. Podemos utilizar `ps` para observar detalhes dos processos em execução.

Com `ps` e `grep` em outro terminal, buscaremos o processo `passwd`, utilizando as opções `-e` (todos os processos) e `-f` (formato completo) com o comando `ps`.

O comando a seguir é executado:

ps -e -f | grep passwd

Duas linhas são retornadas. A segunda linha corresponde ao processo `grep`, e a primeira linha exibe o processo `passwd` iniciado por `dave`.

Podemos ver que o processo `passwd` é executado como se o root o tivesse iniciado.

Definindo o Bit SUID

O bit SUID pode ser alterado facilmente com `chmod`. O modo simbólico `u+s` ativa o bit SUID e `u-s` o desativa.

Para demonstrar alguns conceitos do bit SUID, criaremos um programa chamado `htg`. Este programa, no diretório raiz do usuário `dave`, não tem o bit SUID definido. Ele exibe os IDs de usuário reais e eficazes (UID).

O UID real é o da pessoa que executa o programa. O ID eficaz é o da conta sob a qual o programa está se comportando como se fosse iniciado.

A seguir, os comandos que serão digitados:

ls -lh htg
./htg

Ao executar o programa local, vemos que os IDs reais e eficazes são ambos `dave`. Este é o comportamento esperado de um programa padrão.

Agora, copiaremos o programa para o diretório `/usr/local/bin` para que outros usuários possam utilizá-lo.

Usaremos o comando `chmod` para definir o bit SUID e, em seguida, verificaremos se ele foi ativado:

sudo cp htg /usr/local/bin
sudo chmod u+s /usr/local/bin/htg
ls -hl /usr/local/bin/htg

O programa foi copiado e o bit SUID foi definido. Agora, executaremos a cópia em `/usr/local/bin`:

htg

Embora `dave` tenha executado o programa, o ID efetivo é `root`. Se `mary` executar o programa, o mesmo acontecerá:

htg

O ID real é `mary` e o ID efetivo é `root`. O programa é executado com as permissões do usuário `root`.

O Bit SGID

O bit Set Group ID (SGID) funciona de forma semelhante ao SUID. Quando aplicado a um executável, o grupo efetivo passa a ser o grupo do arquivo. O processo passa a ter as permissões dos membros do grupo do arquivo, e não as da pessoa que o iniciou.

Vamos modificar o programa `htg` para que ele também mostre o grupo efetivo. Alteraremos o grupo do programa `htg` para ser o grupo padrão do usuário `mary`, que também se chama `mary`. Usaremos `chmod` com os modos simbólicos `u-s` e `g+s` para remover o bit SUID e definir o SGID.

A seguir, os comandos digitados:

sudo chown root:mary /usr/local/bin/htg
sudo chmod u-s,g+s /usr/local/bin/htg
ls -lh /usr/local/bin/htg

O bit SGID é denotado por “s” nas permissões de grupo. O grupo do arquivo é agora `mary`, e o nome do arquivo está destacado em amarelo.

Antes de executarmos o programa, vamos verificar a quais grupos `dave` e `mary` pertencem. Usaremos o comando `id` com a opção `-G` para mostrar todos os IDs de grupo. Em seguida, executaremos o programa `htg` como `dave`.

A seguir, os comandos que serão executados:

id -G dave
id -G mary
htg

O ID do grupo padrão de `mary` é 1001, e o grupo efetivo do programa `htg` é 1001. Portanto, embora `dave` tenha iniciado o programa, ele está sendo executado com as permissões dos membros do grupo `mary`. É como se `dave` tivesse se juntado ao grupo `mary`.

Agora, aplicaremos o bit SGID a um diretório. Criaremos um diretório chamado “trabalho”, mudaremos seu grupo para “geek” e definiremos o bit SGID neste diretório.

Usaremos a opção `-d` com `ls` para ver os detalhes do diretório em si, em vez do seu conteúdo.

Os comandos a seguir serão executados:

sudo mkdir work
sudo chown dave:geek work
sudo chmod g+s work
ls -lh -d work

O bit SGID e o grupo “geek” foram definidos. Todas as operações realizadas neste diretório serão afetadas.

A seguir, vamos entrar no diretório “trabalho”, criar um diretório “demo” e verificar suas propriedades:

cd work
mkdir demo
ls -lh -d demo

O bit SGID e o grupo “geek” foram automaticamente aplicados ao diretório “demo”.

Agora, vamos criar um arquivo com o comando `touch` e verificar suas propriedades:

touch useful.sh
ls -lh useful.sh

O grupo do novo arquivo é automaticamente definido como “geek”.

O Bit Pegajoso (Sticky Bit)

O nome do bit pegajoso deriva de seu uso original. Quando definido em um executável, ele indicava ao sistema operacional para manter as partes de texto do executável em swap, tornando a reutilização mais rápida. No Linux, o sticky bit só se aplica a diretórios – aplicá-lo a um arquivo não teria efeito.

Quando o sticky bit é definido em um diretório, os usuários só podem excluir arquivos de sua propriedade dentro desse diretório. Eles não podem excluir arquivos de outros usuários, independentemente das permissões definidas nos arquivos.

Isso permite a criação de um diretório que todos os usuários (e os processos que eles iniciam) podem usar como um local para compartilhar arquivos. Os arquivos ficam protegidos porque nenhum usuário pode excluir os arquivos de outros usuários.

Vamos criar um diretório chamado “compartilhado”. Usaremos o modo simbólico `o+t` com `chmod` para definir o sticky bit nesse diretório. Depois, vamos verificar as permissões deste diretório, bem como os diretórios `/tmp` e `/var/tmp`.

A seguir, os comandos digitados:

mkdir shared
sudo chmod o+t shared
ls -lh -d shared
ls -lh -d /tmp
ls -lh -d /var/tmp

Quando o sticky bit é definido, o bit executável do conjunto de permissões “outros” é definido como “t”. O nome do arquivo também é destacado em azul.

As pastas `/tmp` e `/var/tmp` são exemplos de diretórios que têm todas as permissões definidas para proprietário, grupo e outros (por isso estão em verde). Elas são utilizadas como locais compartilhados para arquivos temporários.

Com essas permissões, qualquer usuário teoricamente poderia fazer qualquer coisa. No entanto, o sticky bit prevalece sobre isso e impede que qualquer usuário delete arquivos de outros usuários.

Lembretes

Um resumo rápido do que abordamos:

  • SUID só funciona em arquivos.
  • SGID pode ser aplicado a diretórios e arquivos.
  • Sticky bit só pode ser aplicado a diretórios.
  • Se os indicadores “s”, “g” ou “t” aparecerem em maiúsculas, o bit executável (x) não está definido.