Compreendendo Permissões


Cyberguard: Linux Luminarium.

Este módulo apresentará a você o sistema de permissões do Linux, que é uma das partes mais fundamentais da sua jornada daqui em diante e controla o acesso a arquivos entre diferentes usuários.

No Linux, os arquivos possuem diferentes permissões ou modos de arquivo (file modes). Você pode conferir as permissões de um arquivo ou diretório usando ls -l. Vamos criar alguns arquivos e examinar suas permissões:

hacker@dojo:~$ mkdir pwn_directory
hacker@dojo:~$ touch college_file
hacker@dojo:~$ ls -l
total 4
-rw-r--r-- 1 hacker hacker    0 May 22 13:42 college_file
drwxr-xr-x 2 hacker hacker 4096 May 22 13:42 pwn_directory
hacker@dojo:~$

Há muitas informações aí, e aprenderemos sobre boa parte delas neste módulo! Por enquanto, vamos analisar a saída acima em linhas gerais:

O Tipo de Arquivo

O primeiro caractere de cada linha representa o tipo de arquivo. No caso de pwn_directory, o d indica que se trata de um diretório (directory), e no caso de college_file, o traço - indica que é um arquivo comum. Existem outros tipos também, e você encontrará alguns deles mais adiante em sua jornada no pwn.college.

As Permissões

Os nove caracteres seguintes representam as permissões de acesso propriamente ditas do arquivo ou diretório. Eles são divididos em 3 blocos de 3 caracteres: os 3 primeiros indicam as permissões que o usuário dono do arquivo (chamado de "dono" ou owner) possui; os 3 seguintes indicam as permissões do grupo dono do arquivo (group); e os últimos 3 caracteres indicam as permissões de qualquer outro usuário (others — outros usuários e outros grupos). Aprenderemos detalhadamente sobre cada uma delas ao longo deste módulo.

Informações de Propriedade (Ownership)

Existem duas colunas que mostram o usuário dono do arquivo (neste caso, o usuário hacker) e, em seguida, o grupo dono do arquivo (neste caso, também o grupo hacker). Você trabalhará bastante com isso por aqui!


Neste módulo, você praticará a percepção e manipulação de permissões. Vamos começar!


Primeiras coisas primeiro: propriedade de arquivos (file ownership). Todo arquivo no Linux pertence a um usuário do sistema. Na maior parte das vezes, no seu dia a dia, esse usuário é a conta com a qual você faz login na máquina.

Em um sistema compartilhado (como em um laboratório universitário), pode haver várias pessoas com diferentes contas de usuário, cada uma com seus próprios arquivos em seus respectivos diretórios pessoais (home directories). Mas mesmo em um sistema não compartilhado (como seu computador pessoal), o Linux mantém várias contas de serviço para diferentes tarefas internas do sistema.

As duas contas de usuário mais importantes são:

  1. A sua conta de usuário! No pwn.college, este é o usuário hacker, independentemente do seu nome real de usuário.
  2. root. Esta é a conta administrativa e, na maioria dos cenários de segurança ofensiva, o grande prêmio. Se você assumir o controle do usuário root, você praticamente completou seu objetivo de invasão!

E o que isso tem a ver? Bem, acontece que a maneira pela qual impedimos que você simplesmente faça cat /flag é definindo o /flag como pertencente ao usuário root, configurando suas permissões para que nenhum outro usuário possa lê-lo (você aprenderá a fazer isso mais adiante) e configurando o binário do desafio para rodar como root (o que também aprenderemos depois). O resultado é que, quando você tenta fazer cat /flag, você recebe:

hacker@dojo:~$ ls -l /flag
-r-------- 1 root root 53 Jul  4 04:47 /flag
hacker@dojo:~$ cat /flag
cat: /flag: Permission denied
hacker@dojo:~$

Aqui, você pode ver que a flag pertence ao usuário root (o primeiro root da linha) e ao grupo root (o segundo root da linha). Quando tentamos lê-la como usuário hacker, nosso acesso é negado. No entanto, se fôssemos o root (o sonho de todo hacker!), não teríamos qualquer problema para ler o arquivo:

root@dojo:~# cat /flag
pwn.college{demo_flag}
root@dojo:~#

Curiosamente, nós podemos mudar a propriedade de arquivos! Isso é feito através do comando chown (change owner):

chown [username] [file]

Normalmente, o chown só pode ser executado pelo usuário root. Vamos fingir que somos o root novamente (isso nunca perde a graça!) e observar um uso típico do chown:

root@dojo:~# mkdir pwn_directory
root@dojo:~# touch college_file
root@dojo:~# ls -l
total 4
-rw-r--r-- 1 root root    0 May 22 13:42 college_file
drwxr-xr-x 2 root root 4096 May 22 13:42 pwn_directory
root@dojo:~# chown hacker college_file
root@dojo:~# ls -l
total 4
-rw-r--r-- 1 hacker root    0 May 22 13:42 college_file
drwxr-xr-x 2 root   root 4096 May 22 13:42 pwn_directory
root@dojo:~#

O dono de college_file foi alterado para o usuário hacker, e agora o hacker pode fazer com ele tudo o que o root conseguia fazer! Se esse fosse o arquivo /flag, significaria que o usuário hacker agora poderia lê-lo!

Neste nível, praticaremos a alteração do dono do arquivo /flag para o usuário hacker e, em seguida, leremos a flag. Exclusivamente para este desafio, configurei o ambiente para que você possa usar o comando chown à vontade mesmo como usuário hacker (lembrando que, normalmente, isso exige privilégios de root). Use esse poder com sabedoria e mãos à obra com o chown!

Compartilhar é se importar, e o compartilhamento está no cerne do design do Linux. Os arquivos possuem tanto um usuário dono quanto um grupo dono. Um grupo pode conter múltiplos usuários, e um usuário pode ser membro de vários grupos simultaneamente.

Você pode conferir de quais grupos faz parte utilizando o comando id:

hacker@dojo:~$ id
uid=1000(hacker) gid=1000(hacker) groups=1000(hacker)
hacker@dojo:~$

Aqui, o usuário hacker faz parte apenas do grupo hacker. O caso de uso mais comum para grupos é controlar o acesso a diferentes recursos do sistema operacional. Por exemplo, o "Modo Privilegiado" (Privileged Mode) no pwn.college concede a você acesso root para facilitar depurações e testes. Isso é feito adicionando um grupo extra ao seu usuário quando você inicia no modo privilegiado:

hacker@dojo:~$ id
uid=1000(hacker) gid=1000(hacker) groups=1000(hacker),27(sudo)
hacker@dojo:~$

Um usuário comum em um computador desktop Linux típico participa de muitos grupos. Por exemplo, veja a saída no computador do Zardus:

zardus@yourcomputer:~$ id
uid=1000(zardus) gid=1000(zardus) groups=1000(zardus),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev),100(users),106(netdev),114(bluetooth),117(lpadmin),120(scanner),995(docker)
zardus@yourcomputer:~$

Todos esses grupos dão a Zardus a capacidade de ler CDs e disquetes (quem ainda usa isso?), administrar o sistema, reproduzir áudio, desenhar na tela de vídeo, usar bluetooth e assim por diante. Geralmente, esse controle de acesso ocorre por meio da propriedade de grupo no sistema de arquivos! Por exemplo, a saída gráfica de vídeo pode ser controlada através do arquivo especial de dispositivo /dev/fb0:

zardus@yourcomputer:~$ ls -l /dev/fb0
crw-rw---- 1 root video 29, 0 Jun 30 23:42 /dev/fb0
zardus@yourcomputer:~$

Esse arquivo é um arquivo de dispositivo especial (o tipo c indica que é um "character device"), e interagir com ele altera a exibição da tela (em vez de alterar dados gravados no disco, como em um arquivo convencional!). A conta de usuário de Zardus pode interagir com ele porque o grupo dono do arquivo é video, e Zardus pertence ao grupo video.

Mas não temos essa facilidade com o arquivo /flag no dojo! Veja o seguinte cenário:

hacker@dojo:~$ id
uid=1000(hacker) gid=1000(hacker) groups=1000(hacker)
hacker@dojo:~$ ls -l /flag
-r--r----- 1 root root ... /flag
hacker@dojo:~$ cat /flag
cat: /flag: Permission denied
hacker@dojo:~$

Aqui, o arquivo da flag pertence ao usuário root e ao grupo root, e o usuário hacker não é o usuário root nem pertence ao grupo root. Logo, o acesso é bloqueado. Felizmente, a propriedade de grupo de um arquivo pode ser modificada com o comando chgrp (change group)! A menos que você seja o dono do arquivo e membro do novo grupo, essa operação normalmente requer acesso de root. Então, vamos testar como root:

root@dojo:~# mkdir pwn_directory
root@dojo:~# touch college_file
root@dojo:~# ls -l
total 4
-rw-r--r-- 1 root root    0 May 22 13:42 college_file
drwxr-xr-x 2 root root 4096 May 22 13:42 pwn_directory
root@dojo:~# chgrp hacker college_file
root@dojo:~# ls -l
total 4
-rw-r--r-- 1 root hacker    0 May 22 13:42 college_file
drwxr-xr-x 2 root root   4096 May 22 13:42 pwn_directory
root@dojo:~#

Neste nível, configurei a flag para que ela possa ser lida por qualquer grupo que seja seu proprietário, mas esse grupo atualmente é o root. Felizmente, também permiti que você invoque o comando chgrp como o usuário hacker! Mude a propriedade de grupo do arquivo da flag e leia a flag!

Nos níveis anteriores, você deve ter notado que o usuário hacker pertence ao grupo hacker e que zardus pertence ao grupo zardus. Existe uma convenção no Linux em que cada usuário tem seu próprio grupo homônimo, mas isso não é uma regra obrigatória. Por exemplo, muitos laboratórios de informática colocam todos os seus usuários em um único grupo compartilhado chamado users.

O ponto aqui é: antes você usou o grupo hacker, mas neste nível isso não funcionará. Ainda permitirei que você use chgrp, mas defini aleatoriamente o nome do grupo em que seu usuário está inserido. Você precisará usar o comando id para descobrir qual é esse grupo e, em seguida, usar chgrp rumo à vitória!

Agora que já estamos bem familiarizados com a propriedade de arquivos, vamos falar sobre o outro lado da moeda: as permissões de arquivos (file permissions). Relembre o nosso exemplo:

hacker@dojo:~$ mkdir pwn_directory
hacker@dojo:~$ touch college_file
hacker@dojo:~$ ls -l
total 4
-rw-r--r-- 1 hacker hacker    0 May 22 13:42 college_file
drwxr-xr-x 2 hacker hacker 4096 May 22 13:42 pwn_directory
hacker@dojo:~$

Para recapitular: o primeiro caractere indica o tipo de arquivo. Os nove caracteres seguintes são as permissões reais de acesso ao arquivo ou diretório, divididas em 3 caracteres indicando as permissões do usuário dono (agora você entende isso perfeitamente!), 3 caracteres indicando as permissões do grupo dono (o que você também já compreende!) e 3 caracteres indicando as permissões de qualquer outro usuário (other — todos os demais usuários e grupos do sistema).

Cada caractere do trio representa um tipo específico de permissão:

r - usuário/grupo/outros podem ler o arquivo (ou listar o conteúdo do diretório)
w - usuário/grupo/outros podem modificar o arquivo (ou criar/excluir arquivos no diretório)
x - usuário/grupo/outros podem executar o arquivo como programa (ou acessar o diretório, ex: usando `cd`)
- - nenhuma permissão

Para o arquivo college_file acima, a entrada de permissões rw-r--r-- é decodificada assim:

  • r: o usuário dono do arquivo (usuário hacker) pode lê-lo
  • w: o usuário dono do arquivo (usuário hacker) pode escrever nele
  • -: o usuário dono do arquivo (usuário hacker) não pode executá-lo
  • r: usuários membros do grupo dono do arquivo (grupo hacker) podem lê-lo
  • -: usuários membros do grupo dono do arquivo (grupo hacker) não podem escrever nele
  • -: usuários membros do grupo dono do arquivo (grupo hacker) não podem executá-lo
  • r: todos os outros usuários podem lê-lo
  • -: todos os outros usuários não podem escrever nele
  • -: todos os outros usuários não podem executá-lo

Agora, vejamos as permissões padrão do /flag:

hacker@dojo:~$ ls -l /flag
-r-------- 1 root root 53 Jul  4 04:47 /flag
hacker@dojo:~$

Aqui, há apenas um bit ativo: a permissão de leitura (r) para o usuário proprietário (neste caso, root). Os membros do grupo dono (o grupo root) e todos os outros usuários não possuem qualquer permissão de acesso.

Você pode estar se perguntando como funcionaram os níveis de chgrp, se não havia permissão para o grupo naquele arquivo. Bem, naqueles níveis específicos, configurei as permissões de forma diferente:

hacker@dojo:~$ ls -l /flag
-r--r----- 1 root root 53 Jul  4 04:47 /flag
hacker@dojo:~$

O grupo tinha permissão de leitura! É por isso que mudar o grupo do arquivo via chgrp permitiu que você o lesse.

Enfim! Assim como a propriedade, as permissões de arquivos também podem ser alteradas. Isso é feito com o comando chmod (change mode). A sintaxe básica do chmod é:

chmod [OPÇÕES] MODO ARQUIVO

Você pode especificar o MODO de duas formas: como uma modificação das permissões existentes ou definindo um modo totalmente novo que sobrescreve o anterior.

Neste nível, cobriremos a primeira forma: modificando o modo existente. O chmod permite ajustar permissões no formato QUEM+/-O_QUE, onde QUEM representa o usuário (u), grupo (g), outros (o) ou todos (a), e O_QUE representa leitura (r), escrita (w) ou execução (x). Por exemplo, para conceder permissão de leitura para o usuário dono, especificamos o modo u+r. Permissões de escrita (w) e execução (x) para o grupo (g) e outros (o) — ou todos (a) — são definidas da mesma maneira. Mais exemplos:

  • u+r, como visto acima, adiciona permissão de leitura às permissões do usuário
  • g+wx adiciona permissões de escrita e execução ao grupo
  • o-w remove a permissão de escrita de outros usuários
  • a-rwx remove todas as permissões do usuário, do grupo e de outros

Veja na prática:

root@dojo:~# mkdir pwn_directory
root@dojo:~# touch college_file
root@dojo:~# ls -l
total 4
-rw-r--r-- 1 root root    0 May 22 13:42 college_file
drwxr-xr-x 2 root root 4096 May 22 13:42 pwn_directory
root@dojo:~# chmod go-rwx *
root@dojo:~# ls -l
total 4
-rw------- 1 hacker root    0 May 22 13:42 college_file
drwx------ 2 root   root 4096 May 22 13:42 pwn_directory
root@dojo:~#

Neste desafio, você deve alterar as permissões do arquivo /flag para conseguir lê-lo! Normalmente, você precisaria ser o dono do arquivo para alterar suas permissões, mas tornei o comando chmod todo-poderoso neste nível: você pode executar chmod em qualquer arquivo que quiser, mesmo sendo o usuário hacker. Esse é um poder absoluto! O arquivo /flag pertence ao root, e você não pode mudar o dono dele aqui, mas pode torná-lo legível para o seu usuário. Vá em frente e resolva o desafio!

Até agora, você lidou principalmente com permissões de leitura (read). Isso faz todo sentido, já que você estava tornando o arquivo /flag legível para ler o seu conteúdo. Neste nível, exploraremos as permissões de execução (execute).

Quando você executa um programa, como /challenge/run, o Linux só permite a execução efetiva se o seu usuário tiver permissão de execução naquele arquivo. Veja:

hacker@dojo:~$ ls -l /challenge/run
-rwxr-xr-x 1 root root    0 May 22 13:42 /challenge/run
hacker@dojo:~$ /challenge/run
Successfully ran the challenge!
hacker@dojo:~$

Neste caso, /challenge/run executa porque ele tem permissão de execução para o usuário hacker. Como o arquivo pertence ao usuário root e ao grupo root, isso exige que o bit de execução esteja ativo nas permissões de "outros" (other). Se removermos essa permissão, a execução falhará:

hacker@dojo:~$ chmod o-x /challenge/run
hacker@dojo:~$ ls -l /challenge/run
-rwxr-xr-- 1 root root    0 May 22 13:42 /challenge/run
hacker@dojo:~$ /challenge/run
bash: /challenge/run: Permission denied
hacker@dojo:~$

Neste desafio, o programa /challenge/run entregará a flag para você, mas antes você precisa torná-lo executável! Lembre-se do que aprendeu sobre o chmod e faça /challenge/run revelar a sua flag!

Acha que já domina o chmod? Vamos praticar!

Este desafio pedirá que você altere as permissões do arquivo /challenge/pwn de maneiras específicas por algumas rodadas consecutivas. Se você errar as permissões solicitadas, o teste será reiniciado e você poderá tentar novamente. Se acertar as permissões oito vezes seguidas, o desafio permitirá que você use chmod no /flag para torná-lo legível para o seu usuário :-) Execute /challenge/run para começar!

Além de adicionar e remover permissões pontuais, como no nível anterior, o comando chmod também pode definir diretamente o conjunto completo de permissões, sobrescrevendo as anteriores. Isso é feito utilizando o operador = em vez de - ou +. Por exemplo:

  • u=rw define permissões de leitura e escrita para o usuário dono e remove a permissão de execução
  • o=x define apenas permissão de execução para outros (world), removendo leitura e escrita
  • a=rwx define permissões de leitura, escrita e execução para todos: usuário dono, grupo e outros!

Mas e se você quiser alterar as permissões do usuário de uma forma e as do grupo de outra? Digamos que você queira definir rw para o usuário dono, mas apenas r para o grupo dono? Você pode fazer isso encadeando múltiplos modos no chmod separados por vírgula (,)!

  • chmod u=rw,g=r /challenge/pwn definirá permissões de leitura e escrita para o usuário e somente leitura para o grupo
  • chmod a=r,u=rw /challenge/pwn definirá leitura e escrita para o usuário e somente leitura para o grupo e outros

Além disso, você pode zerar completamente as permissões utilizando - após o =:

  • chmod u=rw,g=r,o=- /challenge/pwn definirá permissões de leitura e escrita para o usuário, somente leitura para o grupo e absolutamente nenhuma permissão para outros

Tenha em mente que esse -, ao aparecer após =, está em um contexto diferente de quando aparece diretamente após u, g ou o (caso em que removeria bits específicos, e não zeraria o bloco).

Este nível aprofunda o nível anterior exigindo alterações de permissões mais radicais, nas quais você precisará utilizar = e encadeamento por vírgulas (,) para atingir o objetivo. Boa sorte!

Como você viu no módulo anterior, existem muitos casos em que usuários comuns (não-root) precisam de privilégios elevados para executar certas tarefas do sistema. O administrador do sistema não pode estar sempre presente para digitar a senha de root toda vez que um usuário precisar executar uma tarefa que apenas o root ou membros do sudoers têm permissão para fazer. Em vez disso, o bit de permissão especial "Set User ID" (SUID) permite que qualquer usuário execute um programa com os privilégios do usuário proprietário daquele arquivo executável.

Esse é exatamente o mecanismo utilizado pelos programas dos desafios para conseguir ler a flag ou, no mundo Linux fora do pwn.college, para viabilizar ferramentas administrativas essenciais como su, sudo e outras. As permissões de um arquivo com o bit SUID se parecem com isto:

hacker@dojo:~$ ls -l /usr/bin/sudo
-rwsr-xr-x 1 root root 232416 Dec 1 11:45 /usr/bin/sudo
hacker@dojo:~$

A letra s no lugar do bit tradicional de execução (x) indica que o programa é executável com SUID. Isso significa que, independentemente de qual usuário execute o programa (desde que possua permissão de execução), o programa rodará com os privilégios do usuário proprietário (neste caso, o usuário root).

Como proprietário de um arquivo, você pode ativar o bit SUID usando o comando chmod:

chmod u+s [program]

Mas muito cuidado! Conceder o bit SUID a um executável cujo dono é o root pode fornecer a invasores um vetor direto de escalação de privilégios para se tornarem root. Você aprenderá muito mais sobre isso no módulo Program Misuse.

Agora, nós permitiremos que você adicione o bit SUID ao programa /challenge/getroot para abrir uma shell de root e você mesmo conseguir fazer cat na flag!


30-Day Scoreboard:

This scoreboard reflects solves for challenges in this module after the module launched in this dojo.

Rank Hacker Badges Score