Tuesday, December 30, 2008

Creating executable of Shell Script

Many times it happen that shell scripts that we write contains sensitive information like password or some sort of keys or path to some sensitive files and if you running such script it become very easy for the normal user to have a look inside the script and get the sensitive information from the code.
There is a program called "shc" which can provide the protection from such cases that developer wants.

shc itself is not a compiler such as cc, it rather encodes and encrypts a shell script and generates C source code with the added expiration capability. It then uses the system compiler to compile a stripped binary which behaves exactly like the original script. Upon execution, the compiled binary will decrypt and execute the code with the shell -c option. Unfortunatelly, it will not give you any speed improvement as a real C program would.

shc's main purpose is to protect your shell scripts from modification or inspection. You can use it if you wish to distribute your scripts but don't want them to be easily readable by other people.

Download shc (here) and untar it:
tar -xzvf shc-X.X.tgz
cd shc-X.X/
make
make install
This will install the shc binary on your box.

Create a file called: script.sh and add the following contents for testing purpose

############################### script.sh ##############################
#!/bin/sh
echo "This is a test shell script by Nikesh"
############################### script.sh ##############################

Now run the command:
shc -f script.sh

The switch "-f" specifies the source script to encrypt. The above command will create two files: script.sh.x.c and script.sh.x. The encrypted shell script is: script.sh.x. Run that binary and see the output:

./script.sh.x
This is a test shell script by Nikesh
Now you can distibute the script.sh.x without any fear

You can also specify a time limit on the shell script so that it will no longer execute after a certain date (expire) and you can specify a custom message to echo back to the user.

shc -e 09/12/2008 -m "Licence expire, please contact author - Nikesh" -f script.sh
./script.sh.x
./script.sh.x has expired!
Licence expire, please contact author - Nikesh

Check out the man pages for more info on "shc".

16 comments:

  1. ... a fine piece of software; now I know, I always looked for something like this ;-]

    Unfortunately, it has vanished in Debian http://packages.qa.debian.org/s/shc.html

    ReplyDelete
  2. this was exactly i was looking for
    thank u

    ReplyDelete
  3. I am getting the following error.
    ==>tar -xzvf shc-3.8.6.tgz
    tar: z: unknown function modifier
    Usage: tar {c|r|t|u|x}[BDeEFhilmnopPqTvw@[0-7]][bfk][X...] [blocksize] [tarfile] [size] [exclude-file...] {file | -I include-file | -C directory file}...

    pls help.

    ReplyDelete
  4. Bipsy use first gunzip and then use tar xvf

    ReplyDelete
  5. i have tried compiling my script using the command below

    shc -r -v -f

    when i ran the ./scriptname.sh.x, it works!

    but when i copied the scriptname.sh.x to another linux machine, give it the permission (chmod 777), it throws an error...

    -bash : scriptname.sh.x: cannot execute binary file

    any ideas?

    ReplyDelete
  6. * Try with simple "hello world" prog and see it this works.

    * this also leads me to think that the binary may be corrupt while transfering, please go back and recheck everything, just to be sure.

    * This error may also mean that the binary file was not compiled for that particular platform.
    what distribution are you using?

    * This problem sometimes occurs because either the application was built for 64-bits but you are running a 32-bit environment, or it was compiled for an incompatible processor type.

    Please check ...

    ReplyDelete
  7. Also,

    “-r” – Tells shc command to relax the security measure i.e. make a redistributable binary which executes on different systems running the same operating system (from man page).

    ReplyDelete
  8. hi Nikesh,

    i have tried even with a simple program, the compiled script couldnt run. it gave the same error.

    i have also checked the md5sum hash value. both (the origin server and the other server) has the same values

    i did try compiling with diff arguments,

    shc -f scriptname.sh
    shc -r -v -f scriptname.sh
    CFLAGS=-static shc -r -v -f scriptname.sh

    but all gave me the same error message when i copied it across.. "
    -bash : scriptname.sh.x: cannot execute binary file"

    ReplyDelete
  9. Are you running the same OS on both the machine?

    “-r” – Tells shc command to relax the security measure i.e. make a redistributable binary which executes on different systems running the same operating system (from man page).

    ReplyDelete
  10. Hi Nikesh,

    yes, both machine are running the same OS and built...

    ReplyDelete
  11. By far, Linux is the best Operating System =

    ReplyDelete
  12. So I have used shc fine up until now. I have developed some scripts and used shc. I have never ever used the expiration date function however I have been getting reports that the script is now saying that it is expired. This makes no sense at all and I am unable to replicate the problem. I am not sure what the deal is. The only thing I can think of is to actually set an expiration date for 2099..

    ReplyDelete
  13. I am having issues running compiled program using shc. Follow is what I did.

    OS: AIX 6.1TL5

    1- Installed gcc
    2- export CC=/usr/bin/gcc
    3- Installed shc
    4- Wrote a shell program, test.sh;
    #!/usr/bin/sh
    echo "Hello World"

    5- # shc -v -r -f test.sh
    shc shll=sh
    shc [-i]=-c
    shc [-x]=exec %s "$@"
    shc [-l]=
    shc opts=
    shc: /usr/bin/gcc test.sh.x.c -o test.sh.x
    shc: strip test.sh.x

    and when I try to run the compiled program, that's what I get;
    6- ./test.sh.x
    Killed

    ReplyDelete
  14. Hi Carl
    I am also got the same error.
    * Then i found, I am compiled the program in 64 bit and transferred to 32 bit. So that i got the error.

    -bash : scriptname.sh.x: cannot execute binary file

    ReplyDelete
  15. Hi,
    if we give ps -ef, we will be able to see the complete shell script source as argument for the binary(you need give ps -ef before the script completes.)

    ReplyDelete
  16. Hi I am also getting the same error .....

    I tries with

    shc -f script.sh
    shc -r -v -f script.sh

    both gave me a executable binary and a c source code of my script. but when I am trying to execute my script "script.sh.x" i am getting an ERROR like
    [somenumber]+ Stopped

    can someone help me to fix it ?

    ReplyDelete