Scripting WMI Namespace Security (part 1 of 3)

Under most circumstances, you would never need to change WMI
namespace security
.  The default
security settings allow authenticated users read access, method execution, and
provider write permission.  Members of
the Administrators group get full access including remoting.  There may be a scenario where you want a
non-admin (could be an application account or machine account) to be able to
remote to a specific namespace, or explicitly deny a specific user certain
permissions. 

For most cases, you may want to use the wmimgmt.msc
MMC Snap-in
to modify permissions since it provides a full GUI point-and-click
experience.  For application developers,
you may want to set namespace security when the namespace is created by including
the SDDL in your MOF file
.  Even for
application developers, if the user/group is not a well-known type with a fixed
SID, the application will have to set the security during runtime
(installation) using a method similar to this blog.  For ITPros, you may want a script solution
for modifying permissions on multiple machines at the same time during runtime
(probably using AD accounts/groups).

Before we discuss how to change security on a WMI namespace,
let’s define what the WMI permissions mean:

Enable

Allows the user to read objects in a namespace.  Authenticated users by default have this permission.

MethodExecute

Allows the user to invoke a method.  Note that this doesn’t mean the method will succeed; the provider implementing the method (or the OS api being called) will have an additional access check.

FullWrite

Allows the user to write to class schema (as well as create new class schema) in the repository.  In general, only admins should have this permission since non-admins can use this ability for creating arbitrary WMI classes to end up with admin rights.

PartialWrite

Allows the user to write to static instances in the repository.  Although slightly more restrictive than FullWrite, non-admins could still use this to obtain admin rights (depending on the namespace and what classes are available), so this should be restricted to admins only.

ProviderWrite

Allows the user  to write classes and instances, but only to providers, not to the repository.  Similar to methods, providers (or the OS api) will provide additional access check.

RemoteAccess

Allows the user remote access to the namespace.  The other permissions still dictate what they can do.

Subscribe

Allows the user to publish events (only used for applications).

Publish

Allows the user to consume events (only used for applications).

ReadSecurity

Allows the user to read the namespace security descriptor.  By default, only admins have this permission.

WriteSecurity

Allows the user to modify the namespace security descriptor.  By default, only admins have this permission.

 

In each namespace, there is a singleton instance that
controls namespace security: __SystemSecurity=@.  It exposes several methods, but in this case,
we are only interested in two (available on Vista+): GetSecurityDescriptor and
SetSecurityDescriptor.  On older systems,
these two methods are not available and you would have to use GetSD and SetSD
which work on SECURITY_DESCRIPTOR structs represented as binary arrays.  Discussion on how to use those methods (which
is only really possible with C/C++) is outside of the scope of this blog post.

The basic workflow is to call GetSecurityDescriptor (this
will have to be done with an elevated admin account), modify the DACL in the
returned Win32_SecurityDescriptor and call SetSecurityDescriptor with this new
security descriptor.  In the next two
parts, I’ll show the actual Powershell scripts I wrote and will explain how it
works starting with Get-WmiNamespaceSecurity in part 2 and finally Set-WmiNamespaceSecurity
in part 3.

Steve Lee

Senior Test Manager

Microsoft