WMI Permissions on Server Core

I’ve talked about WMI before… WMI and the WBEMTEST – Zewwy’s Info Tech Talks however, in that blog post I simply stated “lets grant it the basic enable and remote access on the WMI object… so back on the server we want to be monitored via WMI…” and simply opened up wmimgmt (WMI Control MMC snapin), and expanded the root node under the security tab…

So easy.. until it’s not… duhh duuhhh duhhhhhh, Core Server. Now some of you might be snapping, like “duhhhh the WMI Control has connect to remote server, just use a management machine to remotely connect using it”. Until you realize that even though the connection appears fine:

Attempting to expand the Root node does nothing:

I don’t know about you, but that’s usually how I deal with this. Now server core doesn’t have this tool available to run locally, so you can’t do it directly at the server either. What do we do?

If you just need to audit a namespace specifically you can just call the systemsecurity class’s getSecurityDescriptor method via wmic:

wmic /namespace:\\root\cimv2 path __systemsecurity call getSecurityDescriptor

this is just a string output though, and you also kinda have to now what each “mask” is supposed to represent. If you need a quick one off to check between servers for differences, it works.

During my research into this I found an old Microsoft blog post from a “Principal Software Engineer” named Steve Lee. Dissecting the script I found you could manually iterate through each in a more proper object oriented manner using “invoke-WmiMethod”

((Invoke-WmiMethod -Name GetSecurityDescriptor -Namespace "root\cimv2" -path "__systemsecurity=@").Descriptor).DACL[0].Trustee.Name

and manually iterating the array “DACL[0…x]” in the powershell cmdlet. All his script does it build an object array of users and then spits them back out… here I tweaked it for simple local runage to verify that I had 4 objects with permissions on as I iterated above…

Param ( [parameter(Mandatory=$true,Position=0)][string] $namespace)
Process {
    $ErrorActionPreference = "Stop" 
    Function Get-PermissionFromAccessMask($accessMask) {
        $WBEM_ENABLE = 1
        $WBEM_METHOD_EXECUTE = 2
        $WBEM_FULL_WRITE_REP = 4 
        $WBEM_PARTIAL_WRITE_REP = 8 
        $WBEM_WRITE_PROVIDER = 0x10 
        $WBEM_REMOTE_ACCESS = 0x20
        $READ_CONTROL = 0x20000
        $WRITE_DAC = 0x40000
 
        $WBEM_RIGHTS_FLAGS = $WBEM_ENABLE,$WBEM_METHOD_EXECUTE,$WBEM_FULL_WRITE_REP, $WBEM_PARTIAL_WRITE_REP,$WBEM_WRITE_PROVIDER,$WBEM_REMOTE_ACCESS, $WBEM_RIGHT_SUBSCRIBE,$WBEM_RIGHT_PUBLISH,$READ_CONTROL,$WRITE_DAC
        $WBEM_RIGHTS_STRINGS = "Enable","MethodExecute","FullWrite","PartialWrite", "ProviderWrite","RemoteAccess","Subscribe","Publish","ReadSecurity","WriteSecurity"
 
        $permission = @()
 
for ($i = 0; $i -lt $WBEM_RIGHTS_FLAGS.Length; $i++) {
            if (($accessMask -band $WBEM_RIGHTS_FLAGS[$i]) -gt 0) { 
                $permission += $WBEM_RIGHTS_STRINGS[$i]
            }
        }
    $permission
    }
 
    $INHERITED_ACE_FLAG = 0x10
    $invokeparams = @{Namespace=$namespace;Path="__systemsecurity=@";Name="GetSecurityDescriptor"}
    $output = Invoke-WmiMethod @invokeparams
 
    if ($output.ReturnValue -ne 0) {
        throw "GetSecurityDescriptor failed: $($output.ReturnValue)"
    }
 
    $acl = $output.Descriptor
 
    foreach ($ace in $acl.DACL) {
        $user = New-Object System.Management.Automation.PSObject
        $user | Add-Member -MemberType NoteProperty -Name "Name" -Value "$($ace.Trustee.Domain)\$($ace.Trustee.Name)"
        $user | Add-Member -MemberType NoteProperty -Name "Permission" -Value (Get-PermissionFromAccessMask($ace.AccessMask))
        $user | Add-Member -MemberType NoteProperty -Name "Inherited" -Value (($ace.AceFlags -band $INHERITED_ACE_FLAG) -gt 0)
        $user
    }
}

and sure enough:

But, how do you add or delete? Here’s Graeme Bray updated version of Steve Lee’s set script.

It was a bit annoying noticing that permissions is set as an optional (not mandatory) parameter (for delete operation), so when called all mandatory ones get asked, but if you pick add, it just flops cause that parameter isn’t marked as mandatory, so you gotta shove it inline after all the other ones:

Can I set permissions without a third party script? in theory, yes, but have fun building each object manually (lines 148 – 169). I generally would love to pump out a oneliner but that would seem to be a little difficult considering the script is 200 lines of code.

And deleting via the script:

Or use the “official” PowerShell Gallery | WmiNamespaceSecurity 0.3.0 module.

Install-Module -Name WmiNamespaceSecurity

requires trusting the good ol PSGallery. Whatever it takes.

I unno, I’m not an expert at this DCS rubbish.. so, I couldn’t get the latest module to work for me. I’m not building a whole “configuration file”, a “MOF (Managed Object Format)” to run some BS “DSC (Desired State Configuration)” via some BS “Start-DSCConfiguration” or “mofcomp.exe” just cause this stupid ass fucking WMI security uses some BS “SDDL (Security Descriptor Definition Language)” of gobbly gook shit ACL design.

Fuck WMI… shits so annoying. Just use the old script which was simple and it worked, man over engineered shit these days… all this shit cause I couldn’t expand an object in an existing remote tool. Fuck me.

 

WMI and the WBEMTEST

WMI and the WBEMTEST

I’ll try and keep this post short, as I have many things to catch up on, and this just happened to be one of those things I haven’t done in a while and had to do today for some newer servers that have been configured.

Now since I hadn’t blogged about this myself I went out to the interests to give me a good reminder on how to accomplish this. My first hit was, Sysops… and I usually really like this site…. well till i read this…

“Access denied should be self-explanatory. The credentials you use must have administrator rights.”

Ughhhhh I’m sorry what did you just say? No I don’t think so, WMI maybe, by default, restricted, but it doesn’t require such drastic permissions to utilize.

My second find was a lot nicer, in particular telling you how to manage those permissions, without ahem need administrator access lol.

So lets follow along shall we! so much for short..

First order of busy-nas is creating a user:

Of course WMI being Windows Management Interface, means I’m making obviously a windows domain user. Nothing special, especially no admin.. 😛

Again, nothing special here. Alright now I need two servers, well I guess in this case the server being monitored is sort of like a client… ugh anyway…

I guess fo r now I’ll just login to my exchange server and wmi query another server to test out first off… mhmm all I have besides that are core servers, oh boy ok… I think I’m going to need to spin up a new testing server one second…

OK all basic settings…

remove floppy boot into EUFI:

Boot system… attach disc from local host…

lets find us some windows erver 2016…. bug CD-ROM stuck “connecting”…
Close vSphere, reopen console, try again…

always loved this trick over uploading a ISO to a datastore….

Ahh modern Windows still giving off that great nostalgic feel.. 😀

yada yada, setup, vmware tools, and join domain, you get the jist of it.

Ping and the Firewall

First order of Business Ping and the Firewall!

Ahh yes connectivity verified (I knew it was good cause I joined the system to the domain, but I like ping… just nothing like a good ICMP) good thing that m is not a u….

Anyway time to run WBEMTEST, bet the first attempt fails cause the firewall again…. hour glass… and (not responding) yeah…. sounds like a stupid firewall…

What?! no way RPC error… lol I totally saw this coming cause again a default server installation doesn’t allow these connections through the firewall by default.

This is a bit old, but lets see if it still works…

Amazing it worked… but yes this was just to verify connectivity through the firewall… so…

WBEMTEST Testing WMI with Least Privileges

OK now that we verified connectivity to the wmi stack with wbemtest using our admin account, lets do it again as a normal domain user. Just to validate these credentials were OK as a standard user i logged into a normal workstation with it, if you want to protect this even further you’d use GPOs to disallow this account local logon. Anyway…

What?! Access denied… lol again expected.. now instead of granting this account admin access, which is overkill, lets grant it the basic enable and remote access on the WMI object… so back on the server we want to be monitored via WMI…

Hope that was easy enough to follow without even saying anything.. anyway lets try that connection again…

Try 2, Scale-able

Mhmmm access still denied… lets see here

This is how I normally do it for a monitoring account anyway cause it usually needs more permissions when mointoring a server so lets try it that way… revert the direct permissions… and grant performance group access…

Now lets add wmi reader account to the dcom groujps and the performance monitor group and reboot the server…

Server rebooting, back up, and lets test that connection again on wbemtest!

and….

Bazzaaaaaa! An account thats not a admin anywhere with permissions needed to monitor your server with WMI! Use these accounts on software such as PRTG, Splunk, Zenoss, etc etc.

Hope everyone enjoyed this tutorial on WMI configuration and testing. 😀