Larry Smith said:
In all honesty your explanation of the situation is very puzzling. If I
undserstand what you're saying then my contention is that WMI is providing
access to something that non-admin users don't normally have access to. If
a regular user tries to access another logon session's handle via
"OpenProcess()" then it will fail because they don't have
"SeDebugPrivilege" in their token. Based on what you've described however,
WMI *will* provide access to the same (or related) information by
specifying "identity" as the impersonation level (which apparently is
something different than "SecurityIdentification" in the WinAPI - see here
http://msdn2.microsoft.com/en-us/library/aa379572.aspx). My question then
is why?
I know, WMI is a complex distributed architecture.
Talking about processes, WMI does give access to process INFO, that doesn't
mean that you are also allowed to perform all possible actions on the
process object.
WMI is a provider/consumer based architecture. One of the most important
providers is CIMWIN32 (WMI's root\cimv2 namespace), a number of system
components do load provider components (COM DLL's), or do keep dynamic
structured info for the providers to be picked-up when needed (through
shared memory segments), this complex structure forms the cimwin32
provider. Each provider is also registered with WBEM (which is WMI) which
keeps a repository describing the providers features (classes properties
etc) , and WMI keeps also static and semi-dynamic instance data in this
store, this sore plus the dynamic instance data held by the components is
what is called the metabase. You can check the repository is
%Windir%\system32\wbem\repository.
There are different provider types, like there are instance providers,
method providers, event providers etc.
When we talk about Process info we are talking about the Win32_process class
"instance" provider, a consumer can ask about the state of a specific
process by means of a WQL query.
Say a consumer needs the status of a process with PID = 123, for this he
issues a query like :
Select * from WIn32_Process where processid=123 ,
this one is passed to WMI, WMI authenticates and performs an access check to
see whether the caller is allowed to "read" properties from this namespace
class (subject of WMI's security settings). When this check succeeds, he
loads the provider for the Process class (that is cimwin32 in root\cimv2),
if not already loaded, and passes the query to the provider. One step
performed by the provider in this case is a call to "OpenProcess" passing
the pid requested as argument. When the thread has no "SeDebugPrivilege" in
its token, the call will fail and the provider will pick-up the data
provided by the system component, in case of the above query this is the
handle value of the corresponding process. Note I said the "handle value",
which is nothing special as the handle value is the same as the PID and is
nothing else than an index in the process handle table. The caller cannot do
anything with this handle value, security is not compromised. With this
handle value as key, WMI picks the instance from the dynamic data blob
provided by the system component, this structured data blob is precisely
described in the repository and is returned to the consumer as instance data
for the process with PI=123.
You can check this process yourself by means of the wbemtest utility, run it
as non admin and do some experiments.
Now, the Win32_process class has also an associated method provider, and
this one implements methods like Create, Terminate, AttachDebugger etc..
Say that a consumer wants' to terminate a process, to do this he has to get
the instance like above and when done he has to execute a method on the
class (Win32_Process) of this instance. In this case WMI will perform an
access check to see whether the consumer is allowed to execute methods on
this namespace class, when it's the case, he will call the "Terminate"
method of the provider (remember providers are COM servers), the Terminate
method will call Win32 TerminateProcess as part of it's implementation and
when when the issuer (that is the impersonator) is allowed to kill the
process the API will succeed, else the API fails.
So in case the client had specified impersonate when connecting, the
provider will execute on a thread that impersonates the consumer and the
call will succeed for all process owned by this caller, all others will
fail. If the caller is an "administrator" he can do pretty much what he
likes, if he's a standard user he can only do what a standard user can do,
no security is compromised.
If the caller sets "identity" when connecting, he can pretty much do
nothing, as the thread will now impersonate "Local Service" and this one is
not allowed to execute any method.
There is a lot more to tell about this, the above is only a small fraction
of the total picture, just experiment yourself, run wbemtest, look at the
processes using tools like "processexplorer", attach a debugger to the WMI
hosting process, look at the providers getting loaded, check the executing
threads tokens and set breakpoints on critical API's you want to trace. This
will take some time, but if you are interested you will sure understand how
things fit together. Take also special notice of the DLL's loaded in several
service process (you'll see a lot of the load wbemcore.dll), also take note
of the shared memory segments like there are:
\BaseNamedObjects\__ComCatalogCache__
and the events like:
\BaseNamedObjects\EVENT_READYROOT/CIMV2PROVIDERSUBSYSTEM
these form the channels over which WMI communicates with the system
components.
Watch the WMI hosting process getting active and getting turned of (DCOM
lifecycle management comes into play here).
There's a dual and conflicting system of security here. Either MSFT
considers it safe for a normal user to access another logon session's
process or they don't. It makes no sense to say you're not allowed to do
this using "OpenProcess()" because you lack a required privilege but OTOH
(wink, wink) just use WMI as a (wide-open) backdoor. If so then why isn't
this privilege simply removed as a prerequisite for calling "OpenProces()"
in the first place.
See above, WMI does not pass a usable handle back to the consumer, only an
handle value, which you can even guess as it's the same as the PID.
Also keep in mind that you can't use an arbitraty handle across process
boundaries, unless the owner pushes the handle in your process handle table
by means of a DuplicateHandle call.
Perhaps it's for backwards compatibility reasons but
obviously it's not a security issue anymore (according to MSFT). In fact,
your contention that WMI is much easier and safer because users don't need
to run with these elevated privileges (for some things) doesn't apply in
an environment where those privileges *are* needed. Therefore, it's not
only *not* a problem to have them, but it's an intrinsic requirement
though it should be kept to a minimum of course (where access is always
govenred on a need-to-know basis). In our on-going example then if you
really don't need these privileges then sure, don't grant user rights that
they don't need. Again however, why does "OpenProcess()" say that you *do*
need them.
"OpenProcess" is the oldest API that exists in WIN32, it's also what I call
a "gateway "API, if you can call it to get a process handle, you can use
that handle without needing any further access checks. Why it requires
"SeDebugPrivileges" is because it was supposed to be called from Debuggers
only (and administrators and the TCB). But there is nothing inherently
dangerous about calling OpenProcess to get an handle, what should have been
protected is what you do with this handle, but MSFT choosed to protect the
root of all the API's that needed a process handle, so they did not need to
enter the kernel each time a handle was passed in another API (obviously for
performance reasons). This is much like there is done at the Filesystem
level, here access checks are only done when you open a file, no further
checks are done when you access the file!!
Pre-XP requires a caller to run in the TCB in order to call LogonUser, lucky
for us all MSFT has lifted this requirement as from XP on.
I'm pretty sure they cannot lift this requirement on "OpenProcess" without
breaking a lot of code, and without the need to change a lot of their own
API's.
Finally, as for DCOM, this is the distrbuted component of the COM SCM.
They're not the same so I don't see why it even comes into the picture
DCOM is a location independent IPC mechanims which can be used
"cross-process, local system" and "cross-process, remote systems". What we
are talking here (what the OP was talking about) is "cross-process, local
system". local DCOM uses shared memory as RPC channel, also called LRPC,
this is an highly optimized IPC mechanism. There ar no security mechanisms
involved no network components are used, thisngs get completely different
when talking cross machine. Note, however, that WMI can also ise COM, that
is it can load providers in-process of the consumer, VISTA and Windows 2008
provide more of these providers, but this is FAR beyond the scope of this NG
and thread.
unless a remote call is required (and even then why is DCOM used given its
notorious configuration problems and issues with firewalls). My experience
with WMI is limited so I can't really comment on its particular security
requirements. After considering what you've said however coupled with a
quick scan of links such as
http://msdn2.microsoft.com/En-US/library/aa390428.aspx and
http://msdn2.microsoft.com/En-US/library/aa389290.aspx, I maintain it's
not as simple as you would have me believe (from a security perspective
anyway). I think I'll put the issue to rest now however but will read any
final follow-up you might want to provide
I never said it was simple, basically it's simple, but it can get pretty
complex, as long as you are talking about local server/client connections
(cross-process same machine) over DCOM, there is no issue with firewalls, if
you are talking about cross machine DCOM then there are. This is the case
with all distributed systems, all of hem are using the network so all of
them are confronted with firewalls these days. Note also that WMI is about
enterprise management, it's not something you will use at home.
Willy.