Linux e ferramentas de desenvolvimento
Bash básico para trabalho de segurança
Aprenda pipes, redirecionamento, variáveis, laços, códigos de saída e set -euo pipefail, e use isso para contar logins falhos e gerar hashes.
Donos, grupos, bits rwx, chmod, umask e setuid no Linux, com laboratório que testa o acesso de outro usuário e procura modos arriscados.
As permissões do Linux decidem quem pode ler, alterar e executar cada arquivo do sistema. A maioria dos problemas que você encontra numa revisão de segurança não é exploit sofisticado. É um arquivo de configuração que qualquer conta local pode gravar, um script que um serviço root executa mas um usuário comum consegue editar, ou um binário com o bit setuid ativo que ninguém lembra de ter colocado. Este artigo monta o mecanismo do zero: dono, grupo, os bits rwx, chmod, umask e os bits especiais que mais importam numa revisão. Você vai criar arquivos, mudar os modos, testar o acesso como um segundo usuário local numa VM de laboratório e procurar permissões arriscadas.
A ideia central é o privilégio mínimo. Um processo deve ter só o acesso de que precisa, e um arquivo só deve ser gravável pelas pessoas e pelos programas que devem alterá-lo. Os modos de arquivo são o primeiro ponto em que o Linux aplica essa regra, por isso são a primeira coisa a conferir.
Todo arquivo e diretório carrega três coisas que decidem o acesso:
Execute isto em qualquer arquivo da sua pasta pessoal:
ls -l notes.txtO primeiro caractere é o tipo do arquivo (- é arquivo comum, d é diretório, l é link simbólico). Os nove caracteres seguintes são o modo. Os nomes do dono e do grupo aparecem depois da contagem de links.
O kernel confere as permissões toda vez que um processo abre um arquivo. Um shell, um servidor web e um job do cron passam pela mesma verificação. Se a verificação falha, aparece Permission denied. O sistema de arquivos não se importa se o processo é confiável.
O modo tem três trios, um para cada classe de usuário:
O Linux confere as classes nessa ordem. Se a sua conta é a dona, valem os bits do dono, e os bits de grupo e de outros são ignorados, mesmo que eles dessem mais acesso. Isso surpreende muita gente. Um arquivo cujos bits do dono são --- não abre para o próprio dono, mesmo que os bits do grupo sejam rwx e o dono pertença ao grupo.
A lista de grupos é separada. Veja a sua com:
id
groupsUma mudança na associação a grupos normalmente vale só no próximo login, não no shell em que você rodou o comando.
Cada trio tem três bits:
| Bit | Em arquivo comum | Em diretório |
|---|---|---|
r (leitura, valor 4) |
Ler o conteúdo | Listar os nomes lá dentro |
w (escrita, valor 2) |
Alterar o conteúdo | Criar, renomear ou apagar entradas |
x (execução, valor 1) |
Executar como programa | Entrar no diretório e alcançar as entradas |
Dois pontos pegam quem está começando.
Primeiro, o bit x de um diretório é o que permite passar por ele. Um diretório com r e sem x deixa ver os nomes, mas não abrir nada. Um diretório com x e sem r deixa abrir um arquivo cujo nome exato você já conhece, mas não listar o conteúdo.
Segundo, a permissão de escrita no arquivo não permite apagá-lo. Apagar depende de escrita e execução no diretório que contém a entrada. Um arquivo seu dentro de um diretório onde você não pode escrever continua não podendo ser removido por você.
O chmod aceita duas notações para a mesma coisa.
Octal. Cada trio vira um dígito, a soma dos bits: r vale 4, w vale 2, x vale 1. Assim rw- é 6, r-- é 4, r-x é 5 e rwx é 7. O modo 644 significa leitura e escrita para o dono (6), leitura para o grupo (4) e leitura para os demais (4). O modo 600 significa que só o dono lê ou escreve.
Simbólica. Você indica a classe, o operador e os bits:
u (dono), g (grupo), o (outros), a (todos). Sem classe, vale a, exceto que os bits da umask ficam como estão.+ adiciona bits, - remove, = define exatamente esses bits na classe e limpa o resto.Assim, chmod u=rw,go=r notes.txt dá o mesmo resultado de chmod 644 notes.txt. chmod g+w notes.txt adiciona escrita para o grupo e mantém os outros bits.
A octal é compacta e fácil de colar em scripts. A simbólica é mais segura para uma mudança só, porque não apaga bits em que você não pensou. Espere as duas numa revisão, em arquivos de gerenciamento de configuração, Dockerfiles e scripts de instalação.
O chmod altera o modo. Num arquivo, só o dono ou o root consegue executá-lo com sucesso. Qualquer outro recebe Operation not permitted.
Um hábito seguro é ler o modo, mudar e ler de novo:
stat -c '%a %A %U:%G %n' notes.txt
chmod 600 notes.txt
stat -c '%a %A %U:%G %n' notes.txtO stat -c mostra o modo em octal (%a), o modo simbólico (%A), os nomes do dono e do grupo (%U, %G) e o nome do arquivo (%n). Você vai usar esse formato no laboratório inteiro.
O chown troca o dono e o chgrp troca o grupo. Trocar o dono para outro usuário normalmente exige root. Não rode chown -R numa árvore antes de listar o que ela vai afetar.
Quando um programa cria um arquivo, ele pede um modo inicial. Para arquivo comum, o valor inicial é 666. Para diretório, é 777. A umask remove bits desse valor inicial. O shell a define, e todo arquivo e diretório criado pelo shell e pelos processos filhos passa por ela.
A maioria das distribuições Linux usa 022 por padrão. Para um arquivo, 666 menos 022 dá 644, então arquivos novos ficam rw-r--r--. Para um diretório, 777 menos 022 dá 755, então diretórios novos ficam rwxr-xr-x. A umask só remove permissões. Um modo nunca fica mais permissivo que o valor inicial.
Veja o seu valor:
umaskUma umask mais restrita, como 077, gera arquivos 600 e diretórios 700, acessíveis só pelo dono. Uma mais aberta, como 002, gera arquivos 664 e diretórios 775, que o grupo pode gravar. Uma umask definida no perfil do shell vale para aquele shell e seus filhos. Ela não muda arquivos que já existem.
Modos octais de quatro dígitos acrescentam um dígito à frente para três bits especiais:
/tmp é o exemplo clássico.O ls -l mostra o setuid como s na posição de execução do dono, e o sticky como t na posição de execução dos outros. No Ubuntu 24.04, a linha do passwd é esta:
-rwsr-xr-x 1 root root 64152 May 30 2024 /usr/bin/passwdProgramas como o passwd precisam de setuid porque devem gravar arquivos protegidos de contas em nome de um usuário comum. O risco é que cada binário de root com setuid permite que um usuário comum rode código com privilégios de root. Um bug nele, como corrupção de memória ou uma chamada insegura a um programa auxiliar, pode virar escalonamento de privilégio local. Revisores mantêm uma lista curta de binários setuid e a comparam com uma referência conhecida. Um novo arquivo setuid que ninguém instalou de propósito é um achado que precisa de resposta.
Arquivos graváveis por todos são o outro problema comum. Um arquivo com o+w permite que qualquer conta local altere o conteúdo. Se esse arquivo for um script, uma configuração lida por um serviço root ou um binário num diretório do PATH, o atacante nem precisa de exploit. Ele só edita o arquivo. Confira também os diretórios. Um diretório gravável num caminho executado pelo root pode deixar um atacante substituir um arquivo, mesmo que o arquivo em si esteja trancado.
Rode isto num ambiente Linux que você controla: uma distribuição no WSL ou uma VM criada para o curso. Não rode em servidor de produção nem em máquina compartilhada. A seção do segundo usuário cria uma conta, então faça isso só na VM de laboratório.
mkdir ~/permlab && cd ~/permlab
echo 'lab secret' > notes.txt && ls -l notes.txtNo Ubuntu 24.04 sob WSL, o arquivo novo apareceu como -rw-r--r--, com o dono e o grupo com o nome da conta. Seu nome de usuário, data e grupo serão diferentes. Compare o modo.
chmod 600 notes.txt && stat -c '%a %U:%G %n' notes.txt
umaskSaída observada:
600 usurio:usurio notes.txt
0022O nome da sua conta será diferente. O 600 significa que só o dono lê e escreve. O 0022 é a umask do shell atual, e o zero à esquerda faz parte da forma octal.
Agora um diretório:
mkdir sub && chmod 750 sub && stat -c '%a %n' subObservado: 750 sub. O dono tem acesso total, o grupo pode ler e entrar, e os outros usuários não recebem nada.
Mudanças simbólicas, uma de cada vez, com uma leitura depois de cada:
chmod u=rw,go=r notes.txt && stat -c '%a %A %n' notes.txt
chmod g+w notes.txt && stat -c '%a %A %n' notes.txt
chmod o-r notes.txt && stat -c '%a %A %n' notes.txtSaída observada:
644 -rw-r--r-- notes.txt
664 -rw-rw-r-- notes.txt
660 -rw-rw---- notes.txtCada comando mudou só os bits que citou.
Rode a umask num subshell para que a mudança não fique na sua sessão:
(umask 077; touch private.txt; stat -c '%a %A %n' private.txt)
(umask 002; touch shared.txt; mkdir made_dir; stat -c '%a %A %n' shared.txt made_dir)Saída observada:
600 -rw------- private.txt
664 -rw-rw-r-- shared.txt
775 drwxrwxr-x made_dirCom 077, o arquivo perdeu todos os bits de grupo e de outros. Com 002, o grupo ganhou escrita no arquivo e no diretório. O diretório partiu de 777 e perdeu apenas 002.
Esta etapa exige uma conta que você possa criar na sua própria VM. Rode-a só lá.
sudo useradd -m labuser
sudo -u labuser cat ~/permlab/notes.txtEu não rodei estes comandos. A conta do WSL precisa de senha para o sudo, e eu não digitei nenhuma. O que observar: com modo 600, o segundo comando deve falhar com uma mensagem Permission denied, porque o labuser não é o dono nem está no grupo.
Depois, libere o arquivo para os outros:
chmod 644 notes.txt
sudo -u labuser cat ~/permlab/notes.txtO que observar: o conteúdo só aparece se o labuser também puder entrar na sua pasta pessoal e em ~/permlab. Muitas distribuições criam pastas pessoais como 755, mas algumas usam 750. Se um diretório pai nega x aos outros usuários, a leitura falha mesmo com o arquivo legível. Confira com ls -ld ~ ~/permlab. No Ubuntu 24.04 sob WSL que usei, ls -ld ~ mostrou drwxr-x---, ou seja 750, então um segundo usuário ficaria bloqueado ali mesmo depois do chmod 644. Esta é a prática do bit x de diretório que vimos antes.
Liste arquivos comuns graváveis por todos dentro da sua pasta pessoal, sem atravessar outros sistemas de arquivos:
find ~ -xdev -type f -perm -o+w 2>/dev/nullNum laboratório limpo, isso não imprime nada. Para ver a busca funcionar, deixe um arquivo gravável de propósito:
chmod 666 ~/permlab/notes.txt
find ~ -xdev -type f -perm -o+w 2>/dev/null
chmod 644 ~/permlab/notes.txtObservado: a primeira busca imprimiu /home/usurio/permlab/notes.txt. Depois da correção, a mesma busca não imprimiu nada.
Liste binários setuid num diretório do sistema:
find /usr/bin -perm -4000 -type f 2>/dev/null | sortObservado no Ubuntu 24.04 sob WSL, isso imprimiu dez arquivos, incluindo /usr/bin/passwd, /usr/bin/sudo, /usr/bin/su, /usr/bin/mount e /usr/bin/umount. Sua lista depende da distribuição e dos pacotes instalados. Numa revisão, compare a lista com o que o gerenciador de pacotes diz que deve ser setuid. Trate uma entrada inesperada como pergunta a responder, não como prova de ataque.
Confira o bit sticky nos diretórios temporários:
stat -c '%a %A %n' /tmp /var/tmpObservado: 1777 drwxrwxrwt nos dois. O t significa que usuários podem criar arquivos ali, mas não apagar arquivos de outra pessoa.
rm -rf ~/permlab
sudo userdel -r labuserO userdel -r também apaga a pasta pessoal da conta. Rode-o só para a conta de laboratório que você criou.
Os mesmos primeiros passos no Git Bash para Windows não se comportaram como no Linux. Depois de chmod 600 notes.txt, o stat ainda mostrou 644, e os chmod seguintes também não mudaram a saída. O Windows guarda o acesso em listas de controle de acesso do NTFS, e o Git Bash traduz só alguns dos bits. Um laboratório no Windows ensina os comandos, mas não mostra o que um modo do Linux faz. Use o WSL com uma distribuição Linux, ou uma VM, para este artigo.
Usar 777 para resolver um erro de acesso negado. Funciona, e ainda deixa todo mundo gravar e executar o arquivo. Descubra qual classe está negada e libere só ela.
Esquecer o diretório. Um arquivo legível pode continuar inacessível se um diretório pai não der x ao usuário. Confira cada diretório do caminho.
Usar chmod -R numa árvore inteira. Mudanças recursivas costumam colocar execução em arquivos comuns ou tirá-la dos diretórios. Use find com -type f ou -type d para atingir só um tipo.
Confiar no modo de um arquivo copiado. cp, tar e ferramentas de arquivamento podem manter ou redefinir modos, dependendo das opções. Confira o resultado com stat.
Ler a notação simbólica como absoluta. chmod g+w adiciona um bit. chmod g=w remove leitura e execução do grupo. A diferença é fácil de deixar passar.
Recorrer ao root primeiro. Muitos problemas de leitura e escrita se resolvem com associação a grupo ou com o modo do diretório, não com um auxiliar setuid nem com um shell root.
Uma revisão de permissões começa com uma pergunta: quem pode alterar aquilo que um processo privilegiado lê ou executa? Três achados aparecem sempre:
Ao escrever um achado, cite o caminho, o modo, o dono, o grupo, o processo que lê ou executa e a mudança que corrige o problema. Teste no seu laboratório. Não rode essas buscas em sistemas que você não administra, e não use sudo -u na máquina de outra pessoa.
Quando os modos básicos estiverem claros, estude listas de controle de acesso com getfacl e setfacl, que adicionam entradas por usuário além de dono, grupo e outros. Leia o manual do chattr sobre os atributos de imutável e de somente anexar. Use namei -l /caminho/do/arquivo para mostrar o modo de cada componente de um caminho. É a forma mais rápida de achar o diretório que bloqueia um serviço.
Para os hábitos de shell por trás desses comandos, comece pelo artigo anterior do Manual de Campo, o básico de Bash para estudantes de segurança. O próximo artigo, o que é SSH e como funcionam as chaves SSH, trata de chaves SSH, que dependem dos mesmos modos: o arquivo da chave privada deve ser legível só pelo dono, e o cliente SSH recusa usar uma chave cujo modo esteja aberto demais.
O privilégio mínimo começa nos modos de arquivo. Um processo que pode escrever menos causa menos dano quando erra, e um arquivo que os outros não conseguem alterar é uma coisa a menos para revisar.
Linux e ferramentas de desenvolvimento
Aprenda pipes, redirecionamento, variáveis, laços, códigos de saída e set -euo pipefail, e use isso para contar logins falhos e gerar hashes.
Linux e ferramentas de desenvolvimento
Como funcionam as chaves SSH de host e de usuário, por que Ed25519 com senha de proteção é o padrão e como proteger o login em uma VM de laboratório.
Linux e ferramentas de desenvolvimento
GitHub para iniciantes: a diferença entre Git e GitHub, os termos básicos, um exercício local com Git e como checar um projeto antes de rodá-lo.