简体   繁体   中英

WMI: Editing the Registry Remotely

I'm trying to use the following code (poorly written, but it's just a proof of concept) to edit the registry of a computer on a domain. I have a domain account, and I've verified that the domain admin group is present in the local admin group on the machines I'm attempting to affect. I've connected to these other machines to perform other administrative type tasks, so I'm sure that I have administrative privileges on these hosts.

All of StdRegProv's "get" methods work fine ( http://msdn.microsoft.com/en-us/library/aa393664%28VS.85%29.aspx ) but the "set" or "create" methods as well as check access all return "5" which is "Error_Access_Denied" according to winerror.h. So there's the problem: why do I get access denied when attempting to modify the registry? If anyone can help me figure this out, you'd have my utmost appreciation!

I almost forgot, when I fire up Visual Studio in admin mode on my local machine and run the code against the local machine, it works flawlessly. If I don't start in admin mode on the local machine, the code fails, so I suspect there's a UAC problem maybe?

UPDATE: Using regedit and connecting to the remote computer, I CAN change the registry key which leads me to believe that this is not a UAC issue, but it executes with a local WMI connection when running in elevated mode on my own machine, so maybe it is UAC. Also, winXP machines return the same error-code (5, ERROR_ACCESS_DENIED) which leads me to believe that it's not UAC... this sucks.

SOLVED: The ManagementClass object is using the wrong override; it must be parameterized with the ManagementScope, otherwise, you're just executing functions locally.

ManagementClass mc = new ManagementClass(scope, new ManagementPath("StdRegProv"), null);

Yes, I'm an epic-fail :/ 9K lines of code, and this line held me up the longest of them all.

using System;
using System.Management;


public class EditRemoteRegistry
{
    public static void Main(string[] args)
    {
        ConnectionOptions options = new ConnectionOptions();
        options.EnablePrivileges = true;
        options.Impersonation = ImpersonationLevel.Impersonate;
        options.Password = "password goes here";
        //options.Authority = "my company's domain";
        //options.Username = "Admin username";

        ManagementScope scope = new ManagementScope("\\\\arbitraryhost\\root\\default", options);
        scope.Connect();

        ManagementClass mc = new ManagementClass("StdRegProv");

        ManagementBaseObject inParams = mc.GetMethodParameters("CreateKey");
        inParams["hDefKey"] = (UInt32)2147483650;
        inParams["sSubKeyName"] = "Software\\Test";
        ManagementBaseObject outParams = mc.InvokeMethod("CreateKey", inParams, null);
        //Should return a 0, but returns a 5, "Error_Access_Denied"
        Console.WriteLine("CreateKey Method returned " + outParams["returnValue"]);

        //This chunk works fine
        ManagementBaseObject inParams5 = mc.GetMethodParameters("GetDWORDValue");
        inParams5["hDefKey"] = 2147483650;
        inParams5["sSubKeyName"] = "Software\\Test";
        inParams5["sValueName"] = "testDWORDvalue";
        ManagementBaseObject outParams5 = mc.InvokeMethod("GetDWORDValue", inParams5, null);
        Console.WriteLine("GetDWORDValue returned " + (UInt32)outParams5["returnValue"] + " ");
        Console.WriteLine((UInt32)outParams5["uValue"]);


        ManagementBaseObject inParams6 = mc.GetMethodParameters("SetStringValue");
        inParams6["hDefKey"] = 2147483650;
        inParams6["sSubKeyName"] = "Software\\Test";
        inParams6["sValueName"] = "TestStringValue";
        inParams6["sValue"] = "Hello World!";
        ManagementBaseObject outParams6 = mc.InvokeMethod("SetStringValue", inParams6, null);
        //Should return a 0, but returns a 5, "Error_Access_Denied"
        Console.WriteLine("SetStringValue returned " + outParams6["returnValue"]);

        Console.ReadKey();
    }
}

You can also turn off remote UAC filtering.

Disabling Remote UAC by changing the registry entry that controls Remote UAC is not recommended, but may be necessary in a workgroup. The registry entryis HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\system\\LocalAccountTokenFilterPolicy. When the value of this entry is zero (0), Remote UAC access token filtering is enabled. When the value is 1, remote UAC is disabled.

http://msdn.microsoft.com/en-us/library/aa826699(VS.85).aspx

It seems that there are issues running WMI setters against machines with UAC on.

quote

From reports we're receiving from the field, it appears UAC needs to be disabled for remote WMI queries to work. With UAC running, an administrator account actually has two security tokens, a normal user token, and an administrator token (which is only activated when you pass the UAC prompt). Unfortunately, remote requests that come in over the network get the normal user token for the administrator, and since there is no way to handle a UAC prompt remotely, the token can't be elevated to the true-administrator security token.

source: http://www.poweradmin.com/help/enableWMI.aspx

Try editing the remote machine's registry key:

HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\system\\LocalAccountTokenFilterPolicy.

0 - build filtered token (Remote UAC enabled) 1 - build elevated token (Remote UAC disabled)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM