Thursday, December 13, 2007

Security Through Obfuscation

Hey there,

Today, we'll look at having some fun with your code :)

Every once and a while, although you don't want your code not to work, if you need to keep folks from messing around with it, a little confusion can keep most other "helpful" co-workers from messing with that script you finally got to work ;)

This is a simple method to keep your code safe (or ensure that it won't be tampered with twice) while not being offensive to your employer. Compiling your tcl script into bytecode would be unconscionable, since it makes it impossible for your employer to ever fix your work if you leave the company (I'm assuming standard intellectual property rights apply and we're dealing with a script that was created as part of your job requirements or a specific work-for-hire).

Step 1 - Dereference like crazy. If you need to run a series of commands, run them in a subshell or remotely. This will increase the number of backslashes at varying depths of your code and can be really hard to get working in the first place.

Step 2 - Compact your script into a single line. Most people already know this, but for anyone who doesn't; formatting is something scripters and coders do so that the code is easy to read and interpret (There are exceptions, like Pascal, that use indentation as condition indicators, etc, but it's generally not the norm in shell scripting).

Step 3 - Put everything back the way it was if you ever do move on to greener pastures. Even though you may hate your job at the time, the ill-will you'll leave behind by screwing those who remain to do your job for you is hard to shake. I, personally, don't know about that first-hand. At least in regards to this sort of thing ;)

Consider this simple script (which, admittedly, doesn't make any sense to run locally - just for example):

#!/bin/ksh
pid=$$
cat $hostfile|while read name emptyvariable
do
if [ $name == "#" ]
then
:
else
print "$name... "
if [ `uname -r` == "5.8" ]
then
output=`echo "howareyou"|/bin/sed 's/are/do/'`
print "OUTPUT $output";
fi
fi
done


Apply Step 1 - Run the main command loop in a remote shell, so you have to do a lot of dereferencing (looking uglier):

#!/bin/ksh
pid=$$
cat $hostfile|while read name emptyvariable
do
if [ $name == "#" ]
then
:
else
print "$name... "
/usr/local/bin/ssh -n $name "if [ \`uname -r\` == \"5.8\" ];then output=\`echo \"howareyou\"|/bin/sed's/are/do/'\`;print \"OUTPUT \$output\";fi"
fi
done


Finally, Apply Step 2 - Make the entire script one line long (And pray you never have to troubleshoot it ;)

#!/bin/ksh
pid=$$;cat $hostfile|while read name emptyvariable;do if [ $name == "#" ];then :;else print "$name... ";/usr/local/bin/ssh -n $name "if [ \`uname -r\` == \"5.8\" ];then output=\`echo \"howareyou\"|/bin/sed's/are/do/'\`;print \"OUTPUT \$output\";fi";fi;done


Now go and do this to a 500 line script. If anything, you'll learn a lot about why it's nice to format :)

Cheers,

, Mike