Block VML Zero-Day Vuln on a domain

By now hopefully you have heard about the latest Internet Explorer Zero-Day attack. This one is allegedly being exploited in the wild making it important to protect against it. As an indication of how urgent this is Microsoft, traditionally loath to block functionality in a work-around, even posted details on how to disable VML in their security advisory. Of course, using cacls to block the attack on a few thousand systems could get cumbersome. Microsoft is planning a fix in the October time-frame apparently, earlier if the rate of attacks picks up.

If you have a Windows Domain you can use Group Policy to block this attack much more easily than having to touch every system manually. With the help of my good friend Alun Jones I was able to produce two security templates that disable and enable, respectively, the dll that renders VML. Here is the one that disables it:

[Unicode]
Unicode=yes
[Version]
signature="$CHICAGO$"
Revision=1
[File Security]
"%ProgramFiles%\Common Files\Microsoft Shared\VGX\vgx.dll",0,"D:AR(D;OICI;CCSWWPLORC;;;WD)"

And here is the template that re-enables it by removing the ACL on vgx.dll:

[Unicode]
Unicode=yes
[Version]
signature="$CHICAGO$"
Revision=1
[File Security]
1="c:\program files\common files\microsoft shared\vgx\vgx.dll", 0, "D:AI"

Save each of these templates to inf files called, respectively, DisableVML.inf and EnableVML.inf. Alternatively, just use the ones in the zip file attached to this post. Save the files in somewhere so you can access them from the system you use to edit your Group Policy objects (GPO). Then create new GPOs to disable and enable VML. You are going to need two different GPOs, one to apply the settings and another to remove them again. Obviously you will want only one active at a time. To create the GPO, take the following steps.

  1. Open the GPMC (if you do not have the Group Policy Management Console, you need to get it. Strictly speaking you can manage GPOs without it, but you really don't want to)
  2. Right-click the domain or OU where you want to link the GPO - you may as well do it at the domain level - and select "Create and Link a GPO Here..." Name your new GPO "DisableVML"
  3. Right-click the GPO DisableVML and select "Edit..."
  4. Expand "Computer Configuration:Windows Settings" and right-click on Security Settings. Select "Import Policy".
  5. Find and select the "DisableVML.inf" file. If you used an existing GPO instead of creating a new one, also check the "Clear this database before importing" checkbox.
  6. Close the GPO editor and go back to the GPMC
  7. In the "Security Filtering" pane remove "Authenticated Users" and click Add...
  8. Select the group "Domain Computers" or some other group that represents the computers to which you want to apply the policy. If you are not using the GPMC you also need to check the "Allow" box under "Apply Group Policy"

That's all there really is to it. When the systems refresh their group policy next time they will automatically apply this GPO and block the attack. By default this happens each time they reboot or every 90 minutes, whichever comes first. You can also force this refresh using "gpupdate /target:computer /force" if you have a way to do that.

If you create both of the GPOs now you save yourself a little bit of work later. You can create one to disable VML and one to enable it, and then disable the link for the one you do not want by right-clicking it in GPMC and selecting "Link enabled" as appropriate.

 Good luck!

 Update Sept. 20, 2006

  • Uploaded a new archive that uses an environment variable in both templates to specify the file location.
  • Fixed the refresh interval
  • Clarified one of the steps

Update Sept. 21, 2006

  • Uploaded a new version of the archive that uses %CommonProgramFiles% instead of %ProgramFiles%\Common Files to specify the file location. This helps make it work on non-English systems that have translated the name of the Common Files directory.
  • Put a version number on the archive to make it easier to track which one you have.

Update Sept. 22, 2006

Published Tue, Sep 19 2006 12:27 PM by jesper
Filed under:

Comments

# Susan said on 19 September, 2006 06:45 PM
IMHO the area that admins of all shapes and sizes still need 'edukatin' on is Group policy. So many folks do not utilize the power of this (myself included)
# Nathan said on 20 September, 2006 08:28 AM
Is there a reason why your script to disable the vgx uses the variable %ProgramFiles%, but the script to enable uses hard coded "C:\program files"?
# jesper said on 20 September, 2006 09:14 AM

Nathan, good catch. No, there is no reason. Both were written using the Security Configuration Editor. I don't know why one uses the environment variable and the other does not. I'd recommend using the environment variable though. It works on more systems, specifically, non-English Systems. I'll see if i can fix it today and post a new zip file.

Sorry about that confusion. I was focusing on getting the ACL right and did not look at how it specified the file name.

# Steve said on 20 September, 2006 10:49 AM
In researching this vulnerability , most people claim that it is an issue for IE6. Has anyone tested this vulnerability again IE7RC1?
# jesper said on 20 September, 2006 11:31 AM

Steve, first off, I am not sure whether IE7 is even vulnerable to the exploit. IE7 does ship with VML support but that does not necessarily mean it is vulnerable. The code may very well have changed to stop the problem.

That said, I tested a non-malicious page that shows VML on IE7 RC1 (running on Windows Vista RC1). When you open the page IE will not render it without an ActiveX warning dialog. It is not much as protection goes, but it is something; if IE7 were vulnerable.

The workaround works on Vista as well. However, on Vista the owner of that file is the Trusted Installer. GP should still be able to make the ACL change to it, but to make it manually you have to first take ownership of the file.

# Andrew from Vancouver said on 20 September, 2006 01:40 PM
... and in Step 8, after adding the Security group that contains the computers to which you want to apply this, you then highlight it and check the Allow checkbox for "Apply Group Policy".
# K said on 20 September, 2006 03:41 PM
Group Policy runs every 90mins + randomized 30 min offset. Interesting approach.
# Mike said on 20 September, 2006 04:05 PM
How can this be tested? I'm getting 1202 errors and would like to make sure the policy is working properly.
# jesper said on 20 September, 2006 04:32 PM

K, yes you are right. My bad. The refresh is 90 minutes if things have been changed. If not, then it takes 16 hours if memory serves me right to enforce the policies. I don't know where I got 8 hours from. I'll fix that.

# jesper said on 20 September, 2006 04:35 PM

Mike, I presume your error is a 1202 from SceCli? There are some troubleshooting steps in KB 324383: http://support.microsoft.com/?id=324383. See if one of those gets you going.

You can also test it by checking the ACL on %ProgramFiles%\Common Files\Microsoft Shared\VGX\vgx.dll. If it has the Everyone Deny:Read and Execute bits then you are fine.

# CypherBit said on 21 September, 2006 03:29 AM
Jesper, I'd really apprecite it if you could clarify something for me. In steps 7, 8 you write: "In the "Security Filtering" pane remove "Authenticated Users" and click Add... and "" Select the group "Domain Computers" or some other group that represents the computers to which you want to apply the policy and check the "Allow" box under "Apply Group Policy" " I've already pointed it at the computers I want it targeted at in the Location (it's pointed for all the computers at our site). May I leave the Authenticated Users in the Security Filtering as it is. Why should they be removed if it's already pointed (in the Location) to all the computers I want it. In Security Filtering I don't have a group (can't create groups, corporate does that and it would take a while) that contains all the computers for my site, adding them on by one would really take a long time. Or is there an easier way, am I missing something? I did some testing and leaving the settings as I have them now has changed the ACL on %ProgramFiles%\Common Files\Microsoft Shared\VGX\vgx.dll. If it has the Everyone Deny:Read and Execute. Please advise.
# Romeo said on 21 September, 2006 04:38 AM
replacing %ProgramFiles%\Common Files with %CommonProgramFiles% would make it more generic and therefor also work on non-english systems
# Jochen said on 21 September, 2006 05:34 AM
I think there is still an error when it comes to internatonal versions of Windows. For example for german language Microft decided to place the files here: CommonProgramFiles=C:\Programme\Gemeinsame Dateien
# CypherBit said on 21 September, 2006 06:56 AM
Jesper, I'd really apprecite it if you could clarify something for me. In steps 7, 8 you write: "In the "Security Filtering" pane remove "Authenticated Users" and click Add... and "" Select the group "Domain Computers" or some other group that represents the computers to which you want to apply the policy and check the "Allow" box under "Apply Group Policy" " I've already pointed it at the computers I want it targeted at in the Location (it's pointed for all the computers at our site). May I leave the Authenticated Users in the Security Filtering as it is. Why should they be removed if it's already pointed (in the Location) to all the computers I want it. In Security Filtering I don't have a group (can't create groups, corporate does that and it would take a while) that contains all the computers for my site, adding them on by one would really take a long time. Or is there an easier way, am I missing something? I did some testing and leaving the settings as I have them now has changed the ACL on %ProgramFiles%\Common Files\Microsoft Shared\VGX\vgx.dll. If it has the Everyone Deny:Read and Execute. Please advise.
# David said on 21 September, 2006 07:12 AM
Hey Jesper, thanks for this. I too am an avid scuba diver and fisherman. I live near Lake Champlain in upstate NY (Plattsburgh). Lots of great wreck dives in the lake and great fishing too.
# jesper said on 21 September, 2006 09:12 AM

Let me try to answer all the comments that came in while I was asleep:

Kimmo:

I have no idea what you are saying, but I hope it is good. Terve! :-)

Cypherbit:

The reason I remove Authenticated Users is mostly cosmetic. By default the GPMC will apply all policies to Authenticated Users. However, this policy applies to the system, not to the users. You do not need it applying every time someone logs on, only when the system boots. That is really all. There are no ill effects from leaving it there.

Jochen: Romeo answered your question just above. Sorry, I should have thought of that. Goes to show there are always ways to improve; and also that the Security Configuration Editor was not designed considering non-English systems. I wish I had some to test on, but I do not. The directory name "Microsoft Shared" is not localized is it?

I have uploaded a new archive that uses %CommonProgramFiles% instead of %ProgramFiles%

# Jochen said on 21 September, 2006 10:28 AM
I'm not sute about other languagesd but: cd %commonprogramfiles% C:\Programme\Gemeinsame Dateien>dir mi* Datenträger in Laufwerk C: hat keine Bezeichnung. Datenträgernummer: 4C90-1F02 Verzeichnis von C:\Programme\Gemeinsame Dateien 15.05.2006 14:03 Microsoft Shared it lokks like the translation ended somewhere ... at least on Widnows Server 2000.
# Andy said on 21 September, 2006 01:42 PM
The DisableVML security template has a side-effect on W2K systems (server and workstation). After applying the change, the automatic updates client (WSUS) can't read vgx.dll and so insists on installing the old JPEG/GDI+ patch from MS04-028. But then it still can't read the file the next time, so the cycle repeats. I had to exempt my W2K systems from the GPO. But at least your tip keeps my 2K3 and XP systems safer, thanks.
# CypherBit said on 21 September, 2006 01:50 PM
jesper: thank you for the explanation. I'll link it ASAP now. And my appologies for the double post.
# jesper said on 21 September, 2006 02:35 PM

Catching up again :-)

Jochen: thanks a lot. That confirms that at least on German versions it will work as is now.

Andy: That's great to know. That means that Microsoft must also not have tested their work-around on W2K. I bet you can use the unregistration work-around on W2K though. If I get a chance tonight I'll figure out how to add that to the GPO so you can use GP to unregister the DLL. You cannot do that by running the command, but there may be a way to make the appropriate registry changes using GP.

# Joe said on 22 September, 2006 10:08 AM
Thanks for this. I use Special Operations Software's free utility to force GP updates on my domain. http://www.specopssoft.com/products/specopsgpupdate/default.asp
# Doc said on 22 September, 2006 10:48 AM
Does not seem to work with Latest .net framework 2.0 -
# Andy said on 22 September, 2006 11:22 AM
I've confirmed that unregistering vgx.dll on W2K systems avoids the WSUS perpetual patch loop. I'm adding the relevant command to my domain user logon script -- inelegant but effective.
# jesper said on 22 September, 2006 11:23 AM

Doc, what is it that is not working? What steps did you take? I have the .net Framework on all my systems and the workaround was fine there.

# Doc said on 22 September, 2006 11:35 AM
I 'had' intended on using the management console on XP SP2 - had not .Net - downloaded and installed the .net from 4/2006 - .net 2.0, and afterwards tried to install the console. Insisted I did not have .NET installed. Weird. I just installed it on our 2003's and the console is very nice to work with. I will install the 'older' .Net 1.0 on my XP workstation and see if the GPMC properly recognizes that - which was what I meant by saying the 'latest' .NET doesn't see to be recognized (but perhaps I did something wrong, as I often do). Thanks.
# jesper said on 22 September, 2006 12:10 PM

Doc, I get it. .net 2.0 is relatively new and the GPMC probably just needs the 1.x version. .net 2.0 is not completely compatible with .net 1.x. I am not an expert on what the differences are, but I'm glad you got your problem resolved.

# Matt said on 22 September, 2006 12:53 PM
Works like a charm. Thank you. And good post on the GPUpdate tool, very handy! http://www.specopssoft.com/products/specopsgpupdate/default.asp
# Doc said on 22 September, 2006 01:10 PM
Interesting Conundrum - .Net 2.0 'seems' to not work with the GPMC - okay, use .Net 1.0 - but this program, mentioned by Joe above is pretty cool :http://www.specopssoft.com/products/specopsgpupdate/default.asp ... AND it requires .NET 2.0 - ain't life grand. I'm working on it. Thanks. Stay safe diving, great sport! PADI from years ago.
# John A. Rolstead said on 22 September, 2006 03:09 PM
You can also disable User side of the policy since it does not apply to users, this avoids the Authenticated Users vs. Domain Computers group issue mentioned earlier. On the Details Tab when viewing the policy in GPMC, GPO Status: User configuration settings disabled The Win2K issue: You can't use a WMI filter, since Win2K ignores the filter. Question: is there a way to apply the inf using secedit? Deliver the inf file using SMS?
# Richard S said on 22 September, 2006 03:40 PM
This is great thanks... I would add one step where you disable processing of the user settings in both GPOs. Since they are not needed they just slow down processing.
# jesper said on 22 September, 2006 04:42 PM

John, good suggestion to disable user processing. I did not think about that.

Yes, you can apply the template using secedit. That is actually how I developed it. To do that on the command line use the secedit /configure command. You can call that command from SMS too, but if you have SMS, I would suggest using the work-arounds I posted in the new post that just went up. You can actually just call that script in SMS or another EMS if you have one.

# Royce said on 23 September, 2006 11:38 PM
Jesper, thanks for another security lifesaver. You mentioned to Andy that you might find a way to script the unregistration. Here is one way that I have tested and confirmed works. You could probably do the same with a batch file, but this was more fun. Copy this to notepad and save the file named vgxunreg.vbs and save it to the netlogon share. You can then use a GPO to push the vb script. Remove the -s if you want to see the message box successful confirmation. '======================================== Set objShell = CreateObject("WScript.Shell") Set objFSO = CreateObject("Scripting.FileSystemObject") strUnregCommand = "regsvr32 -u -s C:\progra~1\common~1\micros~1\vgx\vgx.dll" Set objExec = objShell.Exec(strUnregCommand) '========================================= To re-register vgx.dll, do the same procedure with the script below, but name this one vgxreg.vbs '========================================= Set objShell = CreateObject("WScript.Shell") Set objFSO = CreateObject("Scripting.FileSystemObject") strRegCommand = "regsvr32 -s C:\progra~1\common~1\micros~1\vgx\vgx.dll" Set objExec = objShell.Exec(strRegCommand) '========================================= ZERT offers a 3rd party temporary patch here: http://isotf.org/zert/download.htm On this same page about halfway down they offer a non-malicious test page. Thanks again!
# Sam said on 27 September, 2006 11:31 AM
I used the security template you prodvided to disable vgx.dll in our domain last week. I had to use EnableVML.inf to reverse that change before the patch would correctly install on some XP Pro machines. Some of our users got the DisableVML group policy and are now offsite. What command can I give them to roll that back so they can install the patch (and display SharePoint sites correctly again)? I tried regsvr32 "%ProgramFiles%\Common Files\Microsoft Shared\VGX\vgx.dll" with no luck. Thanks for your help!
# Jonathon said on 02 October, 2006 11:15 AM
As well, I just realized in the EnableVML.inf script, when you view it GPMC, the disable one shows Deny All on the dll, the Enable one doesn't show any permission change, so I'm wondering if the Enable one has a bug?
# jesper said on 02 October, 2006 11:27 AM

Jonathon, that's not a bug, it's a feature! :-)

Seriously, there are no ACEs in the enableVML.inf script. It simply sets the inheritance bits and triggers inheritance propagation. That propagates the parent's permission down to the file.