wget script, mas canaliza-o para bash apenas se SHA256 do script coincidir com o one-liner

7

wget http://example.com/install.sh -O - | bash executa o script automaticamente, mas devido a possíveis ataques de MITM (TLS), etc., isso não é seguro. É possível construir um one-liner que baixe o script, mas o execute apenas se o hash corresponder ao especificado no one-liner? Seria bom se o one-liner imprimisse algo como Warning! Hash mismatch se a verificação de hash falhasse.

    
por maqp 03.04.2017 / 21:11

2 respostas

3

Você quer baixar e executar http://example.com/install.sh .

Por enquanto, suponho que você tenha seu hash SHA256 armazenado localmente em um arquivo chamado my-sha256.txt . O arquivo contém apenas o próprio hash e um caractere linebreak no estilo Unix, portanto, seu tamanho deve ter exatamente 65 bytes. Você pode criá-lo simplesmente executando isto:

sha256sum ORIGINAL_FILE.SH | grep -Eo '^\w+' > my-sha256.txt

Como você distribui esse arquivo de hash de sua máquina de desenvolvimento para o cliente não faz parte dessa resposta (ainda assim, você pode esclarecer sua dúvida e pedir-me para atualizar essa peça com base em suas especificações detalhadas).

O comando real que seu cliente precisa executar para fazer o download, verificar e, com êxito, executar o script pode ser assim:

t=$(mktemp) && wget 'http://example.com/install.sh' -qO "$t" && if sha256sum "$t" | grep -Eo '^\w+' | cmp -s my-sha256.txt ; then bash "$t" ; else echo FAIL ; fi ; rm "$t"

Versão ligeiramente encurtada e feia sem espaço em branco:

t=$(mktemp)&&wget 'http://example.com/install.sh' -qO"$t"&&if sha256sum "$t"|grep -Eo '^\w+'|cmp -s my-sha256.txt;then bash "$t";else echo FAIL;fi;rm "$t"

Colocado em várias linhas para facilitar a leitura:

t=$(mktemp) && 
wget 'http://example.com/install.sh' -qO "$t" && 
if sha256sum "$t" | grep -Eo '^\w+' | cmp -s my-sha256.txt 
    then bash "$t" 
    else echo FAIL 
fi 
rm "$t"

Se você quiser fornecer diretamente o hash dentro do comando como string em vez de ler um arquivo, simplesmente use uma das minhas versões de comando originais acima e substitua a ocorrência de my-sha256.txt por <(echo YOUR_HASH) , inserindo seu hash real do espaço reservado "YOUR_HASH", é claro.

Explicação:

O script / one-liner primeiro cria um arquivo temporário usando mktemp (usa a pasta temp do sistema /tmp ).
Em seguida, ele usa wget para baixar o script de instalação da URL especificada e salvá-lo no arquivo temporário.
Agora, calculamos sua soma de hash, filtramos apenas o valor de hash da saída de sha256sum e comparamos com o que armazenamos em my-sha256.txt .
Se os dois hashes forem iguais, invocaremos bash com nosso arquivo de script temporário como argumento, senão, echo FAIL ou você poderá gerar uma mensagem de erro personalizada.
No final, limpamos excluindo nosso arquivo temporário nos dois casos.

No entanto, voltando ao problema de distribuir o hash com segurança para verificar o script original, esta solução acima não ajudará muito, já que resolve um problema criando outro do mesmo tipo.

O que você realmente deve fazer é criar um par de chaves GPG (e publicar sua chave pública em um servidor de chaves), assinar seu script com ele e oferecer o binário assinado compactado para download. Em seguida, permita que o cliente verifique e decodifique o script usando gpg novamente e execute-o com sucesso.

    
por Byte Commander 03.04.2017 / 23:55
0

Como as impressões digitais de GPG usam hash SHA-1 inseguro, aqui está um one-liner que permite a autenticação com o hash não oficial SHA256 calculado a partir da chave pública com

gpg --export <key ID> | sha256sum

comando:

h="<SHA256 hash of exported public key>"; fp="<PGP key SHA1 fingerprint>"; f='key.pub'; gpg --keyserver pgp.mit.edu --recv $fp && gpg --export $fp > $f && if sha256sum $f | grep -Eo '^\w+' | cmp -s <(echo $h); then rm $f && wget https://example.com/install.sh{,.asc} -q && gpg --verify install.sh{.asc,} && bash install.sh; else rm $f; echo "ERROR: Signing key had invalid SHA256 hash"; fi;

    
por maqp 28.02.2018 / 18:54