shc – Generic shell script compiler

February 22nd, 2005

Category: Seguranca

Shell Scripts são frequentemente utilizados para automatizar tarefas como backup de bancos de dados, transferência de arquivos entre servidores, entre outras atividades. A automatização é normalmente feita com a inclusão destes scripts na crontab de servidores.
Entretanto, muitos desses processos exigem o fornecimento de usuários e senhas para o processo ou servidor a ser conectado. Deste forma, muitas vezes o administrador se vê no dilema de incluir dados sensíveis a segurança do seu ambiente nos scripts, em nome da facilidade de gerenciamento dada pela automatização de tarefas.
Uma solução é criar programas binários através do desenvolvimento de programas em C em detrimento ao desenvolvimento em shell script. Mas nem todos os administradores de sistemas são exímios programadores C, além disso prejudicar a compatibilidade com outros sistemas.
O utilitário apresentado neste artigo é um compilador e encriptador de shell scripts. Com ele, é possível “esconder” o fonte do script, gerando um binário encriptado usando RC4.


O shc aceita, através do parâmetro -f, o nome de um shell script e gera uma versão binária com a extensão .x. Na realidade, a compilação é feita sobre um código C, também gerado por ele, que se comporta de forma idêntica ao shell script. O código C é salvo com a extensão .x.c.
Após gerar o binário, você pode remover o shell script do sistema e guardar um cópia dele em um local seguro para futuras atualizações.

O binário gerado não é, de forma geral, distribuível para outros sistemas. Isso acontece justamente pelo mesmo motivo que programas C compilados não são diretamente compatíveis em diversos sistemas, sem uma recompilação.
Além disso, ele é dependente do shell especificado na primeira linha, como #!/bin/bash, por exemplo. Mas o shc possui a opção -r para “relaxar” a segurança e facilitar a distribuição do binário para outros sistemas, desde que estes usem o mesmo sistema operacional.

Outro recurso interessante é a expiração do script (ou binário do script). Com a opção -e especificada no comando de geração do binário você pode configurar uma data no formato dd/mm/yyyy na qual o script não rodará mais. A partir desta data uma mensagem de expiração padrão é exibida ao usuário que executa o binário. Esta mensagem pode ser alterada com a opção -m.

Vamos ver alguns exemplos.

Baixe a última versão do shc, descompacte o pacote e compile:

myuser@myhost:~/downloads/shc$ tar xzvf shc-3.7.tgz
shc-3.7/c2s.sed
shc-3.7/CHANGES
shc-3.7/Copying
shc-3.7/Makefile
shc-3.7/match
shc-3.7/pru.sh
shc-3.7/s2c.sed
shc-3.7/shc.1
shc-3.7/shc.c
shc-3.7/shc.html
shc-3.7/shc.README
shc-3.7/test.bash
shc-3.7/test.csh

myuser@myhost:~/downloads/shc$ cd shc-3.7

myuser@myhost:~/downloads/shc/shc-3.7$ make
cc -Wall -O6 -pedantic shc.c -o shc
*** ¿Do you want to probe shc with a test script?
*** Please try… make test

Não rode o make test. No meu sistema obtive um erro. Mas rodando o comando abaixo consegui executar o teste com sucesso:

myuser@myhost:~/downloads/shc/shc-3.7$ ./shc -v -r -f match
shc shll=sh
shc [-i]=-c
shc [-x]=exec ‘%s’ “$@”
shc [-l]=
shc opts=
shc: cc match.x.c -o match.x
shc: strip match.x

Execute o binário gerado:

myuser@myhost:~/downloads/shc/shc-3.7$ ./match.x
[22215] PAUSED… Hit return!

Ok. Agora vamos criar um outro script de exemplo, desta vez usando o bash.
Crie o arquivo chamado free.sh com o conteúdo abaixo:

#!/bin/bash

echo “In a world without wall and fences, who needs windows and gates?”

Adicione as permissões de execução e teste o script:

myuser@myhost:~/downloads/shc/shc-3.7$ chmod 755 free.sh

myuser@myhost:~/downloads/shc/shc-3.7$ ./free.sh
In a world without wall and fences, who needs windows and gates?

Para gerar uma versão binária e encriptada do script, execute o comando:

myuser@myhost:~/downloads/shc/shc-3.7$ ./shc -v -f free.sh
shc shll=bash
shc [-i]=-c
shc [-x]=exec ‘%s’ “$@”
shc [-l]=
shc opts=
shc: cc free.sh.x.c -o free.sh.x
shc: strip free.sh.x

O binário foi gerado como free.sh.x. A opção -v apenas ativa o modo verbose da compilação, portanto é opcional. Teste sua execução:

myuser@myhost:~/downloads/shc/shc-3.7$ ./free.sh.x
In a world without wall and fences, who needs windows and gates?

Perfeito. Acrescentando a opção -e podemos configurar uma expiração para este binário. Para validar a funcionalidade vamos colocar uma data anterior a de hoje.

myuser@myhost:~/downloads/shc/shc-3.7$ ./shc -v -e 21/02/2005 -m “Bad, bad script. No donut for you.” -f free.sh
shc shll=bash
shc [-i]=-c
shc [-x]=exec ‘%s’ “$@”
shc [-l]=
shc opts=
shc: cc free.sh.x.c -o free.sh.x
shc: strip free.sh.x


Agora é só executar:

myuser@myhost:~/downloads/shc/shc-3.7$ ./free.sh.x
./free.sh.x has expired!
Bad, bad script. No donut for you.

Você viu que mudamos a mensagem padrão com a opção -m. A mensagem default é “Please contact your provider”.

Apenas relembrando, se você tiver dificuldades de rodar o binário em outra máquina (deve ser o mesmo sistema operacional de qualquer forma), use a opção -r e teste novamente.

O help do shc no formato man pages está no arquivo shc.html, descompactado junto com o pacote.

Este artigo é baseado no artigo em inglês de Duane Dunston.


hlbog

2 comments

  • Thiago says:

    Existe uma flag ou commando para fazer rodar em um processador arm ou raspberry ?

    Obrigado.

  • Thiago, não testei. Mas acredito que se você tiver o linux no raspberry ele deve rodar.


  • Leave a Reply

    Your email address will not be published. Required fields are marked *