// // Function : PrintPermissions // Role : Print and interpret the permissions for threads and processes // Notes : // void PrintPermissions( HANDLE hObject, bool bDesktop) { DWORD dwRet=0; DWORD dwCount=0; PACL DACL; PSECURITY_DESCRIPTOR PSD; ACCESS_ALLOWED_ACE *ACE; // http://msdn2.microsoft.com/en-us/library/aa446654.aspx dwRet = GetSecurityInfo(hObject, SE_WINDOW_OBJECT, OWNER_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, NULL, NULL, &DACL, NULL, &PSD ); if(hObject==NULL || hObject==INVALID_HANDLE_VALUE) return; if (dwRet!=ERROR_SUCCESS) { DWORD dwError = GetLastError(); fprintf(stderr,"[!] Error - %d %d - GetSecurityInfo\n", dwError,dwRet); return; } else { // http://msdn2.microsoft.com/en-us/library/aa379142.aspx if(IsValidAcl(DACL) == TRUE){ // Now for each ACE in the DACL for(dwCount=0;dwCount<DACL->AceCount;dwCount++){ // http://msdn2.microsoft.com/en-us/library/aa446634.aspx // http://msdn2.microsoft.com/en-us/library/aa379608.aspx if(GetAce(DACL,dwCount,(LPVOID*)&ACE)){ // http://msdn2.microsoft.com/en-us/library/aa374892.aspx SID *sSID = (SID*)&(ACE->SidStart); if(sSID != NULL) { DWORD dwSize = 2048; char lpName[2048]; char lpDomain[2048]; SID_NAME_USE SNU; switch(ACE->Header.AceType){ // Allowed ACE case ACCESS_ALLOWED_ACE_TYPE: // Lookup the account name and print it. // http://msdn2.microsoft.com/en-us/library/aa379554.aspx if( !LookupAccountSidA( NULL, sSID, lpName, &dwSize, lpDomain, &dwSize, &SNU ) ) { DWORD dwResult = GetLastError(); if( dwResult == ERROR_NONE_MAPPED){ fprintf(stdout,"[i] |\n"); fprintf(stdout,"[i] +-+-> Allowed - NONMAPPED - SID %s\n", sidToText(sSID)); } else if (dwResult != ERROR_NONE_MAPPED){ fprintf(stderr,"[!] LookupAccountSid Error %u\n", GetLastError()); fprintf(stdout,"[i] |\n"); fprintf(stdout,"[i] +-+-> Allowed - ERROR - SID %s\n", sidToText(sSID)); //return; } else { continue; } } else { fprintf(stdout,"[i] |\n"); fprintf(stdout,"[i] +-+-> Allowed - %s\\%s\n",lpDomain,lpName); } // print out the ACE mask fprintf(stdout,"[i] |\n"); fprintf(stdout,"[i] +-> Permissions - "); if(!bDesktop){ if(ACE->Mask & WINSTA_ALL_ACCESS) fprintf(stdout,",All"); if(ACE->Mask & WINSTA_ACCESSCLIPBOARD ) fprintf(stdout,",Clipboard"); if(ACE->Mask & WINSTA_ACCESSGLOBALATOMS ) fprintf(stdout,",Global Atoms"); if(ACE->Mask & WINSTA_CREATEDESKTOP ) fprintf(stdout,",Create Desktop"); if(ACE->Mask & WINSTA_ENUMDESKTOPS ) fprintf(stdout,",Enum Desktop"); if(ACE->Mask & WINSTA_ENUMERATE) fprintf(stdout,",Enumerate"); if(ACE->Mask & WINSTA_EXITWINDOWS ) fprintf(stdout,",Exit Windows"); if(ACE->Mask & WINSTA_READATTRIBUTES ) fprintf(stdout,",Read Attributes"); if(ACE->Mask & WINSTA_READSCREEN ) fprintf(stdout,",Read Screen"); if(ACE->Mask & WINSTA_WRITEATTRIBUTES ) fprintf(stdout,",Write Attributes"); if(ACE->Mask & SYNCHRONIZE ) fprintf(stdout,",Synchronize"); if(ACE->Mask & DELETE) fprintf(stdout,",Delete"); if(ACE->Mask & READ_CONTROL) fprintf(stdout,",Read Security"); if(ACE->Mask & WRITE_OWNER) fprintf(stdout,",Change Owner"); if(ACE->Mask & WRITE_DAC) fprintf(stdout,",Change Permissions"); if(ACE->Mask & GENERIC_READ) fprintf(stdout,",Generic Read"); if(ACE->Mask & GENERIC_WRITE ) fprintf(stdout,",Generic Write"); if(ACE->Mask & GENERIC_EXECUTE) fprintf(stdout,",Generic Execute"); if(ACE->Mask & GENERIC_ALL ) fprintf(stdout,",All"); } else { if(ACE->Mask & DELETE ) fprintf(stdout,",Desktop Delete"); if(ACE->Mask & READ_CONTROL ) fprintf(stdout,",Read Security Descriptor"); if(ACE->Mask & DESKTOP_CREATEMENU ) fprintf(stdout,",Create Menu"); if(ACE->Mask & DESKTOP_CREATEWINDOW ) fprintf(stdout,",Create Window"); if(ACE->Mask & DESKTOP_ENUMERATE ) fprintf(stdout,",Enumerate"); if(ACE->Mask & DESKTOP_HOOKCONTROL) fprintf(stdout,",Hook Windows"); if(ACE->Mask & DESKTOP_JOURNALPLAYBACK ) fprintf(stdout,",Journal Playpack"); if(ACE->Mask & DESKTOP_JOURNALRECORD ) fprintf(stdout,",Journal Record"); if(ACE->Mask & DESKTOP_READOBJECTS) fprintf(stdout,",Read Objects"); if(ACE->Mask & DESKTOP_SWITCHDESKTOP ) fprintf(stdout,",Switch Desktop"); if(ACE->Mask & DESKTOP_WRITEOBJECTS) fprintf(stdout,",Write Objects"); if(ACE->Mask & GENERIC_READ) fprintf(stdout,",Generic Read"); if(ACE->Mask & GENERIC_WRITE ) fprintf(stdout,",Generic Write"); if(ACE->Mask & GENERIC_EXECUTE) fprintf(stdout,",Generic Execute"); if(ACE->Mask & GENERIC_ALL ) fprintf(stdout,",All"); } fprintf(stdout,"\n"); break; // Denied ACE case ACCESS_DENIED_ACE_TYPE: break; // Uh oh default: break; } } } else { DWORD dwError = GetLastError(); fprintf(stderr,"[!] Error - %d - GetAce\n", dwError); return; } } } else { DWORD dwError = GetLastError(); fprintf(stderr,"[!] Error - %d - IsValidAcl\n", dwError); return; } } LocalFree(PSD); }
/* * @brief Get the UID of the current process/thread. * @param pRequest Pointer to the \c Request packet. * @returns Indication of success or failure. * @remark This is a helper function that does the grunt work * for getting the user details which is used in a few * other locations. */ DWORD populate_uid(Packet* pResponse) { DWORD dwResult; CHAR cbUsername[1024], cbUserOnly[512], cbDomainOnly[512]; BYTE tokenUserInfo[4096]; DWORD dwUserSize = sizeof(cbUserOnly), dwDomainSize = sizeof(cbDomainOnly); DWORD dwSidType = 0; memset(cbUsername, 0, sizeof(cbUsername)); memset(cbUserOnly, 0, sizeof(cbUserOnly)); memset(cbDomainOnly, 0, sizeof(cbDomainOnly)); do { if ((dwResult = get_user_token(tokenUserInfo, sizeof(tokenUserInfo))) != ERROR_SUCCESS) { break; } if (!LookupAccountSidA(NULL, ((TOKEN_USER*)tokenUserInfo)->User.Sid, cbUserOnly, &dwUserSize, cbDomainOnly, &dwDomainSize, (PSID_NAME_USE)&dwSidType)) { BREAK_ON_ERROR("[GETUID] Failed to lookup the account SID data"); } // Make full name in DOMAIN\USERNAME format _snprintf(cbUsername, 512, "%s\\%s", cbDomainOnly, cbUserOnly); cbUsername[511] = '\0'; packet_add_tlv_string(pResponse, TLV_TYPE_USER_NAME, cbUsername); dwResult = EXIT_SUCCESS; } while (0); return dwResult; }
/* * sys_getuid * ---------- * * Gets the user information of the user the server is executing as */ DWORD request_sys_config_getuid(Remote *remote, Packet *packet) { Packet *response = packet_create_response(packet); DWORD res = ERROR_SUCCESS; #ifdef _WIN32 CHAR username[512], username_only[512], domainname_only[512]; LPVOID TokenUserInfo[4096]; HANDLE token; DWORD user_length = sizeof(username_only), domain_length = sizeof(domainname_only); DWORD size = sizeof(username), sid_type = 0, returned_tokinfo_length; memset(username, 0, sizeof(username)); memset(username_only, 0, sizeof(username_only)); memset(domainname_only, 0, sizeof(domainname_only)); do { if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &token)) { OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token); } if (!GetTokenInformation(token, TokenUser, TokenUserInfo, 4096, &returned_tokinfo_length)) { res = GetLastError(); break; } if (!LookupAccountSidA(NULL, ((TOKEN_USER*)TokenUserInfo)->User.Sid, username_only, &user_length, domainname_only, &domain_length, (PSID_NAME_USE)&sid_type)) { res = GetLastError(); break; } // Make full name in DOMAIN\USERNAME format _snprintf(username, 512, "%s\\%s", domainname_only, username_only); username[511] = '\0'; packet_add_tlv_string(response, TLV_TYPE_USER_NAME, username); } while (0); #else CHAR info[512]; uid_t ru, eu, su; gid_t rg, eg, sg; ru = eu = su = rg = eg = sg = 31337; getresuid(&ru, &eu, &su); getresgid(&rg, &eg, &sg); snprintf(info, sizeof(info)-1, "uid=%d, gid=%d, euid=%d, egid=%d, suid=%d, sgid=%d", ru, rg, eu, eg, su, sg); packet_add_tlv_string(response, TLV_TYPE_USER_NAME, info); #endif // Transmit the response packet_transmit_response(res, remote, response); return res; }
static void get_sid_info(PSID psid, LPSTR *user, LPSTR *dom) { static char account[257], domain[257]; DWORD user_size, dom_size; SID_NAME_USE use; BOOL ret; *user = account; *dom = domain; user_size = dom_size = 257; account[0] = domain[0] = 0; ret = LookupAccountSidA(NULL, psid, account, &user_size, domain, &dom_size, &use); ok(ret, "LookupAccountSidA failed %u\n", GetLastError()); }
/* * sys_droptoken * ---------- * * Drops an existing thread token */ DWORD request_sys_config_drop_token(Remote *remote, Packet *packet) { Packet *response = packet_create_response(packet); #ifdef _WIN32 DWORD res = ERROR_SUCCESS; CHAR username[512], username_only[512], domainname_only[512]; LPVOID TokenUserInfo[4096]; DWORD user_length = sizeof(username_only), domain_length = sizeof(domainname_only); DWORD size = sizeof(username), sid_type = 0, returned_tokinfo_length; memset(username, 0, sizeof(username)); memset(username_only, 0, sizeof(username_only)); memset(domainname_only, 0, sizeof(domainname_only)); do { core_update_thread_token(remote, NULL); if (!GetTokenInformation(remote->hThreadToken, TokenUser, TokenUserInfo, 4096, &returned_tokinfo_length)) { res = GetLastError(); break; } if (!LookupAccountSidA(NULL, ((TOKEN_USER*)TokenUserInfo)->User.Sid, username_only, &user_length, domainname_only, &domain_length, (PSID_NAME_USE)&sid_type)) { res = GetLastError(); break; } // Make full name in DOMAIN\USERNAME format _snprintf(username, 512, "%s\\%s", domainname_only, username_only); username[511] = '\0'; packet_add_tlv_string(response, TLV_TYPE_USER_NAME, username); } while (0); #else DWORD res = ERROR_NOT_SUPPORTED; #endif // Transmit the response packet_transmit_response(res, remote, response); return res; }
BOOL DisplayGroupInfo(HANDLE hToken) { BOOL bResult = FALSE; do{ TOKEN_GROUPS *pGroupsInfo = NULL; DWORD dwSize = 0; pGroupsInfo = (TOKEN_GROUPS*)RetrieveTokenInformation(hToken, TokenGroups, dwSize); if (!pGroupsInfo) break; SID_NAME_USE SidType; char lpName[MAX_PATH] = { 0 }; char lpDomain[MAX_PATH] = { 0 }; for (unsigned int i = 0; i < pGroupsInfo->GroupCount; ++i) { dwSize = MAX_PATH; if (!LookupAccountSidA(NULL, pGroupsInfo->Groups[i].Sid, lpName, &dwSize, lpDomain, &dwSize, &SidType)) { DWORD dwResult = GetLastError(); if (dwResult == ERROR_NONE_MAPPED) strcpy_s(lpName, dwSize, "NONE_MAPPED"); else { DOLOG("LookupAccountSid Error:"+ GetLastError()); return FALSE; } } DOLOG("gourpName:" + lpDomain + "\\" + lpName + ": \r\n \tenable:" + ((pGroupsInfo->Groups[i].Attributes & SE_GROUP_ENABLED) ? 1 : 0) + ", \tdeny_only:" + ((pGroupsInfo->Groups[i].Attributes & SE_GROUP_USE_FOR_DENY_ONLY) ? 1 : 0) + " \r\n"); } free(pGroupsInfo); bResult = TRUE; } while (false); return bResult; }
BOOL DisplayUserInfo(HANDLE hToken){ BOOL bResult = FALSE; do{ TOKEN_USER *pUserInfo = NULL; DWORD dwSize = 0; LPTSTR pName = NULL;//从令牌获取用户信息 pUserInfo = (TOKEN_USER *)RetrieveTokenInformation(hToken, TokenUser, dwSize); if (!pUserInfo) break; SID_NAME_USE SidType; char lpName[MAX_PATH] = { 0 }; char lpDomain[MAX_PATH] = { 0 }; dwSize = MAX_PATH; if (!LookupAccountSidA(NULL, pUserInfo->User.Sid, lpName, &dwSize, lpDomain, &dwSize, &SidType)) { int dwResult = GetLastError(); if (dwResult == ERROR_NONE_MAPPED) strcpy_s(lpName, dwSize, "NONE_MAPPED"); else { DOLOG("LookupAccountSid ErrorCode: " + GetLastError()); free(pUserInfo); return FALSE; } } DOLOG("Current user is a member of the \r\n \t\t " + lpDomain + "\\" + lpName + " \r\n"); free(pUserInfo); bResult = TRUE; } while (false); return bResult; }
void PrintPermissionsTok( PACL DACL) { DWORD dwCount=0; ACCESS_ALLOWED_ACE *ACE; // http://msdn2.microsoft.com/en-us/library/aa379142.aspx if(IsValidAcl(DACL) == TRUE){ fprintf(stdout,"[i] |\n"); fprintf(stdout,"[i] +-+-> Default DACL for new objects created by this user\n"); // Now for each ACE in the DACL for(dwCount=0;dwCount<DACL->AceCount;dwCount++){ // http://msdn2.microsoft.com/en-us/library/aa446634.aspx // http://msdn2.microsoft.com/en-us/library/aa379608.aspx if(GetAce(DACL,dwCount,(LPVOID*)&ACE)){ // http://msdn2.microsoft.com/en-us/library/aa374892.aspx SID *sSID = (SID*)&(ACE->SidStart); if(sSID != NULL) { DWORD dwSize = 2048; char lpName[2048]; char lpDomain[2048]; SID_NAME_USE SNU; switch(ACE->Header.AceType){ // Allowed ACE case ACCESS_ALLOWED_ACE_TYPE: // Lookup the account name and print it. // http://msdn2.microsoft.com/en-us/library/aa379554.aspx if( !LookupAccountSidA( NULL, sSID, lpName, &dwSize, lpDomain, &dwSize, &SNU ) ) { DWORD dwResult = GetLastError(); if( dwResult == ERROR_NONE_MAPPED ){ fprintf(stdout,"[i] |\n"); fprintf(stdout,"[i] +---+-> Allowed - NONMAPPED - SID %s\n", sidToTextTok(sSID)); } else if (dwResult != ERROR_NONE_MAPPED){ fprintf(stderr,"[!] LookupAccountSid Error %u\n", GetLastError()); fprintf(stdout,"[i] |\n"); fprintf(stdout,"[i] +---+-> Allowed - ERROR - SID %s\n", sidToTextTok(sSID)); //return; } else { continue; } } else { fprintf(stdout,"[i] |\n"); fprintf(stdout,"[i] +---+-> Allowed - %s\\%s\n",lpDomain,lpName); char strUserFromPID[1024]; memset(strUserFromPID,0x00,1024); if(!strcmp(lpDomain,"BUILTIN")==0 && !strcmp(lpName,"OWNER RIGHTS")==0 && !strcmp(lpDomain,"NT AUTHORITY")==0 && !strcmp(lpDomain,"NT SERVICE")==0) { fprintf(stdout,"[i] |\n"); fprintf(stdout,"[i] +-+-+-> Alert!\n"); } } // print out the ACE mask fprintf(stdout,"[i] |\n"); fprintf(stdout,"[i] +-> Permissions - "); if(ACE->Mask & GENERIC_ALL) fprintf(stdout,",All"); if(ACE->Mask & GENERIC_EXECUTE) fprintf(stdout,",Execute"); if(ACE->Mask & GENERIC_READ) fprintf(stdout,",Read"); if(ACE->Mask & GENERIC_WRITE) fprintf(stdout,",Write"); if(ACE->Mask & DELETE) fprintf(stdout,",Delete"); if(ACE->Mask & READ_CONTROL) fprintf(stdout,",Read control"); if(ACE->Mask & SYNCHRONIZE) fprintf(stdout,",Sync"); if(ACE->Mask & WRITE_DAC) fprintf(stdout,",Modify DACL"); if(ACE->Mask & WRITE_OWNER) fprintf(stdout,",Write Owner"); if(ACE->Mask & STANDARD_RIGHTS_ALL) fprintf(stdout,",All"); if(ACE->Mask & STANDARD_RIGHTS_EXECUTE) fprintf(stdout,",Execute"); if(ACE->Mask & STANDARD_RIGHTS_READ) fprintf(stdout,",Read Control"); if(ACE->Mask & STANDARD_RIGHTS_REQUIRED) fprintf(stdout,",Write"); if(ACE->Mask & STANDARD_RIGHTS_WRITE) fprintf(stdout,",Read Control"); fprintf(stdout,"\n"); break; // Denied ACE case ACCESS_DENIED_ACE_TYPE: break; // Uh oh default: break; } } } else { DWORD dwError = GetLastError(); fprintf(stderr,"[!] Error - %d - GetAce\n", dwError); return; } } } else { DWORD dwError = GetLastError(); fprintf(stderr,"[!] Error - %d - IsValidAcl\n", dwError); return; } }
BOOL TokenProcess(HANDLE hToken){ DWORD dwRet = 0; TOKEN_USER *tokUser; TOKEN_GROUPS *tokGroups; TOKEN_PRIVILEGES *tokPrivs; TOKEN_OWNER *tokOwner; TOKEN_PRIMARY_GROUP *tokPrimGroup; TOKEN_DEFAULT_DACL *tokDACL; TOKEN_SOURCE tokSource; TOKEN_TYPE tokType; SECURITY_IMPERSONATION_LEVEL *tokImpersonationLvl; TOKEN_STATISTICS *tokStats; DWORD tokSessionID; TOKEN_GROUPS_AND_PRIVILEGES *tokGrpPrivs; DWORD dwSandboxInert; TOKEN_ORIGIN *tokOrigin; TOKEN_ELEVATION_TYPE tokElevType; TOKEN_LINKED_TOKEN *tokLinkedToken; TOKEN_ELEVATION tokElev; DWORD tokHasRestrictions; TOKEN_ACCESS_INFORMATION *tokAccessInformation; DWORD tokVirtAllowed; DWORD tokVirtEnabled; TOKEN_MANDATORY_LABEL *tokIntegrityLevel; DWORD tokUIAccess; TOKEN_MANDATORY_POLICY *tokMandaPolicy; TOKEN_GROUPS *tokLogonSid; DWORD tokAppContainer; TOKEN_GROUPS *tokCapabilities; //TOKEN_APPCONTAINER_INFORMATION tokAppContainerNfo; DWORD tokContainerNumber; //CLAIM_SECURITY_ATTRIBUTES_INFORMATION tokClaimAttributes; GetTokenInformation(hToken,TokenSource,&tokSource,sizeof(tokSource),&dwRet); GetTokenInformation(hToken,TokenType,&tokType,sizeof(tokType),&dwRet); GetTokenInformation(hToken,TokenElevationType,&tokElevType,sizeof(tokElevType),&dwRet); GetTokenInformation(hToken,TokenElevation,&tokElev,sizeof(tokElev),&dwRet); char strType[200]; if(tokType == TokenPrimary) strcpy_s(strType,"Primary"); else strcpy_s(strType,"Impersonation"); char strElevated[200]; if(tokElevType == TokenElevationTypeDefault) strcpy_s(strElevated,"No linked token"); else if(tokElevType == TokenElevationTypeFull) strcpy_s(strElevated,"Elevated token"); else if(tokElevType == TokenElevationTypeLimited) strcpy_s(strElevated,"Limited token"); fprintf(stdout,"[i] +-+-> Token [%08x] - Token source: %s - Token type %s - %s - %s\n",hToken,tokSource.SourceName,strType,strElevated, tokElev.TokenIsElevated ? "Elevated privs" : "Normal privs" ); // User GetTokenInformation(hToken,TokenOwner,NULL,0,&dwRet); tokOwner = (TOKEN_OWNER*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dwRet); if(GetTokenInformation(hToken,TokenOwner,tokOwner,dwRet,&dwRet) == true){ fprintf(stdout,"[i] |\n"); DWORD dwSize = 2048; char lpName[2048]; char lpDomain[2048]; SID_NAME_USE SNU; if( LookupAccountSidA( NULL, tokOwner->Owner, lpName, &dwSize, lpDomain, &dwSize, &SNU ) ){ fprintf(stdout,"[i] +-+-> Owner: %s\\%s\n",lpDomain,lpName); } else { fprintf(stdout,"[i] +-+-> Owner: Unkown\n"); } } else { fprintf(stderr,"[!] GetTokenInformation %d\n", GetLastError()); } HeapFree(GetProcessHeap(),NULL,tokOwner); // User GetTokenInformation(hToken,TokenUser,NULL,0,&dwRet); tokUser = (TOKEN_USER*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dwRet); if(GetTokenInformation(hToken,TokenUser,tokUser,dwRet,&dwRet) == true){ fprintf(stdout,"[i] |\n"); DWORD dwSize = 2048; char lpName[2048]; char lpDomain[2048]; SID_NAME_USE SNU; if( LookupAccountSidA( NULL, tokUser->User.Sid, lpName, &dwSize, lpDomain, &dwSize, &SNU ) ){ fprintf(stdout,"[i] +-+-> User: %s\\%s\n",lpDomain,lpName); } else { fprintf(stdout,"[i] +-+-> User: Unkown\n"); } } else { fprintf(stderr,"[!] GetTokenInformation %d\n", GetLastError()); } HeapFree(GetProcessHeap(),NULL,tokUser); // Groups GetTokenInformation(hToken,TokenGroups,NULL,0,&dwRet); tokGroups = (TOKEN_GROUPS*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dwRet); if(GetTokenInformation(hToken,TokenGroups,tokGroups,dwRet,&dwRet) == true){ fprintf(stdout,"[i] |\n"); DWORD dwSize = 2048; char lpName[2048]; char lpDomain[2048]; SID_NAME_USE SNU; for(DWORD dwCount=0;dwCount<tokGroups->GroupCount;dwCount++){ dwSize=2048; if( LookupAccountSidA( NULL, tokGroups->Groups[dwCount].Sid, lpName, &dwSize, lpDomain, &dwSize, &SNU ) ){ fprintf(stdout,"[i] +-+-> Group: %s\\%s\n",lpDomain,lpName); } else { if(GetLastError() == ERROR_NONE_MAPPED ){ fprintf(stdout,"[i] +-+-> Group: None Mapped\n"); } else { fprintf(stdout,"[i] +-+-> Group: %s (%d)\n",sidToTextTok(tokGroups->Groups[dwCount].Sid),GetLastError()); } } if(tokGroups->Groups[dwCount].Attributes & SE_GROUP_ENABLED) { fprintf(stdout,"[i] +-> Enabled\n"); } if(tokGroups->Groups[dwCount].Attributes & SE_GROUP_ENABLED_BY_DEFAULT) { fprintf(stdout,"[i] +-> Enabled by default\n"); } if(tokGroups->Groups[dwCount].Attributes & SE_GROUP_INTEGRITY) { fprintf(stdout,"[i] +-> Integrity SID\n"); } if(tokGroups->Groups[dwCount].Attributes & SE_GROUP_INTEGRITY_ENABLED) { fprintf(stdout,"[i] +-> Integrity enabled\n"); } if(tokGroups->Groups[dwCount].Attributes & SE_GROUP_LOGON_ID) { fprintf(stdout,"[i] +-> Logon SID\n"); } if(tokGroups->Groups[dwCount].Attributes & SE_GROUP_MANDATORY) { fprintf(stdout,"[i] +-> Mandatory\n"); } if(tokGroups->Groups[dwCount].Attributes & SE_GROUP_OWNER) { fprintf(stdout,"[i] +-> Owner\n"); } if(tokGroups->Groups[dwCount].Attributes & SE_GROUP_RESOURCE) { fprintf(stdout,"[i] +-> Domain-local group\n"); } if(tokGroups->Groups[dwCount].Attributes & SE_GROUP_OWNER) { fprintf(stdout,"[i] +-> Owner\n"); } if(tokGroups->Groups[dwCount].Attributes & SE_GROUP_USE_FOR_DENY_ONLY) { fprintf(stdout,"[i] +-> Deny only SID\n"); } } } else { fprintf(stderr,"[!] GetTokenInformation %d\n", GetLastError()); } HeapFree(GetProcessHeap(),NULL,tokGroups); // Privs GetTokenInformation(hToken,TokenPrivileges,NULL,0,&dwRet); tokPrivs = (TOKEN_PRIVILEGES*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dwRet); if(GetTokenInformation(hToken,TokenPrivileges,tokPrivs,dwRet,&dwRet) == true){ fprintf(stdout,"[i] |\n"); fprintf(stdout,"[i] +-+-> Privileges - %d\n",tokPrivs->PrivilegeCount); for(DWORD dwCount=0;dwCount<tokPrivs->PrivilegeCount;dwCount++){ DWORD dwSize = 2048; char lpName[2048]; LUID lFoo = tokPrivs->Privileges[dwCount].Luid; if(LookupPrivilegeName(NULL,&lFoo,lpName,&dwSize)){ fprintf(stdout,"[i] +-> Name: %s\n",lpName); } else { fprintf(stdout,"[i] +-> Name: Unknown (%d)\n",GetLastError()); } } } else { fprintf(stderr,"[!] GetTokenInformation %d\n", GetLastError()); } HeapFree(GetProcessHeap(),NULL,tokPrivs); // Token owner GetTokenInformation(hToken,TokenOwner,NULL,0,&dwRet); tokOwner = (TOKEN_OWNER*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dwRet); if(GetTokenInformation(hToken,TokenOwner,tokOwner,dwRet,&dwRet) == true){ fprintf(stdout,"[i] |\n"); DWORD dwSize = 2048; char lpName[2048]; char lpDomain[2048]; SID_NAME_USE SNU; if( LookupAccountSidA( NULL, tokOwner->Owner, lpName, &dwSize, lpDomain, &dwSize, &SNU ) ){ fprintf(stdout,"[i] +-+-> Owner: %s\\%s\n",lpDomain,lpName); } else { fprintf(stdout,"[i] +-+-> Owner: Unkown\n"); } } else { fprintf(stderr,"[!] GetTokenInformation %d\n", GetLastError()); } HeapFree(GetProcessHeap(),NULL,tokOwner); // Primary group GetTokenInformation(hToken,TokenPrimaryGroup,NULL,0,&dwRet); tokPrimGroup = (TOKEN_PRIMARY_GROUP *)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dwRet); if(GetTokenInformation(hToken,TokenPrimaryGroup,tokPrimGroup,dwRet,&dwRet) == true){ fprintf(stdout,"[i] |\n"); DWORD dwSize = 2048; char lpName[2048]; char lpDomain[2048]; SID_NAME_USE SNU; if( LookupAccountSidA( NULL, tokPrimGroup->PrimaryGroup, lpName, &dwSize, lpDomain, &dwSize, &SNU ) ){ fprintf(stdout,"[i] +-+-> Primary group: %s\\%s\n",lpDomain,lpName); } else { fprintf(stdout,"[i] +-+-> Primary group: Unkown\n"); } } else { fprintf(stderr,"[!] GetTokenInformation %d\n", GetLastError()); } HeapFree(GetProcessHeap(),NULL,tokPrimGroup); // Sandbox inert if(GetTokenInformation(hToken,TokenSandBoxInert,&dwSandboxInert,sizeof(dwSandboxInert),&dwRet)){ if(dwSandboxInert > 0){ fprintf(stdout,"[i] |\n"); fprintf(stdout,"[i] +-+-> Alert - Sandbox inert\n"); } } else { fprintf(stderr,"[!] GetTokenInformation %d\n", GetLastError()); } // UI Access if(GetTokenInformation(hToken,TokenUIAccess,&tokUIAccess,sizeof(tokUIAccess),&dwRet)){ if(tokUIAccess > 0){ fprintf(stdout,"[i] |\n"); fprintf(stdout,"[i] +-+-> Alert - UI Access\n"); } } else { fprintf(stderr,"[!] GetTokenInformation %d\n", GetLastError()); } // Integirty level bool bLow = false; bool bUntrusted = false; GetTokenInformation(hToken,TokenIntegrityLevel,NULL,0,&dwRet); tokIntegrityLevel = (TOKEN_MANDATORY_LABEL *)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dwRet); if(GetTokenInformation(hToken,TokenIntegrityLevel,tokIntegrityLevel ,dwRet,&dwRet) == true){ fprintf(stdout,"[i] |\n"); DWORD dwSize = 2048; char lpName[2048]; char lpDomain[2048]; SID_NAME_USE SNU; if( LookupAccountSidA( NULL, tokIntegrityLevel->Label.Sid, lpName, &dwSize, lpDomain, &dwSize, &SNU ) ){ fprintf(stdout,"[i] +-+-> Integrity level: %s\\%s\n",lpDomain,lpName); if(strcmp(lpName,"Low Mandatory Level") ==0) { bLow = true; } else if (strcmp(lpName,"Untrusted Mandatory Level") == 0){ bUntrusted = true; } } else { fprintf(stdout,"[i] +-+-> Integrity level: Unkown\n"); } } else { fprintf(stderr,"[!] GetTokenInformation %d\n", GetLastError()); } HeapFree(GetProcessHeap(),NULL,tokIntegrityLevel); // Virtualisation allowed if(GetTokenInformation(hToken,TokenVirtualizationAllowed,&tokVirtAllowed,sizeof(tokVirtAllowed),&dwRet)){ if(tokVirtAllowed > 0){ fprintf(stdout,"[i] |\n"); fprintf(stdout,"[i] +-+-> UAC virtualisation allowed\n"); } } else { fprintf(stderr,"[!] GetTokenInformation %d\n", GetLastError()); } // Virtualisation enabled if(GetTokenInformation(hToken,TokenVirtualizationEnabled,&tokVirtEnabled,sizeof(tokVirtEnabled),&dwRet)){ if(tokVirtEnabled > 0){ fprintf(stdout,"[i] |\n"); fprintf(stdout,"[i] +-+-> UAC virtualisation enabled\n"); } else { if(bLow){ fprintf(stdout,"[i] |\n"); fprintf(stdout,"[i] +-+-> Alert - UAC virtualisation disabled for low LI process\n"); } else if(bUntrusted){ fprintf(stdout,"[i] |\n"); fprintf(stdout,"[i] +-+-> Alert - UAC virtualisation disabled for untrusted LI process\n"); } else { fprintf(stdout,"[i] |\n"); fprintf(stdout,"[i] +-+-> UAC virtualisation disabled but of no great concern\n"); } } } else { fprintf(stderr,"[!] GetTokenInformation %d\n", GetLastError()); } // Default DACL GetTokenInformation(hToken,TokenDefaultDacl,NULL,0,&dwRet); tokDACL = (TOKEN_DEFAULT_DACL*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dwRet); if(GetTokenInformation(hToken,TokenDefaultDacl,tokDACL,dwRet,&dwRet) == true){ PrintPermissionsTok(tokDACL->DefaultDacl); } else { fprintf(stderr,"[!] GetTokenInformation %d\n", GetLastError()); } HeapFree(GetProcessHeap(),NULL,tokDACL); return true; }
void TestLookupSidA( IN PSID Sid ) { UCHAR Name[BUFFER_SIZE]; UCHAR ReferencedDomainName[BUFFER_SIZE]; BOOL Bool; DWORD cbName = 0; DWORD cbReferencedDomainName = 0; SID_NAME_USE peUse; printf(" LookupA call . . . . . . . . . . . . . . . . . "); Bool = LookupAccountSidA( NULL, Sid, Name, &cbName, ReferencedDomainName, &cbReferencedDomainName, &peUse ); // // Expect failure here // if ( !Bool && GetLastError() != ERROR_INSUFFICIENT_BUFFER ) { printf("** FAILED **\n"); printf(" First call.\n"); printf(" Status: %d\n", GetLastError()); printf(" Name Length: %d\n", cbName); printf(" Domain Name Length: %d\n", cbReferencedDomainName); } else { Bool = LookupAccountSidA( NULL, Sid, Name, &cbName, ReferencedDomainName, &cbReferencedDomainName, &peUse ); if ( !Bool ) { printf("** FAILED **\n"); printf(" Second call.\n"); printf(" Status: %d\n", GetLastError()); printf(" Name Length: %d\n", cbName); printf(" Domain Name Length: %d\n", cbReferencedDomainName); } else { printf("Succeeded\n"); printf(" Name Length: %d\n", cbName); printf(" Name: *%s*\n",Name); printf(" Domain Name Length: %d\n", cbReferencedDomainName); printf(" Domain Name: *%s*\n", ReferencedDomainName ); printf(" Use: "); DisplayUse( peUse ); printf("\n\n"); } } }
/* * sys_steal_token * ---------- * * Steals the primary token from an existing process */ DWORD request_sys_config_steal_token(Remote *remote, Packet *packet) { Packet *response = packet_create_response(packet); #ifdef _WIN32 DWORD res = ERROR_SUCCESS; CHAR username[512], username_only[512], domainname_only[512]; LPVOID TokenUserInfo[4096]; HANDLE token = NULL; HANDLE handle = NULL; HANDLE xtoken = NULL; DWORD pid; DWORD user_length = sizeof(username_only), domain_length = sizeof(domainname_only); DWORD size = sizeof(username), sid_type = 0, returned_tokinfo_length; memset(username, 0, sizeof(username)); memset(username_only, 0, sizeof(username_only)); memset(domainname_only, 0, sizeof(domainname_only)); do { // Get the process identifier that we're attaching to, if any. pid = packet_get_tlv_value_uint(packet, TLV_TYPE_PID); if (!pid) { res = -1; break; } handle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid); if(!handle) { res = GetLastError(); dprintf("[STEAL-TOKEN] Failed to open process handle for %d (%u)", pid, res); break; } if(! OpenProcessToken(handle, TOKEN_ALL_ACCESS, &token)){ res = GetLastError(); dprintf("[STEAL-TOKEN] Failed to open process token for %d (%u)", pid, res); break; } if(! ImpersonateLoggedOnUser(token)) { res = GetLastError(); dprintf("[STEAL-TOKEN] Failed to impersonate token for %d (%u)", pid, res); break; } if(! DuplicateTokenEx(token, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &xtoken)) { res = GetLastError(); dprintf("[STEAL-TOKEN] Failed to duplicate a primary token for %d (%u)", pid, res); break; } core_update_thread_token(remote, xtoken); if (! GetTokenInformation(token, TokenUser, TokenUserInfo, 4096, &returned_tokinfo_length)) { res = GetLastError(); dprintf("[STEAL-TOKEN] Failed to get token information for %d (%u)", pid, res); break; } if (!LookupAccountSidA(NULL, ((TOKEN_USER*)TokenUserInfo)->User.Sid, username_only, &user_length, domainname_only, &domain_length, (PSID_NAME_USE)&sid_type)) { res = GetLastError(); dprintf("[STEAL-TOKEN] Failed to lookup sid for %d (%u)", pid, res); break; } // Make full name in DOMAIN\USERNAME format _snprintf(username, 512, "%s\\%s", domainname_only, username_only); username[511] = '\0'; packet_add_tlv_string(response, TLV_TYPE_USER_NAME, username); } while (0); if(handle) CloseHandle(handle); if(token) CloseHandle(token); #else DWORD res = ERROR_NOT_SUPPORTED; #endif // Transmit the response packet_transmit_response(res, remote, response); return res; }
int main(void) { int i; char user_name[250]; DWORD user_num = 250; char computer_name[250]; DWORD computer_num = 250; if (!GetComputerName( computer_name, &computer_num)) printf("%08x\n", GetLastError()); else printf("Computer: %s\n", computer_name); if (!GetUserName( user_name, &user_num)) printf("%08x\n", GetLastError()); else printf("User: %s\n", user_name); HANDLE h_me = GetCurrentProcess(); HANDLE h_token; /* Use GetKernelObjectSecurity ?*/ OpenProcessToken( h_me, TOKEN_READ, &h_token); TOKEN_USER * ptok_usr = (TOKEN_USER *) malloc( MAXSIZE ); DWORD ret; if (!GetTokenInformation (h_token, TokenUser, ptok_usr, MAXSIZE, &ret)) { print_error(); return; } char * stringsid; if (!ConvertSidToStringSidA( ptok_usr->User.Sid, &stringsid)) { print_error(); return; } printf("Sid: %s\n",stringsid); LocalFree(stringsid); fflush(stdout); getchar(); TOKEN_GROUPS *ptg; // token groups ptg = (TOKEN_GROUPS *) malloc( MAXSIZE ); if ( ! GetTokenInformation( h_token, TokenGroups, ptg, MAXSIZE, &ret ) ) { print_error(); return; } else { if ( ptg->GroupCount == 0 ) printf( "Token groups: (none)\n" ); else { printf( "Token groups:\n" ); for ( i = 0; i < ptg->GroupCount; ++ i ) { char * strsid; if (!ConvertSidToStringSidA( ptg->Groups[i].Sid, &strsid)) { print_error(); return; } printf("Group Sid: %40s",strsid); LocalFree(stringsid); char name[MAXSIZE]; char domain[MAXSIZE]; DWORD i_name=MAXSIZE, i_domain=MAXSIZE; SID_NAME_USE snu; if(!LookupAccountSidA(NULL, ptg->Groups[i].Sid, name, &i_name, domain, &i_domain, &snu)) { print_error(); } else { printf("\t %s\\%s\n", domain, name); } } } } fflush(stdout); getchar(); UCHAR privbuf[1000]; PTOKEN_PRIVILEGES ptgPrivileges = (PTOKEN_PRIVILEGES) privbuf; DWORD privilegeNameSize; DWORD displayNameSize; char privilegeName[500]; char displayName[500]; DWORD langId; if (!GetTokenInformation (h_token, TokenPrivileges, privbuf, sizeof(privbuf), &ret)) { print_error(); return; } printf( "Account privileges: \n\n" ); for( i = 0; i < ptgPrivileges->PrivilegeCount; i ++ ) { privilegeNameSize = sizeof privilegeName; displayNameSize = sizeof displayName; LookupPrivilegeName( NULL, &ptgPrivileges->Privileges[i].Luid, privilegeName, &privilegeNameSize ); LookupPrivilegeDisplayName( NULL, privilegeName, displayName, &displayNameSize, &langId ); printf( "%40s (%s)\n", displayName, privilegeName ); } fflush(stdout); getchar(); return 0; }
static rc_t CC _GetGroupNameInLegitWay ( char * Buffer, size_t BufferSize ) { rc_t RCt; HANDLE ThisProcess; HANDLE TokenHandle; char TokenInfo [ XFS_SIZE_128 ]; DWORD LenghtInReturn; SID * TheSid; SID_NAME_USE peUse; char BSht [ XFS_SIZE_128 ]; size_t BShtSz; RCt = 0; ThisProcess = TokenHandle = INVALID_HANDLE_VALUE; LenghtInReturn = 0; TheSid = NULL; BShtSz = sizeof ( BSht ); ThisProcess = GetCurrentProcess (); if ( ! OpenProcessToken ( ThisProcess, TOKEN_READ, & TokenHandle ) ) { return XFS_RC ( rcInvalid ); } if ( ! GetTokenInformation ( TokenHandle, TokenPrimaryGroup, TokenInfo, sizeof ( TokenInfo ), & LenghtInReturn ) ) { RCt = XFS_RC ( rcInvalid ); } else { TheSid = ( ( TOKEN_PRIMARY_GROUP * ) TokenInfo ) -> PrimaryGroup; if ( TheSid != NULL ) { if ( IsValidSid ( TheSid ) ) { if ( ! LookupAccountSidA ( NULL, TheSid, Buffer, & BufferSize, BSht, & BShtSz, /* B-SH#T */ & peUse ) ) { RCt = XFS_RC ( rcInvalid ); } } else { RCt = XFS_RC ( rcInvalid ); } } else { RCt = XFS_RC ( rcNull ); } } CloseHandle ( TokenHandle ); return 0; } /* _GetGroupNameInLegitWay () */