I have to admit, I really love Windows impersonation tokens! So when it comes to the possibility to “steal” and/or impersonate a token I never give up!

This is also another chapter of the never ending story of my loved “JuicyPotato”.

 So, here we are (refer to my previous posts in order to understand how we arrived a this point):

  • You cannot specify a custom port for OXID resolver address in latest Windows versions
  • If you redirect the OXID resolution requests to a remote server on port 135 under your control and the forward the request to your local Fake RPC server, you will obtain only an ANONYMOUS LOGON.
  • If you resolve the OXID Resolution request to a fake “RPC Server”, you will obtain an identification token during the IRemUnkown2 interface query.

The following image should hopefully describe the “big picture”

 

But why this identification token and not an impersonation one? And are we sure that we will always get only an identification token? We need at least an impersonation token in order to elevate our privileges!

But first of all we need to understand who/what is generating this behavior. A network capture of the NTLM authentication could help:  

The verdict is clear: in the first NTLM message, the client sets the “Identify” flag, which means that the server should not impersonate the client.

Side Note: Don’t even try to change this flag (remember, we are doing kind of MITM attack in local NTLM Authentication, so we could alter the value), the client would not answer to our NTLM type 2 message!

But why does the client activate this flag? Well, probably it’s all in this RPC API client call setup:

RPC_STATUS RpcBindingSetAuthInfoExA( 
RPC_BINDING_HANDLE Binding, 
RPC_CSTR ServerPrincName, 
unsigned long AuthnLevel, 
unsigned long AuthnSvc, 
RPC_AUTH_IDENTITY_HANDLE AuthIdentity, 
unsigned long AuthzSvc, 
RPC_SECURITY_QOS *SecurityQos 
);

More precisely in this structure:

typedef struct _RPC_SECURITY_QOS {
unsigned long Version; 
unsigned long Capabilities; 
unsigned long IdentityTracking; 
unsigned long ImpersonationType; 
} RPC_SECURITY_QOS, *PRPC_SECURITY_QOS;

The client can define the desidered impersonation level before connecting to server. At this point we can assume that this is the default:

ImpersonationType=RPC_C_IMP_LEVEL_IDENTIFY

for the COM security settings when svchost services starts the DLL inside svchost.exe.

This is also controlled in a registry key (thanks to @tiraniddo for remembering me this)  located in HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Svchost where the impersonation level can be defined overriding the default value.

In the following screen shot we can observe that all services belonging to “print” group will call the CoInitializeSecurity function with Impersonation level =3 (Impersonate)

And which service belongs to this group?

It’s the “PrintNotify” service, which can be instantiated and accessed by the following DCOM server:

Ok, let’s see what happens on a fully patchted Win10 1909 if we try to initialize this object via the IStorageTrigger, redirect to our fake OXID resolver and then intercept he authentication callbacks.

The first request with ANONYMOUS logon is relative to the redircted OXID resolution request. The two subsequent are generated by the IremUnknown2 queries, and this time we have impersonation tokens from SYSTEM!

And according to the registry configuration, we can see that the Impersonation parameter is read from the registry:

But wait, there is still another problem:

The SERVICE user’s group (which is typically the users we will “target” because they have impersonation privileges) cannot start/launch the sevice/dll and does not belong to the INTERACTIVE group.

Again, no way? Well not exactly.

With my modified JuicyPotato – juicy_2 (see previous screenshot) running as “NT AUTHORITY\Local Service”, I tested all CLISD’s (7268 in my Windows 10 1909) in order to find something else and this is the result:

There were 2 other CLSIDS which impersonate LOCAL SYSTEM:

  1. {90F18417-F0F1-484E-9D3C-59DCEEE5DBD8} which is hosted by the obsolete ActiveX Installer service:


This service belongs the “AxInstSVGroup” group, but surprisingly this group is not listed in the registry, so I would expect an Identification token! This means that the previous assumption is not always true, the impersonation level is not exclusively controlled via registry configuration…

2. {C41B1461-3F8C-4666-B512-6DF24DE566D1} This one does not belongs to a specific service but is related to an Intel Graphics Driver “IntelCpHeciSvc.exe” which hosts a DCOM server.




Clearly, the presence of this driver depends on the HW configuration of your machine.

The other CLISD’s impersonates the interactive user connected to first Session:

{354ff91b-5e49-4bdc-a8e6-1cb6c6877182 }- SpatialAudioLicenseServerInteractiveUser

{38e441fb-3d16-422f-8750-b2dacec5cefc}- ComponentPackageSupportServer

{f8842f8e-dafe-4b37-9d38-4e0714a61149} – CastServerInteractiveUser

So if you have impersonation privileges and an admin is connected interactively you could obtain his token and impersonate.

I did the same test on the CLSID’s of a Windows 2019 Server but this time was not able to get a SYSTEM impersonation token. The ActiveX Installer service is disabled by default on this OS. The only valid CLSID’s were the 3 relative to interactive user.

Well that’s all for now, the Impersonation game never ends 😉

.. and thanks to @splinter_code

Source code can be found here

Leave a comment