Isn’t It Ironic?

When it comes to security, don't forget to encode your beloved scripts.

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.

Featured