gpt4 book ai didi

winapi - 从进程中删除管理员权限

转载 作者:行者123 更新时间:2023-12-02 04:50:26 24 4
gpt4 key购买 nike

在这位伟大的帮助下MSDN article ,我的第一个想法是简单地检查进程是否使用提升的管理员组,并使用 AdjustTokenGroups() 将管理员组设置为 SE_GROUP_USE_FOR_DENY_ONLY。但不幸的是,我们无法修改当前正在运行的进程的管理员组,因为它还具有 SE_GROUP_MANDATORY 属性,这使得它无法更改。

MSDN 文档对此有这样的说法:

AdjustTokenGroups 函数无法禁用 TOKEN_GROUPS 结构中具有 SE_GROUP_MANDATORY 属性的组。请改用 CreateRestrictedToken

因此,我完成了以下代码来实现此目的;

bool _IsNewProcessLaunched()
{
HANDLE hToken = NULL;
bool hasRestarted = false;

if (!OpenProcessToken( GetCurrentProcess(),
TOKEN_ASSIGN_PRIMARY | TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ADJUST_GROUPS,
&hToken ))
{
return hasRestarted;
}

PSECURITY_DESCRIPTOR pSID = NULL;
SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY;

if(! AllocateAndInitializeSid( &SIDAuth, 2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0,
&pSID) )
{
CloseHandle(hToken);
hToken = NULL;
return hasRestarted;
}

BOOL isAdmin = FALSE;
BOOL ok = CheckTokenMembership(NULL, pSID, &isAdmin);

// Create the SID structure for the administrator SID
SID_AND_ATTRIBUTES adminSID = {0};
adminSID.Sid = pSID;

// Create a restricted token which denies the administrator group
HANDLE restrictedToken;

CreateRestrictedToken(hToken,RESTR,DISABLE_MAX_PRIVILEGE,&adminSID,NULL,NULL,NULL,NULL,&restrictedToken);

//Create startup info
STARTUPINFO si = {0};
PROCESS_INFORMATION pi = {0};
si.lpDesktop = L"winsta0\\default";
si.cb = sizeof( si );

// Get the current executables name
TCHAR exePath[MAX_PATH];
GetModuleFileName(NULL,exePath,MAX_PATH);

// Start the new (non-administrator elevated) restricted process
if( CreateProcessAsUser(restrictedToken,exePath,NULL,NULL,NULL,TRUE,NORMAL_PRIORITY_CLASS,NULL,NULL,&si,&pi) == 0)
hasRestarted = false;
else
hasRestarted = true;

return hasRestarted;
}

但是新进程仍然以管理员身份运行,而不是作为普通用户运行。

我该如何实现这一目标?

最佳答案

由于您限制了调用进程的 token ,因此启动的进程将使用与调用进程相同的用户帐户运行,只是权限受到限制。请记住,在 UAC 下,管理员在没有提升的情况下没有完整的管理权限。 CreateRestrictedToken() 创建具有受限权限的 token 。因此,即使用户可能是管理员,并不意味着启动的进程将以管理权限运行。

顺便说一句,有一个更简单的 API,称为 Safer API ,您可以使用它来代替 CreateRestrictedToken():

#include <WinSafer.h>

bool _IsNewProcessLaunched()
{
// Create the restricted token.

SAFER_LEVEL_HANDLE hLevel = NULL;
if (!SaferCreateLevel(SAFER_SCOPEID_USER, SAFER_LEVELID_NORMALUSER, SAFER_LEVEL_OPEN, &hLevel, NULL))
{
return false;
}

HANDLE hRestrictedToken = NULL;
if (!SaferComputeTokenFromLevel(hLevel, NULL, &hRestrictedToken, 0, NULL))
{
SaferCloseLevel(hLevel);
return false;
}

SaferCloseLevel(hLevel);

// Set the token to medium integrity.

TOKEN_MANDATORY_LABEL tml = {0};
tml.Label.Attributes = SE_GROUP_INTEGRITY;
// alternatively, use CreateWellKnownSid(WinMediumLabelSid) instead...
if (!ConvertStringSidToSid(TEXT("S-1-16-8192"), &(tml.Label.Sid)))
{
CloseHandle(hRestrictedToken);
return false;
}

if (!SetTokenInformation(hRestrictedToken, TokenIntegrityLevel, &tml, sizeof(tml) + GetLengthSid(tml.Label.Sid))))
{
LocalFree(tml.Label.Sid);
CloseHandle(hRestrictedToken);
return false;
}

LocalFree(tml.Label.Sid);

// Create startup info

STARTUPINFO si = {0};
si.cb = sizeof( si );
si.lpDesktop = L"winsta0\\default";

PROCESS_INFORMATION pi = {0};

// Get the current executable's name
TCHAR exePath[MAX_PATH+1] = {0};
GetModuleFileName(NULL, exePath, MAX_PATH);

// Start the new (non-elevated) restricted process
if (!CreateProcessAsUser(hRestrictedToken, exePath, NULL, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi))
{
CloseHandle(hRestrictedToken);
return false;
}

CloseHandle(hRestrictedToken);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);

return true;
}

关于winapi - 从进程中删除管理员权限,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16099787/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com