Loading... ## Windows权限管理 * #### 相关名词 * SID:安全描述符,用于标识用户身份 * LUID: 局部唯一标识符,系统每次启动都可能变化 * GUID: 全局唯一标识符,一直都保持不变 * UAC(*User Account Control*): 用户账户控制,vista开始启用 * 相关函数 * 获取进程令牌: OpenProcessToken * 获取线程令牌: OpenThreadToken * 获取令牌信息: GetTokenInformation * 查询特权名称的LUID: LookupPrivilegeValue * 修改令牌权限: AdjustTokenPrivileges * **创建管理员进程: ShellExecute 传入 runas** * 内核函数:RtlAdjustPrivilege ```cpp HANDLE hToken = NULL; //首先定义一个hToken的句柄 HANDLE hProcess = GetCurrentProcess(); //该函数获取该进程的伪句柄 //权限可以填入 TOKEN_ALL_ACCESS 全部权限打开 如果失败返回FALSE OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);//打开自己进程的锁,hToken 返回的是信息的结构体 //记录的信息的结构体 TOKEN_PRIVILEGES tp = { 0 }; //查看进程里面的特权信息 返回值FALSE 失败 直接在tp里放入uid 方便设置权限 LookupPrivilegeValue(0, SE_SHUTDOWN_NAME, &tp.Privileges[0].Luid); tp.PrivilegeCount = 1; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;//设置新的权限 //调用函数提升权限 调节进程的权限 AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL); ``` ## Windows C++ 提权/降权/鉴定当前权限 ```cpp #include <Shlobj.h> #include <iostream> #include <Windows.h> void EnableDebugPriv() { HANDLE hToken = NULL; HANDLE hProcess = GetCurrentProcess();//该函数获取该进程的伪句柄 //权限可以填入 TOKEN_ALL_ACCESS 全部权限打开 OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);//打开自己进程的锁,hToken 返回的是信息的结构体 //记录的信息的结构体 TOKEN_PRIVILEGES tp = { 0 }; //查看进程里面的特权信息 返回值FALSE 失败 LookupPrivilegeValue(0, SE_SHUTDOWN_NAME, &tp.Privileges[0].Luid); tp.PrivilegeCount = 1; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; //调用函数提升权限 调节进程的权限 AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL); } BOOL ElevatePrivileges() { // 2. 获取当前程序路径 WCHAR szApplication[MAX_PATH] = { 0 }; DWORD cchLength = _countof(szApplication); QueryFullProcessImageName(GetCurrentProcess(), 0, szApplication, &cchLength); // 3. 以管理员权限重新打开进程 SHELLEXECUTEINFO sei = { sizeof(SHELLEXECUTEINFO) }; sei.lpVerb = L"runas"; // 请求提升权限 sei.lpFile = szApplication; // 可执行文件路径 sei.lpParameters = NULL; // 不需要参数 sei.nShow = SW_SHOWNORMAL; // 正常显示窗口 if (ShellExecuteEx(&sei)) exit(0); return FALSE; } BOOL IsSystemPrivileget() { // 1. 获得本进程的令牌 HANDLE hToken = NULL; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) return false; // 2. 获取提升类型 TOKEN_ELEVATION_TYPE ElevationType = TokenElevationTypeDefault; BOOL bIsAdmin = false; DWORD dwSize = 0; if (GetTokenInformation(hToken, TokenElevationType, &ElevationType, sizeof(TOKEN_ELEVATION_TYPE), &dwSize)) { // 2.1 创建管理员组的对应SID BYTE adminSID[SECURITY_MAX_SID_SIZE]; dwSize = sizeof(adminSID); CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, &adminSID, &dwSize); // 2.2 判断当前进程运行用户角色是否为管理员 if (ElevationType == TokenElevationTypeLimited) { // a. 获取连接令牌的句柄 HANDLE hUnfilteredToken = NULL; GetTokenInformation(hToken, TokenLinkedToken, (PVOID)&hUnfilteredToken, sizeof(HANDLE), &dwSize); // b. 检查这个原始的令牌是否包含管理员的SID if (!CheckTokenMembership(hUnfilteredToken, &adminSID, &bIsAdmin)) return false; CloseHandle(hUnfilteredToken); } else { bIsAdmin = IsUserAnAdmin(); } CloseHandle(hToken); } BOOL bFullToken = false; switch (ElevationType) { case TokenElevationTypeDefault: /* 默认的用户或UAC被禁用 */ if (IsUserAnAdmin()) bFullToken = true; // 默认用户有管理员权限 else bFullToken = false;// 默认用户不是管理员组 break; case TokenElevationTypeFull: /* 已经成功提高进程权限 */ if (IsUserAnAdmin()) bFullToken = true; //当前以管理员权限运行 else bFullToken = false;//当前未以管理员权限运行 break; case TokenElevationTypeLimited: /* 进程在以有限的权限运行 */ if (bIsAdmin) bFullToken = false;//用户有管理员权限,但进程权限有限 else bFullToken = false;//用户不是管理员组,且进程权限有限 } return bFullToken; } BOOL EnableDebugPrivilege(BOOL fEnable) { //提升为调试权限 BOOL fOk = FALSE; HANDLE hToken; // 以修改权限的方式,打开进程的令牌 if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { // 令牌权限结构体 TOKEN_PRIVILEGES tp; tp.PrivilegeCount = 1; //获得LUID LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid); tp.Privileges[0].Attributes = fEnable ? SE_PRIVILEGE_ENABLED : 0; AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL); //修改权限 fOk = (GetLastError() == ERROR_SUCCESS); CloseHandle(hToken); } return(fOk); } int main() { if (IsSystemPrivileget()) { printf("现在已经是管理员权限:降权\n"); getchar(); EnableDebugPrivilege(FALSE); getchar(); if (IsSystemPrivileget()) { printf("用户权限\n"); } getchar(); } else { printf("现在已经是用户权限:提权\n"); getchar(); //提升管理员 ElevatePrivileges(); } } ``` 最后修改:2021 年 04 月 20 日 © 允许规范转载 赞 0 如果觉得我的文章对你有用,请随意赞赏
1 条评论
想想你的文章写的特别好