Kaseya Community

Getting a command to run in an agent procedure that requires an elevated command prompt.

This question is answered

We're trying to create a workaround to the current IE vulnerability.  One of MS's recommendations is to either unregister VGX.DLL or change the permissions on the file.

First we tried unregistering it and we found that required an elevated command prompt and could not get it to run as an agent procedure. I also tried writing it as a bat file and downloading and running it, but it would not run that way either.  Changing the permission on the file requires taking ownership of it and that requires an elevated command prompt.

I tried running the script commands 'as system' and specifying a user and running as that user, but apparently neither of these are equivalent to an elevated command prompt.

How can we get a command to run in an agent procedure that requires an elevated command prompt?  

Thanks,
- Marc

Verified Answer
  • Issue resolved!!!!

    The problem is the %CommonProgramFile% variable.   If I echo that locally, it gives me "C:\Program Files\Common Files".   If I write a kaseya script to echo it to a text file, it gives me "C:\Program Files (x86)\Common Files".

    I changed the script to use %CommonProgramW6432% and it successfully unregisters the DLL now.

    Thanks to Quentin Jimemez on another list that spotted that one.

    Thanks,

    - Marc

All Replies
  • I just tested on a 32 bit computer and the %CommonProgramW6432% variable doesn't seem to exist.   To get around this, I just put the same command in the script twice, one with each variable and set it to continue on fail.

    Is everyone for whom this was working using a 32 bit OS, or running some 64 bit version of Kaseya?

    Thanks,

    - Marc

  • In that case the procedure should have and if64bitOS nest and a 32bitOS nest.

  • BroncoMarc
    Is everyone for whom this was working using a 32 bit OS, or running some 64 bit version of Kaseya?

    The Agent has always been 32-bit.  I'm not aware of any plans to make a 64-bit Agent.

    Those environment variables, man... they get ya every time Smile

  • Looks like Microsoft updated their advisory to list off the commands for both 32-bit and 64-bit OSes using Internet Explorer: https://technet.microsoft.com/library/security/2963983#sectionToggle1

    The drawback to this approach is that, "Applications that render VML will no longer do so once vgx.dll has been unregistered."

    I don't think it would be a huge hit to disable VML rendering based on what I'm reading it does: http://en.wikipedia.org/wiki/Vector_Markup_Language

    Any thoughts?

  • I'd like to see the script you are using to disable this.  I'm starting out fresh after fighting with the Flash install most of today and yesterday.  Now that I have Flash under control, I'm told that we need to address the .DLL vector as well.  I also added a reg change to see if I can get EPM turned on.  I'm thinking about not taking that route after reading Brian's post from here. community.kaseya.com/.../19888.aspx

    Can someone post it so I can see where I went wrong?

    This is what I have:

    <ScriptExport xmlns:xsi="www.w3.org/.../XMLSchema-instance" xmlns:xsd="www.w3.org/.../XMLSchema" xmlns="www.kaseya.com/.../Scripting">

    <Procedure name="IE Exploit - CVE-2014-1776" treePres="3" id="493714196" folderId="33186969229242912114933267" treeFullPath="myProcedures - mjones">

    <Body description="This is to mitigate the risk from: CVE Reference - CVE-2014-1776">

    <If description="This will unregister the VGX.DLL on 32bit Windows systems">

    <Condition name="Windows 32 or 64 Bit Check">

    <Parameter xsi:type="EnumParameter" name="Condition" value="NotExists"/>

    </Condition>

    <Then>

    <Statement name="ExecuteShellCommand" continueOnFail="false">

    <Parameter xsi:type="StringParameter" name="Command" value=""%SystemRoot%\System32\regsvr32.exe" -u "%CommonProgram32%\Microsoft Shared\VGX\vgx.dll""/>

    <Parameter xsi:type="EnumParameter" name="ExecuteAccount" value="System"/>

    <Parameter xsi:type="BooleanParameter" name="Is64Bit" value="False"/>

    </Statement>

    </Then>

    </If>

    <If description="This will unregister the VGX.DLL on 64bit Windows systems">

    <Condition name="Windows 32 or 64 Bit Check">

    <Parameter xsi:type="EnumParameter" name="Condition" value="Exists"/>

    </Condition>

    <Then>

    <Statement name="ExecuteShellCommand" continueOnFail="false">

    <Parameter xsi:type="StringParameter" name="Command" value=""%SystemRoot%\System32\regsvr32.exe" -u "%CommonProgram64%\Microsoft Shared\VGX\vgx.dll""/>

    <Parameter xsi:type="EnumParameter" name="ExecuteAccount" value="System"/>

    <Parameter xsi:type="BooleanParameter" name="Is64Bit" value="False"/>

    </Statement>

    <Statement name="ExecuteShellCommand" continueOnFail="false">

    <Parameter xsi:type="StringParameter" name="Command" value=""%SystemRoot%\System32\regsvr32.exe" -u "%CommonProgramFiles32%\Microsoft Shared\VGX\vgx.dll""/>

    <Parameter xsi:type="EnumParameter" name="ExecuteAccount" value="System"/>

    <Parameter xsi:type="BooleanParameter" name="Is64Bit" value="False"/>

    </Statement>

    </Then>

    </If>

    <Statement name="SetRegistryValue" continueOnFail="false" osType="8">

    <Parameter xsi:type="StringParameter" name="RegistryPath" value="HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\Isolation"/>

    <Parameter xsi:type="StringParameter" name="Value" value="PMEM"/>

    <Parameter xsi:type="EnumParameter" name="DataType" value="String"/>

    </Statement>

    </Body>

    </Procedure>

    </ScriptExport>

  • My procedure is pretty simple...

    Mine is 3 lines long.

    regsvr32.exe /u /s "%CommonProgramFiles%\Microsoft Shared\VGX\vgx.dll"           -- Runs for 32 bit and 64 bit

    If getOS() 64-Bit Windows

    regsvr32.exe /u /s "%CommonProgramW6432%\Microsoft Shared\VGX\vgx.dll"       -- Runs for just 64 bit

    Here's the full code:

     <?xml version="1.0" encoding="utf-8" ?>

    - <ScriptExport xmlns:xsi="www.w3.org/.../XMLSchema-instance" xmlns:xsd="www.w3.org/.../XMLSchema" xmlns="www.kaseya.com/.../Scripting">

    - <Procedure name="test" treePres="3" id="1101854202" folderId="647012012613477" treeFullPath="Scripts.Windows Maintenance.Vulnerability Workarounds">

    - <Body description="Vulnerability in Internet Explorer Could Allow Remote Code Execution Unregister VGX.DLL as a workaround for the security hole. technet.microsoft.com/.../2963983.aspx">

    - <Statement name="ExecuteShellCommand" continueOnFail="true">

     <Parameter xsi:type="StringParameter" name="Command" value="regsvr32.exe /u /s "%CommonProgramFiles%\Microsoft Shared\VGX\vgx.dll"" />

     <Parameter xsi:type="EnumParameter" name="ExecuteAccount" value="System" />

     <Parameter xsi:type="BooleanParameter" name="Is64Bit" value="False" />

     </Statement>

    - <If description="">

    - <Condition name="Windows 32 or 64 Bit Check">

     <Parameter xsi:type="EnumParameter" name="Condition" value="Exists" />

     </Condition>

     </If>

    - <Statement name="ExecuteShellCommand" continueOnFail="true">

     <Parameter xsi:type="StringParameter" name="Command" value="regsvr32.exe /u /s "%CommonProgramW6432%\Microsoft Shared\VGX\vgx.dll"" />

     <Parameter xsi:type="EnumParameter" name="ExecuteAccount" value="System" />

     <Parameter xsi:type="BooleanParameter" name="Is64Bit" value="False" />

     </Statement>

     </Body>

     </Procedure>

     </ScriptExport>

  • The problem that I'm running into is that Kaseya's "executeShellCommand()" step will always run in a 32-bit command shell environment.

    This means that, when your command is executed using Kaseya's executeShellCommand() step on 64-bit machines, the %CommonProgramFiles% variable will always be "C:\Program Files (x86)\Common Files", when, if you actually execute the shell command on a 64-bit command prompt, you'll get the expected value of "C:\Program Files\Common Files" (sans the (x86)).  Ergo, you'll never get that damn DLL unregistered.

    So, I went digging.  There's a different Agent Procedure step called executeShellCommandToVariable() that has an option to "Execute in 64-bit shell environment."

    HUZZAH, right?  Not so fast.  That functionality is broken.

    I submitted ticket #19460 on this, but here it is duplicated for your reading pleasure:

    <BEGIN TICKET 19460>

    This is obscure, so bear with me. I was trying to unregister VGX.dll and ran into issues with environment variables, namely %CommonProgramFiles% variable. In my troubleshooting, I discovered that the executeShellCommandToVariable() step is broken when it comes to executing in a 64-bit shell.

    In Windows alone, when you do an "echo %CommonProgramFiles%" in a 32-bit command prompt, you get "C:\Program Files (x86)\Common Files" as expected.

    When you do the same "echo %CommonProgramFiles%" in a 64-bit command prompt, you get "C:\Program Files\Common Files" again, as expected.

    See exhibits A and B, where I echo out %CommonProgramFiles% and %ProgramFiles% in x64 and then x86 Command Shells. Again, this is all as expected.


    The problem comes in when you try to have Kaseya do the same by using the executeShellCommandToVariable() step with "Execute in 64-bit shell environment" set to True. See Exhibit C - Execute in 64-bit shell environment.

    I have also attached the Agent Procedure. In instances where you see "true" highlighted, it means that it's /supposed/ to be executing the command in a 64-bit shell environment.

    2742.Exhibit D - Procedure executeShellCommandToVariable x86-x64 Shell Test.xml

    EDIT EDIT EDIT: Long day... I swapped the color scheme on accident, so from here on out, x86 is yellow, and x64 is purple.  Sorry.  Conclusions are still accurate.

    In a true 64-bit shell, the expected output of "echo %ProgramFiles%" should be "C:\Program Files"... but Kaseya instead returns "C:\Program Files (x86)" as though it was executed in a 32-bit shell environment (despite 64-bit shell being set to true). Exhibit F shows the Agent Procedure Log for same, run on a 64-bit machine. I've used arrows to call out the output that is incorrect.

    EDIT EDIT EDIT: The incorrect lines are called out as wrong here... the arrows should point to the lines highlighted in purple where it's "supposedly" executing in a 64-bit shell.  Conclusions are still accurate.

    I'm therefore left to conclude that "Execute in 64-bit shell environment" has no effect at all and is, in fact, broken.

    Let me know if you need any additional information.

    <END TICKET 19460>

    The only fix that I'm aware of at this point is to use %CommonProgramW6432% as your path variable on 64-bit Windows installations, because even when executed in a 32-bit shell via executeShellCommand() or the (broken) executeShellCommandToVariable(), it returns the proper 64-bit path:

    Hope this saves you some time, and thanks to  for finding that magic variable!



    Swapped color schemes on accident and used arrows to call out the wrong output. Added EDIT EDIT EDIT to denote these mistakes in the screenshots. Long day, sorry folks. Conclusions are still accurate... executeShellCommandToVariable's 64-bit shell execution remains broken.
    [edited by: Brian Dagan at 1:15 PM (GMT -7) on Apr 30, 2014]
  • ExecuteShellCommandToVariable is just a wrapper for ExecuteShellCommand.

    ExecuteShellCommand does have an option for 64-bit which ExecuteShellCommandtoVariable is passing (the interfaces where you select 64-bit in the steps are slightly different).

    The core issue is that ExecuteShellCommand does not in fact appear to be generating the right environment variables for a 64-bit shell, or is simply not actually executing in a 64-bit shell in the first place.



    .
    [edited by: Ben at 1:46 PM (GMT -7) on Apr 30, 2014]
  • Thanks for checking into this, .  I dissected subScripts.xml, but (if I'm reading it right), the executeShellCommandToVariable() function doesn't appear to do anything differently based on whether "Execute in 64-bit shell environment" is true or false... it's still calling an executeShellCommand() (as you noted) and piping STDOUT and STDERR to a temporary file for later transformation into #global:cmdResults#.

    I look forward to having a Dev or whomever have a looksee.  Thanks for verifying I'm not crazy :-)

  • I have published my version of the VGX.dll registering/unregistering script in the Knowledge Exchange.

    Hope you find it useful!  It supports both unregistering the DLL, and re-registering same once Microsoft fixes the underlying vulnerability.

    http://community.kaseya.com/resources/m/knowexch/86513.aspx

  • Any idea when we will get the MS patch released to us in Patch Management? technet.microsoft.com/.../ms14-021

  • Dan, it will show up in Patch Management the moment Microsoft makes it available.