January 30, 2007

Windows Scripting for Security

Windows scripting is a very powerful security (and administration) tool. It strikes me, however, that not many system administrators or security experts realize its potential.

This article tries to illustrate that potential with a sample script I wrote to obtain the list of wireless card drivers installed and their versions, from a local or remote Windows system. The script can be found here. (Note: The script has been renamed to .txt to make it harder to execute it inadvertedly. You'll have to rename it back to .vbs to run it).

In the Unix world it is just common standard knowledge that if you are going to perform a task more than once or twice you may want to write a simple script (e.g. a bash or perl script) to do it for you. This way you will be able to repeat the task effortlessly as many times as it is necessary, in as many systems as needed, and at any time it is required (just schedule the script to run with cron).

In Windows environments, by contrast, I find most people normally use GUI tools, only some people use their command-line equivalents from time to time, and almost no one will even consider the possibility of writing a script to perform a particular task if there is no tool available to do it. They will rather say "it can't be done".

In the old days it was true that we only had .BAT files for scripting and very few managament tools had a command line version so trying to solve a problem by writing a script was probably not the way to go. Today, however, we have Windows Script Host (WSH) included in all modern versions of Windows. WSH provides an interface to almost every object in the system and exposes it to several scripting languages like Visual Basic Script (included in Windows), perl and others. With WSH, scripts can interact very easily with entities as complex as the registry, or Active Directory, or the file system and perform very advanced tasks.

I'll give you an example. You may have heard of the vulnerabilities that were discovered on many wireless card drivers a few months ago. Most vendors, if not all, issued patches for their drivers. Now, let's say you read on a web page the versions of the vulnerable drivers. How can you know which version you have installed on your system(s)?

One way would be going to control panel > system > hardware > device manager > select wireless card > right click > properties > driver > details; then take note of the version number and repeat for each wireless card on the system. However, there are two problems with this approach: one, not all wireless cards configured in the system are shown in Device Manager by default (only those currently connected); and two, it doesn't scale. Or would you repeat this process on 100 systems? And what if those systems were remote?

A different approach would be writing a script to check this information for you. Actually, it was pretty easy to write such script: all the required information (number and type of wireless cards installed on the system, their drivers and their drivers' versions) is in the registry and the registry can be accessed from visual basic scripts through WMI (Windows Management Instrumentation) with a simple call to GetObject().

I will not go into the details of the source code of the script because it would make this post too long and I'm not sure it would be interesting for everyone. Instead, I'll show you an example of usage:

C:\tmp>cscript /nologo WMIGetWirelessDriversVersion.vbs localhost

I use cscript.exe because the default WSH executable to kick in, if I didn't explicity specify cscript.exe, would be wscript.exe, which would show the text messages in popup windows instead of a in a text console, which would be annoying (you can try, though, there is no
harm).

The output should look similar to this:

================
Found wireless card at:
HKLM\SYSTEM\CurrentControlSet\Control\Network\{4D36E972-E325-11CE-BFC1-08002BE10318}\{7C1F7564-C990-420E-A4D6-F54092764DF9}\Connection

Name: Wireless Connection 1

Found corresponding driver data at:
HKLM\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002bE10318}\0011

NetCfgInstanceId: {7C1F7564-C990-420E-A4D6-F54092764DF9}
DriverDesc: Intel(R) PRO/Wireless 2200BG Network Connection
DriverVersion: 9.0.3.9
Service: w29n51
ImagePath: system32\DRIVERS\w29n51.sys
================

Instead of localhost you can specify the name or IP address of a remote system. The only requisites are that your current user must have administrative access to the target system and that RPC communication must be allowed between the systems.

Now suppose you manage a Windows OU (organizational unit), domain or a whole forest and you want all systems under your control checked. Could you schedule it to run automatically and collect the results, all from a central location? Oh, yes! That's what Active Directory, Group Policy and network shares are for (among other things), but that's another story.

David.

<plug>
I will be teaching "SEC505: Securing Windows" at SANS Prague 2007 (Feb. 12-17). If you want to discover how a Windows network can be made really really secure (for those of you chuckling... Yes, it can!) come and join me there!
</plug>

PS: Thanks to Joshua Wright, for an interesting challenge, an to Jason Fossen, for sharing his knowledge (he is the author of "SEC505: Securing Windows") and his scripts.

PS: The code in the script is not optimized in any way and it does not do proper error checking. Please don't flame me for that. Instead, feel free to improve it and send me a copy back ;-).

<stats>
The smiley (image) at the end of this sentence has been included to track statistics about this Blog/post. Believe us, it is not a WMF exploit! (Counter29012007)
</stats>

Labels: ,

0 Comments:

Post a Comment

<< Home