【问题标题】:How to copy privileges from one primary user token to another?如何将权限从一个主要用户令牌复制到另一个?
【发布时间】:2015-10-30 10:19:17
【问题描述】:

我的目标是在使用目标令牌启动用户模式进程之前,将privileges 从一个主用户令牌复制到另一个。我创建了一个示例伪代码来说明我需要完成的工作。

以下将从本地系统服务运行:

//dwSessionId = user session ID to run process in

HANDLE hToken1 = NULL;      //Source user token
WTSQueryUserToken(dwSessionId, &hToken1);

HANDLE hSelfToken = NULL;   //User token for system service
HANDLE hToken2 = NULL;      //Adjusted self-token

OpenProcessToken(::GetCurrentProcess(), TOKEN_ALL_ACCESS, &hSelfToken);
DuplicateTokenEx(hSelfToken, TOKEN_ASSIGN_PRIMARY | TOKEN_ALL_ACCESS, 
    NULL, SecurityIdentification, TokenPrimary, &hToken2);

//Specify user session to run in
SetTokenInformation(hToken2, TokenSessionId, &dwSessionId, sizeof(dwSessionId));

//Now I need to set privileges in 'hToken2' as they are in 'hToken1'
...

//Then use 'hToken2' in CreateProcessAsUser() to start a process

知道如何将权限从hToken1 复制到hToken2

【问题讨论】:

  • 为什么不能直接使用hToken1 创建进程?
  • @JonathanPotter:我试过了,但后来CreateProcessAsUser 成功了,但用户进程永远不会启动,我将其退出代码设置为STATUS_DLL_INIT_FAILED0xC0000142
  • 当然可以将CreateProcessAsUserhToken1 一起使用,而且会更安全 - 除非您尝试在安全桌面上启动该进程?
  • @HarryJohnston:安全桌面会发生什么?你的意思是Winlogon 对吧?
  • IIRC 安全桌面名为 Winlogon,是的,我认为在用户上下文中运行的进程无法使用它(因此是“安全的”)。我不熟悉细节。但这是我能想到的唯一原因,为什么使用 hToken1 可能是不可能的。如果这不是你在做的,那么你真的应该使用hToken1 - 如果你发布一个 MCVE(作为一个单独的问题),我希望我们能找出你做错了什么。

标签: c++ c windows winapi kernel32


【解决方案1】:

好的。我可能已经得到了接近我需要的东西。这并不是真正的复制权限,但为了“剥离”权限,我可以创建一个受限令牌,该令牌将删除几乎所有权限(SeChangeNotifyPrivilegeSeSystemtimePrivilege 除外。)

//Call the following instead of DuplicateTokenEx() in my example above
CreateRestrictedToken(hSelfToken, DISABLE_MAX_PRIVILEGE,
            0, NULL, 0, NULL, 0, NULL,
            &hToken2);

仅供参考:只是一个奇怪的事实。由于某种原因,我无法从令牌中删除 SeSystemtimePrivilege。不使用此方法,也不使用属性设置为SE_PRIVILEGE_REMOVEDAdjustTokenPrivileges。除了这个之外,所有其他权限都可以删除。所以如果有人知道为什么,我很乐意学习它?

【讨论】:

    【解决方案2】:

    使用以下代码从hToken获取hToken2,然后在CreateProcessAsUser中使用。其实不用hSelfToken

    HANDLE GetAdjustedToken(HANDLE hSrcToken)
    {
        TOKEN_LINKED_TOKEN admin = {};
        HANDLE hTarToken = 0;
        DWORD dw = 0;
        if (GetTokenInformation(hSrcToken, (TOKEN_INFORMATION_CLASS)TokenLinkedToken, &admin, sizeof(TOKEN_LINKED_TOKEN), &dw))
        {
            hTarToken = admin.LinkedToken;
        }
        else
        {
            DuplicateTokenEx(hSrcToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &hTarToken);
        }
        return hTarToken;
    }
    

    如果您想以较低的强制性完整性级别创建新流程,请参阅this MSDN 文章。

    【讨论】:

    • 谢谢。你能解释一下它的作用吗?尤其是TokenLinkedToken的电话?
    • 哦,我明白了。 TokenLinkedToken 检索管理令牌。好吧,我在这里练习的重点是实际上减少特权而不是升级它们。如果我像上面显示的那样运行它,我的用户进程会以一组 SYSTEM 权限运行,这是我不想要的。
    • 很抱歉弄错了您的用例。所以你想要这个? msdn.microsoft.com/en-us/library/bb625960.aspx
    • 不,这与mandatory integrity level 无关。我在问token privileges。这是两个不同的东西。
    【解决方案3】:

    首先,您必须使用TokenPrivileges 类为您的原始令牌调用GetTokenInformation 以获得TOKEN_PRIVILEGES 结构。然后用它调用AdjustTokenPrivileges 来更新你的克隆令牌。您必须调用 GetTokenInformation 两次 - 第一次获取缓冲区长度,第二次获取实际数据。

    HANDLE hSelfToken = NULL;   //User token for system service
    HANDLE hToken2 = NULL;      //Adjusted self-token
    
    OpenProcessToken(::GetCurrentProcess(), TOKEN_ALL_ACCESS, &hSelfToken);
    DuplicateTokenEx(hSelfToken, TOKEN_ASSIGN_PRIMARY | TOKEN_ALL_ACCESS,
        NULL, SecurityIdentification, TokenPrimary, &hToken2);
    
    PTOKEN_PRIVILEGES pPriv = NULL;
    DWORD dwLen = 0;
    GetTokenInformation(hSelfToken, TokenPrivileges, (LPVOID)pPriv, 0, &dwLen);
    if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
        return(0);
    
    pPriv = (PTOKEN_PRIVILEGES)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwLen);
    if (!GetTokenInformation(hSelfToken, TokenPrivileges, (LPVOID)pPriv, dwLen, &dwLen))
        return(0);
    
    AdjustTokenPrivileges(hToken2, FALSE, pPriv, dwLen, NULL, NULL);
    

    【讨论】:

    • 感谢您指出 GetTokenInformationAdjustTokenPrivileges API。但是您的代码示例完全错误。你不能只打电话给AdjustTokenPrivileges
    • 为什么? MSDN 清楚地告诉您,您可以通过一个AdjustTokenPrivileges 调用来调整多个令牌权限。我的测试示例也没有报告任何错误。
    • @HarryJohnston:不,它实际上也可以删除它们。特权属性中的SE_PRIVILEGE_REMOVED 标志不会这样做吗?
    • @Ari0nhh:目标是减少目标令牌(或hToken2)中的权限,因此您的示例将从hSelfToken 获取全套系统权限并将其应用于目标令牌@987654334 @.
    • 在您的问题中,您写的目标是 - 将原始令牌权限复制到新令牌。没有任何关于减少的问题文本。
    猜你喜欢
    • 1970-01-01
    • 2012-06-13
    • 1970-01-01
    • 2017-02-16
    • 2011-05-18
    • 2011-05-03
    • 1970-01-01
    • 1970-01-01
    • 2010-12-21
    相关资源
    最近更新 更多