Originally published February 26, 2018 @ 7:37 pm
Unix shell scripting language is run by the command-line interpreter and, as such, can be read and understood by anyone with sufficient access and experience. Sometimes this is not a good thing. Sometimes you want people and applications to be able to run the script but not necessarily look under its hood.
Various obfuscation techniques for Unix shell scripts go back decades. The methods include replacing variable names with odd-looking strings; removing or adding spaces and comments; inserting bogus functions that do nothing; replacing Latin letters with international or extended characters.
This by no means truly conceals a script’s nature, but obfuscation can render the script nearly indecipherable. This is especially true for more complex scripts. Here’re some of the script obfuscation tools you can use.
The good old obfsh
you can get from here. Just run obfsh -h
to see a summary of available options. You can add this convenient alias to your .bashrc
so you don’t have to remember those options:
alias obfuscate='obfsh -c 2 -d 1 -e 2-27 -g 23-2+100-309 -i -f'
Consider this simple script that tells you if the argument is a positive or negative integer (or not an integer at all):
#!/bin/sh i='^(-)?[0-9]+$' if ! [[ $1 =~ $i ]] ; then echo "error: $1 is not an integer" >&2; exit 1 fi if [ $1 -gt 0 ]; then echo "$1 is positive" elif [ $1 -lt 0 ]; then echo "$1 is negative" elif [ $1 -eq 0 ]; then echo "$1 is zero" fi
And here’s the obfuscated version using the alias set above:
#!/bin/sh : '$/+d 0) Zz1IF G ] .o F= S ▒0 $ 5. 1 Pj tN*d b 4 &%▒uQ J34 2l ' a=1; c=0 # comment i='^(-)?[0-9]+$' f_() { while read l; do echo $l; done < $f ; } # comment if ! [[ $1 =~ $i ]] ; then echo "error: $1 is not an integer" >&2; exit 1 fi if [ $1 -gt 0 ]; then echo "$1 is positive" elif [ $1 -lt 0 ]; then echo "$1 is negative" elif [ $1 -eq 0 ]; then echo "$1 is zero" fi : '$/+d 0) Zz1IF G ] .o F= S ▒0 $ 5. 1 Pj tN*d b 4 &%▒uQ J34 2l
Not terribly confusing, but better than nothing.
Another option that produces a somewhat more confusing output is bash-obfuscate
Node.js CLI utility. You can check it out here. Here’s what it does to the script from the previous example:
apt-get install npm nodejs ln -s /usr/bin/nodejs /usr/bin/node npm install -g bash-obfuscate bash-obfuscate sample.sh -o sample2.sh
The result is much better, but still fairly easy to figure out and reverse:
z=" ";Fz=' [[ ';mz=']; t';pz='1 -e';Wz=' 1';Kz='en';gz='tive';Dz=']+$'\''';Cz='[0-9';Yz='if [';jz=' [ $';Vz='exit';Pz='is n';iz='elif';Iz=' ]] ';rz='zero';Lz='echo';az='0 ];';Ez='if !';ez=' is ';Mz=' "er';nz='hen';dz=' "$1';fz='posi';Hz='~ $i';oz='nega';Oz=' $1 ';hz='"';Sz='tege';Xz='fi';Az='i='\''^';Jz='; th';Gz='$1 =';Rz='n in';Bz='(-)?';cz='n';Uz='&2; ';bz=' the';Nz='ror:';qz='q 0 ';lz='t 0 ';Tz='r" >';Qz='ot a';kz='1 -l';Zz='-gt '; eval "$Az$Bz$Cz$Dz$z$Ez$Fz$Gz$Hz$Iz$Jz$Kz$z$Lz$Mz$Nz$Oz$Pz$Qz$Rz$Sz$Tz$Uz$Vz$Wz$z$Xz$z$Yz$Oz$Zz$az$bz$cz$z$Lz$dz$ez$fz$gz$hz$z$iz$jz$kz$lz$mz$nz$z$Lz$dz$ez$oz$gz$hz$z$iz$jz$pz$qz$mz$nz$z$Lz$dz$ez$rz$hz$z$Xz"
Perhaps the best option I’ve found so far is the shell compiler. Here’s a quick example:
git clone https://github.com/neurobin/shc.git cd shc ./configure make make install echo -e '#!/bin/bash\necho this is a test' > test.sh && chmod 750 test.sh shc -U -f test.sh -o testbin file testbin testbin: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, stripped ./testbin this is a test
To an extent, this can even be used to obfuscate a password inside the compiled script. For example, if you run strings testbin | grep test
you will see nothing. Having said that, there is a better way to hide passwords in interactive scripts using gpg
.
Experienced Unix/Linux System Administrator with 20-year background in Systems Analysis, Problem Resolution and Engineering Application Support in a large distributed Unix and Windows server environment. Strong problem determination skills. Good knowledge of networking, remote diagnostic techniques, firewalls and network security. Extensive experience with engineering application and database servers, high-availability systems, high-performance computing clusters, and process automation.