O que exatamente diferencia o usuário root de todos os outros usuários?

6

Quais são as diferenças fundamentais entre uma conta arbitrária e root ? É apenas o UID sendo algo diferente de zero?

Então, o que exatamente o su binário faz e como ele eleva o usuário ao root? Eu sei que um usuário deve primeiro fazer parte do grupo sudo através do que encontramos em /etc/sudoers .

# User privilege specification
root    ALL=(ALL:ALL) ALL

# Members of the admin group may gain root privileges
%admin ALL=(ALL) ALL

# Allow members of group sudo to execute any command
%sudo   ALL=(ALL:ALL) ALL

Observando as permissões do executável su , encontramos -rwsr-xr-x , ou 4755 (ou seja, setuid está definido).

É o binário su que lê este arquivo de configuração e verifica se o usuário que está solicitando permissões de root faz parte do grupo sudo ou admin ? Em caso afirmativo, o binário gera outro shell como root (considerando o bit setuid ) assumindo que o usuário faz parte dos grupos esperados e conhece a senha do usuário apropriada que está tentando ser substituída (.eg root , em particular)?

tl; dr O ato de elevação de privilégio depende do setuid bit no binário su , ou existem outros mecanismos para alterar o UID do processo atual? No caso do primeiro, parece que somente o EUID mudaria deixando o UID! = EUID. Isso é sempre um problema?

relacionado Como tudo isso é emulado no ambiente do Android? Tanto quanto eu li, o acesso ao root foi totalmente removido - embora os processos ainda sejam executados nesse nível de privilégio.

Se removêssemos sudo e su isso seria suficiente para impedir a elevação de privilégios ou o Android tomaria outras medidas?

    
por sherrellbc 02.03.2016 / 19:56

3 respostas

10

Raiz é usuário 0

A principal coisa é o ID do usuário 0. Existem muitos lugares no kernel que verificam o ID do usuário do processo de chamada e concedem permissão para fazer algo apenas se o ID do usuário for 0.

O nome do usuário é irrelevante; o kernel nem sabe sobre nomes de usuários.

O mecanismo de permissão do Android é idêntico no nível do kernel, mas completamente diferente no nível do aplicativo. O Android tem um usuário root (UID 0), assim como qualquer outro sistema baseado em um kernel Linux. O Android não tem contas de usuário, e na maioria das configurações não permite que o usuário (como no ser humano que opera e possui o dispositivo) execute ações como o usuário root. Um Android "enraizado" é uma configuração que permite que o proprietário / usuário do dispositivo execute ações como root.

Como funciona o setuid

Um executável setuid é executado como o usuário que possui o executável. Por exemplo, su é setuid e pertence a root, portanto, quando qualquer usuário o executa, o processo executando su é executado como usuário root. O trabalho de su é verificar se o usuário que o chama tem permissão para usar a conta raiz, executar o comando especificado (ou um shell se nenhum comando for especificado) se essa verificação for bem-sucedida e sair se essa verificação falhar . Por exemplo, su pode pedir ao usuário para provar que conhece a senha do root.

Mais detalhadamente, um processo tem três IDs de usuário : o eficaz UID , que é usado para verificações de segurança; o real UID, que é usado em algumas verificações de privilégio, mas é principalmente útil como backup do ID do usuário original e do ID do usuário salvo que permite que um processo mude temporariamente seu UID efetivo para o real ID do usuário e, em seguida, voltar ao antigo UID efetivo (isso é útil, por exemplo, quando um programa setuid precisa acessar um arquivo como o usuário original). A execução de um executável setuid define o UID efetivo para o proprietário do executável e mantém o UID real.

A execução de um executável setuid (e mecanismos semelhantes, por exemplo, setgid) é a única maneira de elevar os privilégios de um processo. Quase tudo o resto só pode diminuir os privilégios de um processo.

Além do Unix tradicional

Até agora eu descrevi sistemas tradicionais Unix. Tudo isso é verdade em um sistema Linux moderno, mas o Linux traz várias complicações adicionais.

O Linux tem um sistema de capacidade . Lembre-se de como eu disse que o kernel tem muitas verificações onde apenas os processos em execução como ID de usuário 0 são permitidos? Na verdade, cada cheque recebe seu próprio recurso (bem, não é bem assim, algumas verificações usam o mesmo recurso). Por exemplo, há um recurso para acessar soquetes de rede brutos e outro recurso para reinicializar o sistema. Cada processo tem um conjunto de recursos ao lado de seus usuários e grupos. O processo passa a verificação se estiver executando como usuário 0 ou se tiver a capacidade correspondente à verificação. Um processo que requer um privilégio específico pode ser executado como um usuário não raiz, mas com o recurso necessário; isso limita o impacto se o processo tiver uma falha de segurança. Um executável pode ser setcap para um ou mais recursos: isso é semelhante ao setuid, mas funciona no conjunto de recursos do processo em vez do ID do usuário do processo. Por exemplo, o ping só precisa de soquetes de rede brutos, então pode ser setcap CAP_NET_RAW em vez de setuid root.

O Linux tem vários módulos de segurança , sendo o mais conhecido SELinux . Os módulos de segurança introduzem verificações de segurança adicionais, que podem ser aplicadas até mesmo a processos em execução como raiz. Por exemplo, é possível (não fácil!) Configurar o SELinux para executar um processo como o ID do usuário 0, mas com tantas restrições que não pode realmente fazer nada .

O Linux tem namespaces de usuário . Dentro do kernel, um usuário não é apenas um ID do usuário, mas um par que consiste em um ID do usuário e um namespace. Os namespaces formam uma hierarquia: um namespace filho refina as permissões dentro de seu pai. O usuário todo poderoso é o usuário 0 no namespace raiz. O usuário 0 em um namespace tem poderes apenas dentro desse namespace. Por exemplo, o usuário 0 em um namespace de usuário pode representar qualquer usuário desse namespace; mas do lado de fora todos os processos nesse namespace são executados como o mesmo usuário.

    
por 03.03.2016 / 02:02
4

No Linux há 4 UIDs: RUID (real), EUID (efetivo), SUID (salvo), FSUID (sistema de arquivos).

Estes nada mais são do que números e são propriedades de processos, que são armazenados em um bloco de controle na tabela de processos do Kernel.

O UID '0' tem uma característica especial, pois denota o usuário root , que geralmente tem direitos de acesso irrestrito.

su e sudo são programas para alterar os direitos de acesso efetivo do usuário, iniciando um novo subprocesso com o EUID definido para o novo UID por meio do bit SetUID de su . Este processo su, em seguida, gera um novo shell novamente em um novo subprocesso com os 4 UIDs configurados para o novo valor de UID.

O exemplo a seguir deve demonstrar isso. Digamos que um usuário rda esteja logado em um terminal ssh. ps fax mostrará os seguintes processos envolvidos:

472 ?        Ss     0:00 /usr/sbin/sshd -D
9151 ?        Ss     0:00  \_ sshd: rda [priv]
9153 ?        S      0:00  |   \_ sshd: rda@pts/1
9154 pts/1    Ss+    0:00  |       \_ -bash

4 processos, o daemon ssh, dois processos para a sessão ssh (e terminal?), o último processo é um shell de login (denotado por um - na frente de bash )

ps faw -eo euser,ruser,suser,fuser,f,comm mostrará os UIDs dos processos:

EUSER    RUSER    SUSER    FUSER    F COMMAND
...
root     root     root     root     4 sshd
root     root     root     root     4  \_ sshd
rda      rda      rda      rda      5  |   \_ sshd
rda      rda      rda      rda      0  |       \_ bash

Invocar su seguido por uma autenticação bem-sucedida resultará no seguinte:

EUSER    RUSER    SUSER    FUSER    F COMMAND
...
root     root     root     root     4 sshd
root     root     root     root     4  \_ sshd
rda      rda      rda      rda      5  |   \_ sshd
rda      rda      rda      rda      0  |       \_ bash
root     rda      root     root     4  |           \_ su
root     root     root     root     4  |               \_ bash

O processo 'bash' inicia um novo processo-filho 'su' com o EUID definido pelo bit SetUID para '0' (root), o RUID ainda está configurado para o UID do rda neste momento. O processo 'su' inicia novamente um novo processo-filho com um novo shell, concedendo acesso ao usuário root (o RUID agora está configurado para '0' também). O usuário permanece em seu diretório de trabalho e o novo shell usará o mesmo ambiente que o shell pai, por exemplo:

server:/home/rda# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
server:/home/rda# pwd
/home/rda

O shell pode ser fechado com exit e o usuário estará no shell pai com seus direitos de acesso originais.

A situação é diferente se 'su' for invocado com um parâmetro hífen '-' :

rda@server:~$ su -
Password:
server:~# echo $PATH
/root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
server:~# pwd
/root

O ambiente shell mudou, como o novo shell é um shell de login, veja '-su' , que executa alguns scripts de configuração adicionais:

 9151 ?        Ss     0:00  \_ sshd: rda [priv]
 9153 ?        S      0:00  |   \_ sshd: rda@pts/1
 9154 pts/1    Ss     0:00  |       \_ -bash
 9613 pts/1    S      0:00  |           \_ su -
 9614 pts/1    S+     0:00  |               \_ -su

Um shell de login deve ser fechado com logout .

Em teoria, acho que é possível evitar que o usuário obtenha privilégios elevados removendo sudo e su e não dá a possibilidade de fazer logon no sistema diretamente (via terminal, ssh, etc) e sem acesso físico ao dispositivo.

Atualização: processo de enraizamento no Android

Como explicado em detalhes aqui , os métodos possíveis para fazer o root de um dispositivo Android dependem do carregador de inicialização e da propriedade do sistema Android ro.secure .

O destino é sempre o mesmo, para instalar o su binário em /system e torná-lo setuid(0) .

Dispositivo com bootloader desbloqueado:

Puxe a ROM de estoque com dd do dispositivo, adicione su , reembale (ou faça o download de uma ROM modificada), reinicialize o dispositivo no modo flash e exiba a ROM modificada.

Dispositivo com ro.secure = 0 :

Esta propriedade do sistema controla se os comandos digitados em adb shell são executados como raiz ( ro.secure=0 ) ou como um usuário não privilegiado ( ro.secure=1 ) O valor de ro.secure é definido no tempo de inicialização do arquivo default.prop no diretório root , que é acessível apenas pelo usuário root e, portanto, seguro.

Na maioria dos casos, esse ro.secure está definido como 1 , mas alguns fabricantes definem isso como 0 . Isso pode ser verificado executando o comando getprop ro.secure em um emulador de terminal no dispositivo ou em um shell adb. Se estiver configurado para 0 , o enraizamento é bastante fácil, conecte-o a um computador, execute adb , monte /system como leitura-gravação, instale su .

Dispositivo com bootloader bloqueado:

Esse dispositivo tem uma recuperação que não permite o flash de uma ROM personalizada, que não foi assinada pelo fabricante. A única maneira de obter acesso root nessa situação é explorando uma vulnerabilidade de segurança em um dos processos do sistema em execução, que são executados no modo privilegiado e o permitem para permitir a execução de "código arbitrário". Este código normalmente monta /system e instala su permanentemente.

    
por 03.03.2016 / 00:47
2

Em geral, é apenas que o uid efetivo é 0. O bit "setuid" em executáveis na verdade configura o fluxo efetivo do processo. Se o uid efetivo não for zero e o uid real não for zero, o programa está sendo executado como um usuário "não privilegiado". O seguinte se aplica:

Unprivileged processes may only set the effective user ID to the real user ID, the effective user ID, or the saved set-user-ID. Unprivileged users may only set the real user ID to the real user ID or the effective user ID.

No que diz respeito ao Android, não, eu não acho que remover sudo e su seja suficiente - se algum programa puder ter o conjunto de bits seteuid, esse programa pode potencialmente ser executado com uid = 0. Se existe qualquer possibilidade de ter acesso ao sistema de arquivos interno como root a qualquer momento, então tal programa pode ser introduzido e o acesso root é viável.

    
por 02.03.2016 / 22:06