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.

 

Manage IIS on Server Core remotely

I’ve started to mange server core installations more and more. I recently required to manage on that was utilize IIS. While I’m fairly used to IIS manager, I wasn’t exactly quite sure how remote management worked.

At first I thought it was a part of RSAT, nope, but fret not it is a feature of Windows, just not enabled by default.

As I expected there to be a bunch of configuration BS required figured I’d google how to do it instead of googling errors. 😀 I found this really nice right tot the point YouTube video. Luckily this made my life easy.

So on the Core server:

#Install the required service
Install-WindowsFeature -Name Web-Mgmt-Service

#enable IIS remote management
reg add HKLM\SOFTWARE\Microsoft\WebManagement\Server /v EnableRemoteManagement /t REG_DWORD /d 1

#Enable service at boot
Set-Service WMSVC -StartupType Automatic

#Enable Service
Start-Service WMSVC

On the Client Machine (Windows 7-10)

#Enable IIS management tools
Programs and Features -> Turn Windows Features on or off -> IIS -> (check off all items under Web Management Tools, you may not need them all but to be safe doesn’t hurt to add them)

#Open IIS Manager
Either through Server Manager -> manage -> IIS
Or Under the Star menu -> Admin Tools -> IIS Manager

*NOTE* Don’t bother adding the IIS manager Snap-in to an existing MMC session, I found it’s missing the top menu bar.

*NOTE 2* You also need to install IIS Manager for Remote Administration 1.2 (Cause you know this isn’t bundled with RSAT, cause… reasons)
Else you’ll be missing the connect to server option under the file menu.

*UPDATE* Grab it from here (good drive share) as MS for some reason has removed the source link in place of a 404.

*NOTE 3* You have to prepend the admin user name with the domain name, else the connection will failed stating unauthorized.

Thanks SSmith!