Threats and Countermeasures Guide for Windows 7 and Server 2008 R2

Finally, Microsoft has released their Threats and Countermeasures guide for Windows 7 and Server 2008 R2. It is a very lengthy document going into gory details on hundreds of security settings, mostly covered by GPOs. It’s a great resource for understanding WHY Microsoft recommends a certain setting, and understanding implications of the lockdown, such as breaking compatibility.

You can download the full guide here.

Windows Recovery Environment VMware Driver Injection

This post will show you how to configure Windows recovery environment VMware drivers. In a previous blog post here I described how to inject VMware pvscsi and VMNET3 mass storage drivers into your Windows Server 2008 or Windows 7 image. However, that did not cover injecting the same drivers into the Windows Recovery Environment, which is a separate WIM within the install.wim, thus requiring extra work.

Here’s how to inject drivers into the winRE.wim file and repackage the install.wim with the updated recovery environment.

1. Follow the first five steps at my blog here to install WAIK, find the right drivers, and create a scratch directory.

2. Mount the install.wim file from your Windows installation DVD:
dism /Mount-Wim /WimFile:D:\install.wim /Index:1 /MountDir:D:\mount

3. Copy the winRE.WIM to a working folder:
copy D:\mount\windows\system32\recovery\winre.wim D:

4. Create another mount directory, D:Mount2, then run this command:
dism /Mount-Wim /WimFile:D:\winre.wim /Index:1 /MountDir:D:\mount2

5. Inject the pvscsi and VMXNET3 drivers:
dism /image:D:\mount2 /Add-Driver /driver:d:\drivers\pvscsi.inf
dism /image:D:\mount2 /Add-Driver /driver:d:\drivers\vmxnet3ndis6.inf

6. Unmount the winRE image:
dism /unmount-wim /mountdir:d:\mount2 /commit

7. Copy the modified winRE.wim file to:

8. Unmount and commit the changes to the install.wim:
dism /unmount-wim /mountdir:d:\mount /commit

At this point you now have a modified install.wim file that you can copy back into your Windows OS ISO. Depending on your install.wim file, you may have multiple operating systems that need to be modified. To do this you would serially mount all OS indexes, inject the new winRE.wim then unmount the image. For a typical Windows Server 2008 R2 DVD, you could have 8 images that need to be modified to cover all of your bases. So this process can be a bit tedious and would lend itself to scripting.

Inject VMware drivers into Windows Install Discs

I like to perform unattended installations of my operating systems, like Windows Server 2008 R2 or Windows 7 using autounattend.xml so that requires that the image have the required drivers to recognize critical devices like mass storage hardware.

One of the performance optimizations that I always include in our Windows VM templates is the VMware paravirtual SCSI driver. This is a high performance mass storage driver that is optimized for virtual environments and gives you the best disk I/O performance. Unfortunately Microsoft does not include it out of the box on any OS install disk.

So you have two options:

1) Extract boot floppies from an ESXi update. I posted a blog on this a while back. Then you need to mount the virtual floppy image during the Windows install process and manually load the driver. This does not work for an unattended installation as Windows doesn’t automatically look for mass storage drivers.

2) Inject the mass storage drivers directly into the boot.wim file, so it is ‘baked in’ and then you can use an automated Windows install process all while using the high performance SCSI driver. I also inject the drivers into the main OS image (install.wim) so they are available to the operating system after installation.

Since option #2 is more automated, that is of course the option that I want to use. It’s a bit of a complicated process, but in the end in makes life easier. This process can work for other drivers as well, if you also want to use the ISO image on a physical server that has a unique mass storage controller, for instance.

Here is the basic process:

1) You will need to download and install the Windows Automated Installation Kit (WAIK). I used the latest version for Windows 7. Best practices is to install it on a x64 computer, so you can manipulate x64 images should you need to do that.

2) Perform a fully default installation of the WAIK. After the installation is complete, launch the Deployment Tools command prompt.

3) Mount the ISO image of your operating system. Navigate to the Sources directory and copy boot.wim to your computer, say on the D: drive.

4) Create a folder on your D: drive called Drivers. VMware provides both 32-bit and 64-bit pvscsi drivers, and you must use the right one depending on what CPU architecture you are injecting the drivers into. The easiest solution is to leverage an existing 32-bit or 64-bit VM running on vSphere and go into the C:\Program Files\VMware\VMware Tools\Drivers\pvscsi and copy the files in there to D:\drivers.

To verify the supported architecture of the drivers, open the pvscsi.inf file and scroll down to the [Manufacturer] section. If you see NTamd64, you have 64-bit drivers. If you see NTx86, you have 32-bit drivers. The 64-bit pvscsi.sys file is also larger than the 32-bit version (40K vs 35K for vSphere 4.1).

Do not inject both drivers into your image; only use the matching driver for the OS you are modifying. Server 2008 R2 is 64-bit only, whereas you have a choice with Windows 7.

5) Create a folder on the D:\ drive called Mount.

6) In the deployment tool command prompt type:

dism /get-wiminfo /wimfile:d:\boot.wim

And look at the index numbers. This is key!  You must select index 2, the Windows setup image. If you inject the drivers into index 1, the Windows setup routine will NOT see them and you will be banging your head against the wall.

Microsoft DISM

7) In the deployment tool command prompt type:

dism /Mount-Wim /WimFile:D:\boot.wim /Index:2 /MountDir:D:\mount

8) You should see an operation successful if the image mounted properly.

9) In the deployment tool command prompt type:

dism /image:D:\mount /Add-Driver /driver:d:\drivers\pvscsi.inf

10) You should see an operation successful if the driver was injected properly.

11) Commit the changes and unmount the image with this command:

dism /unmount-wim /mountdir:d:mount /commit

12) At this point I also inject the same drivers into the sourcesinstall.wim file, so the drivers are present before VMware tools gets installed. You follow the same procedure of mounting the WIM, adding the drivers, and then committing the changes. Most install.wim files have multiple images in them, so execute step #6 to list all of the images in the WIM and select the right one(s) to inject the drivers into.

13) Create a backup of your OS ISO file, and then use your favorite ISO editing tool (such as UltraISO) and replace the boot.wim and install.wim files in the Sources directory.

Now you can use the new ISO image to create a VM which uses the pvscsi controller for the boot drive, and you won’t need to manually mount a virtual floppy drive to use a pvscsi boot disk.

If you also want to inject the VMware vmxnet3 drivers, you can use the same procedures. But where do you find the drivers? On a VM running on vSphere navigate to C:\Program Files\VMware\VMware Tools\Drivers\vmxnet3. Copy all of the driver files to the same driver folder from above, and run step #9 a second time, but specifying the vmxnet3ndis6.inf file. Unlike the pvscsi driver, the VMXNET3 driver supports both 32-bit and 64-bit versions with the same set of files.

I would not recommend including the VMware mouse driver (vmmouse.inf) as it’s an unsigned driver and you will get an “Error 50 The request is not supported” when you try and commit the image changes, unless you use the /forceunsigned switch when adding the driver. VMware tools will of course install the mouse driver, so just leave this driver out.

I also wrote a blog about incorporating these drivers into the Windows Recovery environment. This can be very useful if a server goes belly up and you want to try and repair it. You can check that out here.

SYSPREP resetting your renamed Administrator and Guest accounts?

Lately I’ve been working on our Server 2008 R2 vSphere 4.1 template and ran into an interesting issue. During the template build process we rename the Administrator and Guest accounts, to comply with best practices. However, after vCenter executed the customization specification the accounts got reset back to Administrator and Guest. Well that’s no good since it violates our security policies. I wanted to find an automated solution, and I did.

During the SYSPREP process Windows can call a script called setupcomplete.cmd which is located in %WINDIR%SetupScripts. So I added two lines to my existing script:

wmic useraccount where name=”Administrator” call rename name=”NewAdmin”
wmic useraccount where name=”Guest” call rename name=”NewGuest”

Since this gets called at the very end of the sysprep process, it renames the accounts just before Windows reboots. This should work on Windows 7, and very likely previous generation operating systems.

How strong is your SSL? Sniff and find out!

Today a colleague of mine asked me if I really thought one could tell what cipher strength is used during SSL transactions. I said sure! Piece of cake if you know what to look for. Just like in the movie Matrix, if you stare at the cipher text long enough you visualize the meaning and a little voice in your head tells you “AES-256…..” or “ECDHE….” or “They are out to get you…..”

Well ok not really..but you can easily find out and here’s how. When a client like IE connects to a web server that supports SSL there’s a handshake message called ClientHello. In this message the client bares all and lists all of the cipher suites that it supports. See the example below for an example ClientHello message…and look very carefully.

If you are used to seeing ClientHello messages, two things should appear somewhat odd in the image above. I captured it during an IE8/Windows 7 handshake with an IIS 7.5 web server. First, the client supports TLS 1.2. This is unusual, and takes manual intervention to enable in IE8. Second, the order of the cipher suites is non-standard as well. I didn’t like the default order that Microsoft bakes into Windows so I put the AES-256/SHA-256 cipher suites at the top of the list. Nothing but the best!

Now how about the server end? Astonishingly there’s a server message called ServerHello. Servers are busy beasts, so all it returns is the strongest cipher suite that it has in common with the client. In this case I also enabled TLS 1.2 on the server end, so it picked AES-256 with SHA-256.

From there on out the SSL handshake continues and eventually an encrypted session is built up and all comms go secure. You can apply the same sniffing techniques to deconstructing SQL SSL sessions as well. Network Monitor 3.4 seems better than WireShark at decoding more types of SSL connections, such as those used by SQL.

WMI GPO Filters for Operating System Types

As a standard practice in the environment I support we use WMI filtering on GPOs to ensure a GPO only gets applied to the right operating system type. This can prevent accidents such as applying a client GPO to a server, or a GPO for Server 2003 to a Server 2008 R2 system.

Creating WMI filters can be a pain, so here are the WMI queries that I use which cover a variety of operating systems.

Windows XP
select * from Win32_OperatingSystem WHERE Version LIKE “5.1%”

Windows 7
select * from Win32_OperatingSystem WHERE Version LIKE “6.1%” and ProductType = “1”

Windows Server 2003/R2
select * from Win32_OperatingSystem WHERE Version LIKE “5.2%”

Windows Server 2008
select * from Win32_OperatingSystem WHERE Version LIKE “6.0%” AND ( ProductType = “2” or ProductType = “3” )

Windows Server 2008 R2
select * from Win32_OperatingSystem WHERE Version LIKE “6.1%” AND ( ProductType = “2” or ProductType = “3” )

If you are wondering what the product types are, they are defined by Microsoft and distinguish between a client OS (1), domain controller (2) or member server (3). So you could easily create a filter to only apply to Windows Server 2008 R2 domain controllers, if you wished. Alternatively for 2008/R2 you could use AND ProductType “1” if you want something a bit shorter that covers both server product types.

To use these queries, open the GPMC. Expand down until you find the WMI Filters node. Right click on it and select New WMI Filter. Click Add, then paste the query of your choice into the query box. Give the filter a name, then you can apply it to any GPO in your forest.

WMI queries need not be limited to just querying operating system type. You could for instance apply a GPO only to systems with 8GB of RAM, a certain graphics card, hard drive size, or thousands of other parameters. A nice free tool I found for exploring WMI is WMI Explorer. It also lets you run queries, so you can validate that your query is working properly.

RMS Automatic Template Downloading on Windows 7

Recently the project I’m supporting is looking at RMS to provide information rights management (IRM) on some documents. Windows RMS provides two means to let users protect content. First, there is the ad hoc method that lets a user specify what protections they want to put on their content, and what users/groups it applies to. Second, an RMS administrator can configure standard templates (i.e. “Company Confidential”) which all users in the enterprise can use. In most organizations both content protection methods have their place.

However, I’m disappointed in how Microsoft implemented these templates. You’d think the RMS client would dynamically query the RMS server for available templates when you want to protect content and present them to the user for selection. However, it’s much more brain dead and less dynamic. In Windows XP and Vista RTM, the administrator had to ‘manually’ copy the XML templates to a special directory on each and very computer for every user. Most used a GPO or logon script. Still a kludge if you ask me.

Starting with Vista SP1 and later, including Windows 7, Microsoft included a scheduled task called “AD RMS Rights Policy Template Management” which discovers the RMS servers in the environment and downloads the templates for each user. It’s triggered to run every day at 3AM or at user logon time.

However, the default configuration of this task is brain dead. Under HKCUSoftwareMicrosoftMSDRMTemplateManagement there’s a key called “lastUpdatedTime” which gets populated each time the scheduled task runs. There’s also another key called “UpdateFrequency” which is set to 30. What does the 30 mean? It will only download templates once every 30 days. Even if you manually run the task it won’t touch the RMS servers. The minimum you can set the frequency to is once a day (1). You can, however, delete the “lastupdatedtime” key and it will check the RMS server and re-populate the key.

Also another very important point is to add the RMS FQDN to each user’s Local Intranet security zone in IE. If you don’t do this then the task won’t authenticate to the RMS IIS server and you will get a Last Run Result of (0x8004CF43).

If the task worked the scheduled task probably has a Last Run Result of (0x4CF04). To confirm the templates actually downloaded, go to your profile directory and under C:Users%username%AppDataLocalMicrosoftDRMTemplates you should see one XML document for each template defined in the RMS console. If not, make sure you have invoked a document protection attempt in office so that it discovers your RMS server.

Another annoyance with RMS is that Office isn’t smart enough to look in this templates folder by default. NO! Let’s make it harder on our admins to get all of this working. Under:


you need to create a REG_EXPAND_SZ value with a name of AdminTemplatePath with a value of:


Why Microsoft needs to make this so difficult is beyond me. Personally I think the embedded RMS client should make a dynamic web services call to the RMS server when a user wants to protect content, get the latest templates, and cache them locally. Office needs to look at the default template location too. Also remember the scheduled task is NOT enabled by default. So if your organization is going to use RMS, you need to configure a GPO or script to enable the task on all Vista SP1 and later clients. If you are going to use Remote Desktop Services (RDS) or XenApp, enable the scheduled task on your servers.

PowerShell command to change Windows Cipher Suite Order

While journying down the whole cipher suite road this weekend, I put together a little one liner that reconfigures the cipher suite order that Windows will try and use. As I mentioned in a previous blog, you can configure this via GPO. But, maybe you want to build in the configuration to a golden image. You probably have other PowerShell scripts to configure your golden image, so you can throw this command in to tweak the cipher suite order.

The command only works on Windows Server 2008 R2 and Windows 7. If you use Vista or Server 2008, look at your existing registry key for the list of cipher suites then modify the script. Many of the new cipher suites are not availabile on 2008/Vista.

After you cut and paste the script to your computer remove all line breaks and spaces in the cipher suite string. This is important, as we are at the 1024 character limit of a PowerShell string.


Easily configure your Windows Cipher Suites!

After many hours of digging around the Windows registry and experimenting with various keys to enable TLS 1.2 on Windows Server 2008 R2 and Windows 7 (see my blog post here), I found this free tool that gives you one click access to configuring your Windows Cipher Suites. The Harden SSL/TLS tool is in beta, but worked great for me.

The tool lets you enable/disable protocols, hashes, key exchanges, and prioritize the cipher suites. One click exporting to registry files, and PCI DSS compliance. The author also has a few other tools and whitepaper as well.

The SSL hardening tool seems to make system changes in real time. My suggestion is to use a VM, take a snapshot, run the tool, export the registry settings, and then look at the registry file. Compare the registry file to the clean snapshot then decide what registry changes you want to push to production servers.

The tool is still in beta, and I had it lock up on me a few times. So using it to see what registry key changes you need to make manually is a pretty safe bet. Don’t run it on production systems!

I also found a web site that would let you query SSL enabled site, score them on security, and show the cipher suites they support. Great for checking out your bank or other secure sites you need to trust. My bank scored an 81, which was pretty good. Check out Qualsy SSL Labs.

Enable TLS 1.2 Ciphers in IIS 7.5, Server 2008 R2, Windows 7

Some industries, like Government, require the use of certain cryptography algorithms. One of the great features of Windows Server 2008 R2 and Windows 7 is the support for TLS 1.2 ciphers. TLS 1.2 ciphers support AES-256 encryption with SHA-256 hashes. Unfortunately, Microsoft did not enable these protocols out of the box. I wanted IIS 7.5 to negotiate TLS 1.2 connections with my Windows 7 clients. After some registry hacking I was successful, as shown by a Wireshark trace.

I created a simple PowerShell script that enables TLS 1.2 for both client and server communications. It also disables SSL 2.0 server responses, in case you need to be PCI compliant. The lines are pretty long, so pay attention to the wrapping. After you run the PS script (with elevated rights) you must reboot the client and server.

Please note that all values must be DWORD. This is very important, as any other value type will NOT work and you may be pulling your hair out wondering why it’s not working.

# Enables TLS 1.2 on Windows Server 2008 R2 and Windows 7

# These keys do not exist so they need to be created prior to setting values.
md "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2"
md "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server"
md "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client"

# Enable TLS 1.2 for client and server SCHANNEL communications
new-itemproperty -path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server" -name "Enabled" -value 1 -PropertyType "DWord"
new-itemproperty -path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server" -name "DisabledByDefault" -value 0 -PropertyType "DWord"
new-itemproperty -path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client" -name "Enabled" -value 1 -PropertyType "DWord"
new-itemproperty -path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client" -name "DisabledByDefault" -value 0 -PropertyType "DWord"

# Disable SSL 2.0 (PCI Compliance)
md "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Server"
new-itemproperty -path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Server" -name Enabled -value 0 -PropertyType "DWord"

After you run the PowerShell script, you should see DWORD entries like those shown below. Also, go into the Advanced properties of IE and check the box next to TLS 1.2.

If you start a WireShark capture on a TLS session you will know it’s v1.2 by two easy methods. First, the Protocol column will show TLSV1.2. Secondly, if you open the ServerHello packet you should see burried in the packet:

Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA256 (0x003d)

You can also configure the advanced settings in IE8 on Windows 7 or Server 2008 R2 to only use TLS 1.2 by de-selecting all other SSL/TLS options. If your browser can connect with just TLS 1.2 selected, then you are golden. But for 100% verification, use a packet sniffer.

Another tweak you can do to your system is change the order of the cipher suites that Windows negotiates. This is possible in Windows Vista and higher. I changed the order such that TLS_RSA_WITH_AES_256_CBC_SHA256 is at the top of the list. Next to elliptical curve ciphers, this is the strongest that Windows offers.

To change the cipher suite order, open the GPMC on a Server 2008 or higher DC and navigate to: Computer\ Configuration\Policies\Administrative Templates\Network\SSL Configuration Settings. Enable the policy, then copy the cipher suites to Notepad and change the order as you wish. I just flipped the first two entries. So my first two entries look like:


I haven’t done extensive testing to know what types of compatibility problems enabling TLS 1.2 may create. So as always, test, test, test! I confirmed with WireShark that the Windows RMS client in Windows 7 will use TLS v1.2 to contact the root Windows Server 2008 R2 RMS server.

During my research I stumbled upon a cool Microsoft web site that lets you test various cipher suites with your browser. If you click on the cipher suites on the server authentication line you can see what your browser will support.

Lastly, Microsoft has a good reference of which cipher suites are associated with which protocols.