Isn’t It Ironic?
When it comes to security, don't forget to encode your beloved scripts.
- By Chris Brooke
- March 01, 2003
Probably the most misunderstood word in the English language is “irony.”
What many people call irony would be better called “coincidence” or “happenstance.”
The
American
Heritage Dictionary defines irony as, “Incongruity between what
might be expected and what actually occurs.” Something I find ironic is
this: As administrators, we go to a great deal of trouble to secure our
networks, store our script source code in folders secured by NTFS file
permissions, regularly change passwords and follow other rigorous security
precautions. However, on those occasions when we have to deploy a script
to a user’s machine, many of us send plain old clear text scripts. Ironic,
isn’t it?
Oh, sure, we know about the Windows Script Encoder. We’ve even used it
on occasion with our old WSH 1.0 scripts. It encodes the contents of the
script and changes the file extension from VBS to VBE (for VBScript) and
from JS to JSE (for JScript). “But, Chris,” you say, “we’ve been working
almost exclusively with .WSF scripts for quite some time. What about them?”
Indeed, that question was posed by Chris Lawrence, who sent an e-mail
in response to my February column asking if it was possible to encode
the contents of .WSF scripts. The answer is yes.
Why Encode?
One of the great advantages of using compiled languages like Visual
Basic is that the resultant executable is stored as a binary file. This
makes it quite difficult for an unauthorized person to make changes to
(or even view) your code. While the script encoder doesn’t offer the level
of protection afforded by a compiler, it’ll make your scripts difficult—but
not impossible—to read. Moreover, if someone makes a change to the encoded
file, the script is rendered useless. This provides peace of mind that
if someone does “goober with it,” at least they won’t be able to do any
real damage.
How Encode?
The encoding process is quite simple. Really. First, you have to
prepare your scripts for encoding. This is the easiest part. Simply put
this comment line in your actual script code (the part between <script>
and </script>):
' **Start Encode**
Everything between this line and the ending </script> tag will
be encoded.
The next step is to download the Windows Script Encoder from the MSDN
site at: http://msdn.microsoft.com/scripting/vbscript/download/x86/sce10en.exe.
This installs a command-line utility named screnc.exe. From a command
prompt, simply type:
C:\>screnc /e sct TestEncode.wsf eTestEncode.wsf
specifying the name of the source file and the name of the destination
file. The encoder will take care of the rest. The following listing…
<package>
<comment>
This script is encoded
</comment>
<job>
<script language="VBScript">
'Everything below the next line will be encoded
'**Start Encode**
WScript.Echo "Encoding is cool!!"
</script>
</job>
</package>
...looks like this after being encoded:
<package>
<comment>
This script is encoded
</comment>
<job>
<script language="VBScript.Encode">
'Everything below the next line will be encoded
'**Start Encode**#@~^KQAAAA==@#@&j1D
bwYc214W,J3x1W[roPbdP1WW^ZZJ@#@&PQsAAA==^#~@</script>
</job>
</package>
Not ironically, this encoded script runs perfectly, producing the same
output as the source script (just as we’d expect).
What Encode?
The first change you’ll notice (aside from the “gibberish” following
the **Start Encode** line) is that the <script> tag now has the
language listed as “VBScript.Encode.” This tells the parser that it has
to decode the following script in order to run it. It also helps remind
you that the script was encoded (just in case you start to panic, thinking
your most important script file’s been corrupted).
You may also have noticed that I used a flag when invoking the script
encoder (“/e sct”). This tells the script encoder that I’m encoding a
scriptlet file. The .WSF file extension isn’t recognized by the encoder
as a valid extension. Ironic? Possibly. But since the script encoder is
designed to encode many types of files—from ASP pages and HTML documents
to standard VBS and JS files—and because it’s free, I don’t fault it for
making me specify that I’m encoding a “scriptlet.”
You’ll also notice that I named the encoded file “eTestEncode.wsf.” The
script encoder does have a flag that allows you to encode and replace
the original file, but you should always keep your original scripts intact.
Remember: You can’t edit the encoded script. For simplicity, I like to
keep the same script name but preface it with a lowercase “e.” This tells
me that this file is a completed, debugged and encoded script—ready to
be deployed to a user’s machine.
Finally, only the code following the '**Start Encode** line is encoded.
It’s a good idea to insert a comment above this line that tells anyone
looking at the script that it has been encoded and any changes will “break”
the script.
Y_Enc_d?
Scripting technology continues to improve. Tools like WMI and ADSI allow
you to manage many administrative tasks remotely. Unfortunately, there
are times when running a script locally on the user’s machine can’t be
avoided. When this happens, consider encoding your scripts prior to deploying
them.
As I mentioned above, the script encoder is not a strong encryption tool.
The encoding performed on the script is primarily designed to keep the
casual observer from looking at your code. The real strength of the script
encoder is code integrity. You can be assured that when you deploy an
encoded script to the client machine, it will do exactly what you programmed—or
nothing at all.
Homework
Your homework for this month is to write a script that encodes a specified
script or scripts. I’m going to make it even more difficult by stipulating
that you can’t shell out to the command line and use screnc.exe to do
this. I will, however, give you a hint: the FileSystemObject. Because
you’ll be expecting me to have the answer next month, I’ll try not to
be ironic.