How to make it run
The author of your linked repo did not provide any method to automatically obfuscate your script. You have to do it yourself, but I wouldn't recommend to do so.
The Obfuscation Idea
Your linked obfuscation method replaces each character by a variable containing said character. That way a string equal to the original command is built. Then said string is passed to eval
. Example:
cmd a "b c"
becomes something like
Ba=a; Bb=b; Bc=c; Bm=m; Bd=d; Cs=' '; Cq='"'
eval $Bc$Bm$Bd$Cs$Ba$Cs$Cq$Bb$Cs$Bc$Cq
Why The Linked Obfuscation Is Bad
- It is extremely easy to undo. Replace all
eval
s with printf '%s\n'
then run the script. The script will print its original source code.
- You have to make sure that there are no variable name collisions between your script and the obfuscation method.
- When writing an obfuscator you have to come up with a method to obfuscate more advanced constructs. For instance a loop spanning multiple lines cannot be split into multiple
eval
s. You have to preprocess. Either replace linebreaks by ;
or use a heredoc <<END
.
An Alternative
Obfuscation can only be an obstacle, but never completely stop someone from understanding or modifying the obfuscated code. I would strongly advise against obfuscation. But if you feel better that way, you could use the following approach.
You can compress your script A and embed the compressed version in another script B. Executing B decompresses and executes A. Security-wise this approach is as bad as your linked obfuscation method. Compression is easy to undo. However there are no drawbacks like name collisions and preprocessing. Furthermore the obfuscated scripts appear to be binary files which may prevent some editors from opening them.
Here is a script to obfuscate bash scripts using gzip compression:
obfuscate.sh:
#! /bin/bash
loader='#! /bin/bash
source <(gzip -c -d <(tail -n+"$((LINENO + 2))" "$BASH_SOURCE"));
status="$?"; return "$status" 2> /dev/null || exit "$status"
'
for original; do
obfuscated="$original-obfuscated.sh"
gzip -c "$original" | cat <(printf %s "$loader") - > "$obfuscated"
chmod u+x "$obfuscated"
done
Usage: ./obfuscate.sh myScript.sh
creates the obfuscated script myScript.sh-obfuscated.sh
in the current directory.
When the target system does not support process substitution <( )
you can use the following alternative version.
#! /bin/bash
loader='#! /bin/bash
tail -n+"$((LINENO + 2))" "$BASH_SOURCE" | gzip -c -d | source /dev/stdin;
status="$?"; return "$status" 2> /dev/null || exit "$status"
'
for original; do
obfuscated="$original-obfuscated.sh"
printf %s "$loader" > "$obfuscated"
gzip -c "$original" >> "$obfuscated"
chmod u+x "$obfuscated"
done
That should work if the target system has bash
>4.0 and /dev/stdin
. If it doesn't meet these requirements replace | source /dev/stdin
by bash -s - "$@"
. The only downside of doing so is that the obfuscated script cannot be sourced (. script.sh
or source script.sh
) anymore.