Existe um shell que verifica se o código está assinado?

19

Eu estava brincando com o PowerShell esta semana e descobri que você precisa assinar seus scripts para que eles possam ser executados. Existe alguma funcionalidade segura semelhante no Linux relacionada à prevenção de execução de scripts bash?

A única funcionalidade semelhante a esta, que eu conheço é a do SSH que exige uma determinada chave.

leeand00
fonte
2
Soa um pouco como uma solução ad-hoc para a assinatura de pacotes para mim. Não sei se o Windows tem um pacote criptográfico assinando como o Linux.
Wildcard
6
@ leeand00 Um script é um caso especial de um pacote de software e não vejo sentido em destacar esse caso.
Gilles 'SO- stop be evil'
2
O mecanismo que mais me agrada é a maneira como o ChromeOS faz isso - colocando o único sistema de arquivos não sinalizado noexecem uma partição somente leitura em um dispositivo de bloco assinado pelo dm-verity.
Charles Duffy
1
source.android.com/security/verifiedboot fala sobre a adoção pelo Android desse recurso (inicialmente ChromeOS).
Charles Duffy
1
Você pode considerar o bash como um monte de comandos que podem ser digitados manualmente na interface da linha de comandos. Qual é o sentido de restringir os scripts quando você pode digitar o conteúdo na linha de comando?
Ding-Yi Chen

Respostas:

11

Se você está bloqueando a capacidade dos usuários de executar scripts sudo, poderá usar a digestfuncionalidade.
Você pode especificar o hash de um script / executável no sudoersqual será verificado sudoantes de ser executado. Portanto, embora não seja o mesmo que assinar, ele oferece uma garantia básica de que o script pelo menos não foi modificado sem que os sudoers também sejam modificados.

Se um nome de comando for prefixado com um Digest_Spec, o comando só corresponderá com êxito se puder ser verificado usando o resumo SHA-2 especificado. Isso pode ser útil em situações em que o usuário que está chamando sudo tem acesso de gravação ao comando ou ao diretório pai. Os seguintes formatos de resumo são suportados: sha224, sha256, sha384 e sha512. A cadeia pode ser especificada no formato hexadecimal ou base64 (base64 é mais compacto). Existem vários utilitários capazes de gerar resumos SHA-2 em formato hexadecimal, como openssl, shasum, sha224sum, sha256sum, sha384sum, sha512sum.

http://www.sudo.ws/man/1.8.13/sudoers.man.html

batfastad
fonte
Isso vai me prender até eu ler sobre o SE Linux e fazer o certo.
precisa saber é o seguinte
13

Sim e não.

A distribuição de software Linux funciona de maneira um pouco diferente da distribuição de software Windows. No mundo Linux (não incorporado), o método principal para distribuir software é por meio de uma distribuição (Ubuntu, Debian, RHEL, Fedora, Arch, etc.). Todas as principais distribuições assinam seus pacotes sistematicamente há cerca de uma década.

Quando o software é distribuído de forma independente, cabe ao fornecedor decidir como enviará o software. Bons fornecedores fornecem fontes de pacotes compatíveis com as principais distribuições (não há mecanismo de distribuição unificado para todo o Linux: a distribuição de software é um dos principais pontos de diferenciação entre distribuições) e assinadas com a chave do fornecedor. As distribuições Linux raramente agem como uma autoridade de assinatura para fornecedores terceirizados (a Canonical faz isso com parceiros do Ubuntu, mas isso cobre muito poucos fornecedores), e acho que todas as principais distribuições usam a Web PGP de confiança em vez da infraestrutura de chave pública TLS, portanto cabe ao usuário descobrir se deseja confiar em uma chave.

Não há mecanismo especial que destaque pacotes de software que consistem em um único script a partir de pacotes de software que consistem em um executável nativo, um arquivo de dados ou vários arquivos. Nenhuma verificação de assinatura também é incorporada a qualquer interpretador de script comum, porque verificar um pacote de software é uma preocupação completamente ortogonal da execução de um script.

Eu acho que o Windows anota arquivos com sua origem e requer confirmação do usuário para executar um arquivo cuja origem é "baixada" em vez de "local". O Linux realmente não tem um mecanismo semelhante. O mais próximo é a permissão de execução: um arquivo baixado não tem permissão de execução, o usuário precisa ativá-lo explicitamente ( chmod +xna linha de comando ou a ação equivalente em um gerenciador de arquivos).

Gilles 'SO- parar de ser mau'
fonte
2
FWIW, além disso, o PowerShell pode ser configurado (por configurações de política) para executar apenas scripts assinados e esta política pode ser configurada para que todos os scripts sejam assinados ou apenas scripts de "origem remota" ou nenhum script. Funciona melhor em um ambiente AD com gerenciamento de chaves e gerenciamento central de políticas. Ele pode ser contornado :-)
Stephen Harris
@StephenHarris Bem, sim, se você configurá-lo para desvio ...
leeand00
@ leeand00 - Aparentemente, a codificação base64 também funciona como um desvio, mas não sei se foi fechada nas versões mais recentes do PowerShell.
Stephen Harris
1
@ leeand00 - veja darkoperator.com/blog/2013/3/5/… para se divertir :-) Passe basicamente o script codificado em base64 como parâmetro na linha de comando :-) Fácil o suficiente para empacotar!
Stephen Harris
2
O SeLinux faz anotações nos arquivos com sua origem. É uma de suas principais premissas.
loa_in_ 9/08/16
10

O Linux não fornece a capacidade de limitar a execução de scripts bash com base em assinaturas digitais.

Há algum trabalho na autenticação de executáveis ​​binários. Consulte https://lwn.net/Articles/488906/ para obter informações.

Quentin Fennessy
fonte
Voto positivo para resposta direta sem sugerir uma solução alternativa do hackey.
User394
8

Em uma palavra, "não".

O Linux não diferencia realmente entre executáveis ​​e scripts; o #!no início é uma maneira de dizer ao kernel qual programa executar para avaliar a entrada, mas não é a única maneira que um script pode ser executado.

Então, por exemplo, se eu tiver um script

$ cat x
#!/bin/sh 
echo hello

Então eu posso executar isso com o comando

$ ./x

Isso fará com que o kernel tente executá-lo, localize o #!e então efetivamente execute /bin/sh x.

No entanto, eu também poderia executar qualquer uma dessas variantes:

$ sh ./x
$ bash ./x
$ cat x | sh
$ cat x | bash
$ sh < x

ou mesmo

. ./x

Portanto, mesmo que o kernel tente impor a assinatura na execcamada, podemos contornar isso executando apenas o interpretador com o script como parâmetro.

Isso significa que o código de assinatura teria que estar no próprio intérprete. E o que impediria um usuário de compilar sua própria cópia de um shell sem o código de execução de assinatura?

A solução padrão para isso não é usar assinatura, mas usar Controles de Acesso Obrigatório (MAC), como SELinux. Com os sistemas MAC, você pode especificar exatamente o que cada usuário tem permissão para executar e fazer a transição de camadas. Assim, por exemplo, você pode dizer "usuários normais podem executar qualquer coisa, exceto o servidor da web e os processos CGI podem acessar apenas itens do /var/httpddiretório; todo o resto é rejeitado".

Stephen Harris
fonte
1
This means that signing code would have to be in the interpreter itself. And what would stop a user from compiling their own copy of a shell without the signing enforcement code?Não permitir a execução de nenhum executável não assinado faria isso, se o usuário não tiver a chave de assinatura. Já existem vários projetos * nix para isso.
alzee
2

As distribuições Linux geralmente têm gnupg . Parece-me que tudo o que você quer é um simples invólucro de bash que verifique uma assinatura de gpg desanexada no script de argumento e só continue executando o script se a verificação for bem-sucedida:

#!/bin/sh
gpgv2 $1.asc && bash "$@"
PSkocik
fonte
A única coisa que este não presente está a executar um script que alguém acabou de fazer ... por conta própria ...
leeand00
2

A contra-pergunta que vem à mente imediatamente é "Por que você deseja impedir os usuários de executar os programas que eles escreveram? " Existem várias possibilidades:

  1. É literalmente impossível detectar quem criou o código em primeiro lugar. O proprietário do arquivo de script é quem realmente salvou o conteúdo desse arquivo, independentemente de onde ele veio. Portanto, impor uma assinatura é apenas um substituto complicado para uma caixa de diálogo de confirmação: "Tem certeza de que deseja fazer isso?" No Linux, parte desse problema é resolvida de forma transparente com pacotes assinados e atenuada pelo fato de os usuários terem acesso limitado por padrão. Também é esperado que o usuário saiba que executar o código de outras pessoas pode ser perigoso *.
  2. Na mesma linha, assinar um script é uma operação muito mais complexa do que salvar um arquivo. Na melhor das hipóteses, isso faz com que o usuário perceba que está executando uma ação semelhante à assinatura de um documento e deve inspecionar o que diz antes de continuar. Provavelmente, ele simplesmente garante um nível mínimo de proficiência técnica por parte do usuário para poder executar o script. Na pior das hipóteses, demonstra uma disposição de pular uma longa série de aros para executar o que eles queriam. Proficiência técnica é assumida no Linux *.
  3. É mais provável que as pessoas detectem código obviamente malicioso ao digitar / colar uma série de comandos na linha de comando. Os trechos de texto simples que devem ser copiados e colados geralmente são menores que a série de comandos necessários para fazer algo adequadamente nefasto. O usuário também pode copiar e colar cuidadosamente todas as linhas separadamente, entendendo o que acontece. Com um script, é possível que o usuário nunca tenha visto o código. Essa pode ser uma aplicação útil de scripts assinados, com o custo de complacência muito comum após a 12ª vez em que você o fizer.

* Isso provavelmente está se tornando cada vez menos verdadeiro à medida que mais pessoas começam a usar o Linux

l0b0
fonte
1

A razão pela qual os sistemas evoluíram de maneira diferente é que o Linux possui o atributo de arquivo 'exec' e o Windows usa extensões de arquivo para determinar a executabilidade.

Portanto, no Windows, é fácil induzir o usuário a baixar um arquivo com a extensão ".exe", ".bat", ".scr", que ficará oculta por padrão . Clicar duas vezes nesse arquivo forneceria a execução de código arbitrário. Portanto, um grande mecanismo de rastreamento de origem e assinatura de executável / script foi criado para mitigar esse risco.

No Linux, você pode obter um arquivo para o usuário, mas não pode forçar facilmente a configuração do bit 'exec'. Além disso, é possível tornar todo o sistema de arquivos 'noexec'.

Em qualquer caso, você pode executar um script explicitamente chamando o intérprete. Você pode até criar scripts de shell em tempo de execução e canalizá-los para "sh" ou executar "sh -c".

pjc50
fonte
0

Por costume, muitos programas de arquivamento não preservam o bit de execução nos arquivos contidos. Isso torna impossível executar executáveis ​​arbitrários. Bem, quase.

O ponto é, o que foi descrito em outra resposta que a falta de bit de execução não impede que você passe esse script diretamente para bash. Embora seja discutível que a maioria desses scripts sejam bashscripts, o shebang pode especificar qualquer programa como intérprete. Isso significa que cabe ao usuário executar o intérprete apropriado se decidir ignorar a semântica executável.

Embora isso não seja muito, isso abrange praticamente a prevenção de executar executáveis ​​não confiáveis ​​em * nixes com apenas kernel e shell .

Como mencionei em um dos comentários, há outra camada de proteção - SeLinux- que rastreia a origem dos arquivos com base em um conjunto de regras. Uma configuração SeLinuxnão permitiria, por exemplo, que o root executasse um executável com o conjunto de bits executável baixado da Internet, mesmo se você copiar e mover o arquivo. Pode-se adicionar uma regra de que esses arquivos só podem ser executados através de outro binário que verificaria a assinatura, não muito diferente do que você mencionou na sua pergunta.

Portanto, no final, é uma questão de configuração das ferramentas comumente pré-instaladas, e a resposta é sim .

loa_in_
fonte
Muitos programas de arquivamento não preservam o bit de execução nos arquivos contidos . Bem, isso é uma desvantagem quando você realmente deseja usá-lo para arquivamento. Felizmente tar não preservar a executar bit.
Pjc50
Você tem que usar o tar -p código
loa_in_ 9/08/16
-p, --preserve-permissions, --same-permissionsmeios extrair informações sobre permissões de arquivo (padrão para superusuário)
loa_in_
Não, você NÃO precisa de -p. Entendo o que a página de manual diz, mas não é o que acontece. touch permtest; chmod +x permtest; tar cf permtest.tar.gz permtest; rm permtest; tar xf permtest.tar.gz; ls -l permtest- é executável aqui e não sou root.
domen
Vou tentar melhorar minha resposta então.
loa_in_ 9/08/16