Getting SIDs from impersonated processes

Hi all,

In my filter driver I’m trying to match Create IRPs with a user account
(the logged on user) and I’m doing this by recovering the SID from the
IRP. When I identify the file as being opened by the user, I perform
special processing. This works fine except when the create request comes
SVCHOST. In this case, the request is impersonated and the client token
gives the SID as ‘Restricted Code’ (S-1-5-12) and not that of the
requesting user.

Is this to be expected? Is there any way to identify the user making the
request?

Thanks,
Andy

Hello,

This is a very interesting process.
How can you get SID from IRP?
This is the requestor?s SID?

Thanks,
Fernando.

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com]On Behalf Of
xxxxx@ArmourSoft.com
Sent: ter?a-feira, 13 de agosto de 2002 11:12
To: File Systems Developers
Subject: [ntfsd] Getting SIDs from impersonated processes

Hi all,

In my filter driver I?m trying to match Create IRPs with a user account
(the logged on user) and I?m doing this by recovering the SID from the
IRP. When I identify the file as being opened by the user, I perform
special processing. This works fine except when the create request comes
SVCHOST. In this case, the request is impersonated and the client token
gives the SID as ?Restricted Code? (S-1-5-12) and not that of the
requesting user.

Is this to be expected? Is there any way to identify the user making the
request?

Thanks,
Andy


You are currently subscribed to ntfsd as: xxxxx@scuasecurity.com.br
To unsubscribe send a blank email to %%email.unsub%%

If I’m correct, the undelete utility from sysinternals.com shows you how
to get the SID.


Bartjan.

> SVCHOST. In this case, the request is impersonated and the client
token

gives the SID as ‘Restricted Code’ (S-1-5-12) and not that of the
requesting user.

Is this to be expected? Is there any way to identify the user making
the
request?

I had the same task about a year ago.

The below is step-by-step logic for doing this. Tested on NT4, works
fine even for accesses from SRV.
Note that SRV sometimes accesses the shares from LocalSystem account,
and not from the client’s account. This is by design.

1).
Token =
CurrentLoc->Parameters.Create.SecurityContext->AccessState->SubjectSec
urityContext.ClientToken;
if( Token == NULL )
Token =
CurrentLoc->Parameters.Create.SecurityContext->AccessState->SubjectSec
urityContext.PrimaryToken;

  1. ObOpenObjectByPointer on Token, provides hToken.

  2. ZwQueryInformationToken(hToken, TokenUser, NULL, 0, &RetLen).
    This returns the size of the SID.

  3. Allocate memory for RetLen bytes, put the pointer to
    PSID_AND_ATTRIBUTES UserBuf variable.

  4. ZwQueryInformationToken(hToken, TokenUser, UserBuf, RetLen,
    &RetLen);

  5. ZwClose(hToken)

The user’s SID is in UserBuf->Sid after this.

Max

Hi all and thanks for replying,

I must first apologise for not posting my original code. Although slightly
different to Maxim’s, it does the same job and gives the same results.

99% of the time, I get the users SID during Create as expected, but it
seems that for a few operations, this fails. I am assuming that this is
because an application has requested a COM object perform an operation and
this operation is being performed in the LocalSystem context. The only
real-world case I have of this happening is when a word doc with a
containing an excel spreadsheet link is saved and closed quickly after
making changes to the excel data. This test is timing sensitive and very
hard to reproduce. Thankfully, we have found that the Ziff Davis Content
Creation benchmark also causes this to happen on the first application
test (either Adobe Premiere or Macromedia Director).

It seems that the impersonation token is not an impersonation of the user
but a restricted version of the svchost process token. I am a little
surprised to find user operations being performed in the context of the
system. Isn’t this a potential security hole?

Anyway, it seems my original code is working. I now just have to figure
out how to deal with this situation.

Thanks –
Andy

The code that I have been using is as follows:

PSECURITY_SUBJECT_CONTEXT pSubjectSecurityContext =
&pCurrentStackLocation->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext;

PACCESS_TOKEN pToken = SeQuerySubjectContextToken( pSubjectSecurityContext
);
if ( !pToken )
return STATUS_UNSUCCESSFUL;

// Recover the users token
TOKEN_USER * pTokenUser;
rc = SeQueryInformationToken( pToken, TokenUser,
reinterpret_cast(&pTokenUser) );
if ( STATUS_SUCCESS != rc )
return STATUS_UNSUCCESSFUL;

// Check the token for validity
PSID pUsersSid = pTokenUser->User.Sid;
if ( !RtlValidSid( pUsersSid ) )
{
ExFreePool( pTokenUser );
return STATUS_UNSUCCESSFUL;
}

unsigned int nSidLength = RtlLengthSid( pUsersSid );

// Copy the SID

// Free the token
ExFreePool( pTokenUser );

> 99% of the time, I get the users SID during Create as expected, but
it

seems that for a few operations, this fails. I am assuming that this
is
because an application has requested a COM object perform an
operation and

Have you tested your code with SRV?

Max

Yes, I have tested against SRV, and the code successfully identifies the
calling user. I am building a security product and one of the design goals
was to prevent access to files from remove clients. Therefore my code
identifies the remote user as being different from the local user and
denies access.

  • Andy