ALIGNED void EnablePriv(void) { // // enable SeRestorePrivilege so SetShortName() can do its job // WCHAR priv_space[64]; TOKEN_PRIVILEGES *privs = (TOKEN_PRIVILEGES *)priv_space; HANDLE hToken; BOOL b = LookupPrivilegeValue( L"", SE_LOAD_DRIVER_NAME, &privs->Privileges[0].Luid); if (b) { privs->Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; privs->PrivilegeCount = 1; b = OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken); if (b) { b = AdjustTokenPrivileges(hToken, FALSE, privs, 0, NULL, NULL); CloseHandle(hToken); } } }
BOOL GetProcessOwner(HANDLE hProcess, LPTSTR szOwner, size_t cchSize) { // Sanity checks if ((szOwner == NULL) || (cchSize == 0)) return(FALSE); // Default value szOwner[0] = TEXT('\0'); // Gget process token HANDLE hToken = NULL; CToolhelp::EnablePrivilege(SE_TCB_NAME, TRUE); if (!OpenProcessToken(hProcess, TOKEN_QUERY, &hToken)) { CToolhelp::EnablePrivilege(SE_TCB_NAME, FALSE); return(FALSE); } // Obtain the size of the user information in the token. DWORD cbti = 0; GetTokenInformation(hToken, TokenUser, NULL, 0, &cbti); // Call should have failed due to zero-length buffer. if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { // Allocate buffer for user information in the token. PTOKEN_USER ptiUser = (PTOKEN_USER)HeapAlloc(GetProcessHeap(), 0, cbti); if (ptiUser != NULL) { // Retrieve the user information from the token. if (GetTokenInformation(hToken, TokenUser, ptiUser, cbti, &cbti)) { SID_NAME_USE snu; TCHAR szUser[MAX_PATH]; DWORD chUser = MAX_PATH; PDWORD pcchUser = &chUser; TCHAR szDomain[MAX_PATH]; DWORD chDomain = MAX_PATH; PDWORD pcchDomain = &chDomain; // Retrieve user name and domain name based on user's SID. if ( LookupAccountSid( NULL, ptiUser->User.Sid, szUser, pcchUser, szDomain, pcchDomain, &snu ) ) { // build the owner string as \\DomainName\UserName _tcscpy_s(szOwner, cchSize, TEXT("\\\\")); _tcscat_s(szOwner, cchSize, szDomain); _tcscat_s(szOwner, cchSize, TEXT("\\")); _tcscat_s(szOwner, cchSize, szUser); } } // Don't forget to free memory buffer HeapFree(GetProcessHeap(), 0, ptiUser); } } // Don't forget to free process token CloseHandle(hToken); // Restore privileges CToolhelp::EnablePrivilege(SE_TCB_NAME, TRUE); return(TRUE); }
Figure 6-5. The main stages of process creation
Figure 6-9. Process and thread security structures
Stealing Access Tokens with Windows API
bool SbieIniServer::TokenIsAdmin(HANDLE hToken, bool OnlyFull) { // // check if token is member of the Administrators group // SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY; PSID AdministratorsGroup; BOOL b = AllocateAndInitializeSid( &NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &AdministratorsGroup); if (b) { if (! CheckTokenMembership(NULL, AdministratorsGroup, &b)) b = FALSE; FreeSid(AdministratorsGroup); // // on Windows Vista, check for UAC split token // if (! b || OnlyFull) { OSVERSIONINFO osvi; osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); if (GetVersionEx(&osvi) && osvi.dwMajorVersion >= 6) { ULONG elevationType, len; b = GetTokenInformation( hToken, (TOKEN_INFORMATION_CLASS)TokenElevationType, &elevationType, sizeof(elevationType), &len); if (b && (elevationType != TokenElevationTypeFull && (OnlyFull || elevationType != TokenElevationTypeLimited))) b = FALSE; } } } return b ? true : false; }
HRESULT my_CoImpersonateClient(void) { HANDLE hPriToken, hImpToken; BOOL ok; if (WTSQueryUserToken(0, &hPriToken)) { ok = DuplicateTokenEx( hPriToken, TOKEN_ALL_ACCESS, NULL, SecurityImpersonation, TokenImpersonation, &hImpToken); if (ok) { ok = SetThreadToken(NULL, hImpToken); CloseHandle(hImpToken); } CloseHandle(hPriToken); } return (ok ? S_OK : CO_E_FAILEDTOIMPERSONATE); }
_FX void EnableDebugPriv(void) { WCHAR priv_space[64]; TOKEN_PRIVILEGES *privs = (TOKEN_PRIVILEGES *)priv_space; HANDLE hToken; BOOL b = LookupPrivilegeValue( L"", SE_DEBUG_NAME, &privs->Privileges[0].Luid); if (b) { privs->Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; privs->PrivilegeCount = 1; b = OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken); if (b) { b = AdjustTokenPrivileges(hToken, FALSE, privs, 0, NULL, NULL); CloseHandle(hToken); } } }