Winapi: Does LOGON32_LOGON_INTERACTIVE give restricted token?

匿名 (未验证) 提交于 2019-12-03 01:33:01

问题:

What I'm trying to understand is whether LogonUser with LOGON32_LOGON_INTERACTIVE produces restricted token or not? Here is my code:

int davai() { FILE * fp;  fp = fopen ("C:\\tmp\\davai.txt", "a"); fprintf(fp, "shevedi davai"); fflush(fp);  HANDLE token = NULL; HANDLE dupToken = NULL;  if(!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_DUPLICATE, &token)) {   fprintf(fp, "davai: OpenProcessToken cheijva. %d\n", (int)GetLastError());   fflush(fp); }  if (DuplicateTokenEx(token, MAXIMUM_ALLOWED, NULL, SecurityDelegation,                           TokenPrimary, &dupToken) == 0) {   fprintf(fp, "davai: OpenProcessToken DuplicateTokenEx. %d\n", (int)GetLastError());   fflush(fp); }  PTOKEN_GROUPS pPrivilegesToken = NULL; DWORD cbSize = 0;  GetTokenInformation(dupToken, TokenGroups, NULL, 0, &cbSize);  pPrivilegesToken = (PTOKEN_GROUPS) LocalAlloc(LPTR, cbSize);  if (GetTokenInformation(dupToken, TokenGroups,                               pPrivilegesToken, cbSize, &cbSize) == FALSE) {   fprintf(fp, "davai: GetTokenInformation cheijva. %d\n", (int)GetLastError());   fflush(fp); }  char * gio;  for (ULONG i = 0; i < pPrivilegesToken->GroupCount; i++) {   if (ConvertSidToStringSid(pPrivilegesToken->Groups[i].Sid, &gio) == 0)   {     fprintf(fp, "davai: ConvertSidToStringSid cheijva. %d\n", (int)GetLastError());     fflush(fp);   }    fprintf(fp, "Value: %s attribute -> %ld \n",gio, pPrivilegesToken->Groups[i].Attributes);   fflush(fp); }  LocalFree (gio);  return 1; } 

which is run by a token which was obtained by LOGON32_LOGON_INTERACTIVE. And my output is this:

Value: S-1-5-21-1018819917-2920201817-244685803-513 attribute -> 7  Value: S-1-1-0 attribute -> 7  Value: S-1-5-21-1018819917-2920201817-244685803-1000 attribute -> 7  Value: S-1-5-32-544 attribute -> 16  Value: S-1-5-32-545 attribute -> 7  Value: S-1-5-4 attribute -> 7  Value: S-1-2-1 attribute -> 7  Value: S-1-5-11 attribute -> 7  Value: S-1-5-15 attribute -> 7  Value: S-1-5-5-0-19732224 attribute -> -1073741817  Value: S-1-5-64-10 attribute -> 7  Value: S-1-16-8192 attribute -> 96  

Notice the 16 with Administrators Group. If I use LOGON32_LOGON_BATCH I get this:

S-1-5-21-1018819917-2920201817-244685803-513 attribute -> 7  Value: S-1-1-0 attribute -> 7  Value: S-1-5-21-1018819917-2920201817-244685803-1000 attribute -> 7  Value: S-1-5-32-544 attribute -> 15  Value: S-1-5-32-545 attribute -> 7  Value: S-1-5-3 attribute -> 7  Value: S-1-2-1 attribute -> 7  Value: S-1-5-11 attribute -> 7  Value: S-1-5-15 attribute -> 7  Value: S-1-2-0 attribute -> 7  Value: S-1-5-5-0-20537541 attribute -> -1073741817  Value: S-1-5-64-10 attribute -> 7  Value: S-1-16-12288 attribute -> 96  

I also found that some people have same problem as I do.
1)Perl: IsAdminUser returns incorrect value
2)In Windows: How do you programatically launch a process in administrator mode under another user context?
3)How to call LogonUser() to get a non-restricted full token inside a Windows Service with UAC enabled?

It seems to me that LOGON32_LOGON_INTERACTIVE produces restricted token (or is it that just different types of logons produce different kind of token?), Is there any documentation that would verify that I'm right?

回答1:

Does LOGON32_LOGON_INTERACTIVE give restricted token?

Yes, for all interactive logon types : { Interactive, RemoteInteractive, CachedInteractive, CachedRemoteInteractive }

let debug lsass.exe and look what happen during call to LsaApLogonUserEx2 (this function is called in context of lsass when client process called LsaLogonUser or it shell LogonUser)

if login is ok, the lsass must create new token for logged user. this done in function LsaBuildAndCreateToken (of course this is internal implementation and name of this function can changed from version to version, but general how it worked - unchanged). so i trace this function under debugger - look at call tree at the right (this is for interactive logon)

look for red squire - here in ESI - LogonType - SECURITY_LOGON_TYPE enumeration value

so code in general is next:

    SECURITY_LOGON_TYPE LogonType;     switch (LogonType)     {     case Interactive://2     case RemoteInteractive://10      case CachedInteractive://11     case CachedRemoteInteractive://12         // optimization (LogonType == 2) || (LogonType - 10) <= 2         BOOLEAN b, c;         if (0 <= LsapShouldSplitToken(Sid, &b,&c) && b)         {             LsaSplitElevatedToken(..)         }         break;     } 

this mean that lsass try restrict ONLY INTERACTIVE logon types, if will be another logon type, say Batch - token will never be filtered.

next interesting point - let look for LsapShouldSplitToken function

who know x64 - can understand code :) in general if LUA not enabled - dont filter token. if global variable LsapGlobalFilterAdministratorToken is false - check are user is built-in admin - check RID of Sid - are it 0x1f4 - DOMAIN_USER_RID_ADMIN (in other words built-in admin restricted only when LsapGlobalFilterAdministratorToken true - based on global comp politics (gpedit.msc) ) - and returned result of query 10+4=0x14=TokenElevation and returned value of TokenIsElevated

so if TokenIsElevated is true lsass call (not forget only for Interactive logon type) LsaSplitElevatedToken - what this function is doing visible in image:

created additional logon session (elevated and not elevated process for same user run in different logon sessions), created else one token (LsapCreateTokenObject) and it filtered by call NtFilterToken(hToken, LUA_TOKEN, 0, 0, 0, &hNewToken) (the win32 api CreateRestrictedToken is shell over NtFilterToken)



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!