views:

387

answers:

2

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();
    }
}
A: 

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)

GWLlosa
That's the problem, I can't remotely edit the key because UAC is on. I'll be running this code on thousands on machines, and they're all required to be running UAC unfortunately :/
Quanta
+1  A: 

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

Adam Driscoll
Good tip, but unfortunately, UAC is required to be turned on across the domain by policy. Also, doesn't the machine require a restart after the registry value is changed?
Quanta
Yeah it would require a restart. Seems like there should be a way around this...
Adam Driscoll
Did you try adding you user to the local admin group? According to the link I posted: 'If your computer is part of a domain, connect to the target computer using a domain account that is in the local Administrators group of the remote computer. Then UAC access token filtering will not affect the domain accounts in the local Administrators group.' I don't know if this would be possible in your circumstance.
Adam Driscoll
Unfortunately, yes, I've tried that (see the first para of my post). I think msdn is incorrect in saying that, "Then UAC access token filtering will not affect the domain accounts in the local Administrators group" because it definitely seems to unless I'm missing something... I hope I'm missing something. Surely someone out there's remotely edited a registry using WMI?
Quanta
Yeah really....It wouldn't be the first time MSDN was wrong.
Adam Driscoll
Got it... notice how my ManagementClass is NOT parameterized with the connection object. I've been executing these functions locally for the past two days like an EPIC-FAIL N00b-tard dumba**. As a work-around, I made a .reg file, pushed it to the remote machine, ran it, and got an error code of 8 on win32_process. I thought that was strange so I decided to run notepad and noticed that it'd executed in front of my face instead of on the remote machine.The correct code was something like: ManagementClass mc = new ManagementClass(conn, new ManagementPath("StdRegProv"), null);
Quanta