Windows 如何将受限用户令牌转换为非受限用户令牌?

Windows 如何将受限用户令牌转换为非受限用户令牌?,windows,security,token,Windows,Security,Token,我有一个从受限UAC启动的进程复制的用户令牌,我想从中删除拒绝组SID。我该怎么做? 如果使用TOKEN_GROUPS information类类型调用SetTokenInformation,则会得到一个无效的参数错误 谢谢。事实证明,有一种受支持的方法可以做到这一点。基本上,你需要做一个双重的间接,使这项工作。首先,您希望使用获取用户令牌的会话。接下来,您需要获取与关联的管理用户令牌(查找令牌LinkedToken信息)。现在您有了admintokn,可以使用该令牌调用CreateProces

我有一个从受限UAC启动的进程复制的用户令牌,我想从中删除拒绝组SID。我该怎么做? 如果使用TOKEN_GROUPS information类类型调用SetTokenInformation,则会得到一个无效的参数错误


谢谢。

事实证明,有一种受支持的方法可以做到这一点。基本上,你需要做一个双重的间接,使这项工作。首先,您希望使用获取用户令牌的会话。接下来,您需要获取与关联的管理用户令牌(查找令牌LinkedToken信息)。现在您有了admintokn,可以使用该令牌调用CreateProcessAsUser。如果需要环境块,可以调用以获取正确的环境变量

下面是我从一位同事那里得到的一段VB代码(他介绍了这个技巧):

公共函数StartAppInSessionAsAdmin(ByVal SessionID作为字符串,ByVal WinstationName作为字符串,ByVal AppName作为字符串)作为整数
作为IntPtr的Dim hToken
将hLinkedToken设置为IntPtr
作为布尔函数的Dim-bRet
Dim pi作为新的过程信息
Dim si作为新的STARTUPINFO
作为整数的Dim err
作为整数的Dim-iret
作为IntPtr的Dim lpEB
Dim TLT作为新令牌\u链接\u令牌
Dim TLT设置为整数
将大小设置为整数
si.lpDesktop=WinstationName“Winsta0\default”
si.cb=Marshal.SizeOf(si)
TLTSize=Marshal.SizeOf(TLT.LinkedToken)
'获取会话ID令牌
bRet=WTSQueryUserToken(Integer.Parse(SessionID),hToken)
'我们需要获取令牌链接令牌
bRet=GetTokenInformation(hToken,TOKEN\u INFORMATION\u CLASS.TokenLinkedToken,hLinkedToken,TLTSize,retSize)
'将CreateEnvironment块与原始令牌一起使用,为具有用户环境的新程序创建环境
bRet=CreateEnvironmentBlock(lpEB、hToken、False)
如果布雷特那么
'调用CreateProcessAsUser以使用用户修改的令牌创建进程
iret=CreateProcessAsUser(hLinkedToken,Nothing,AppName,0,0,False,1072,lpEB,Nothing,si,pi)
'给用户一个反馈
如果iret为0,则
给予反馈(会话ID,“来自StartAppInSessionAsAdmin的消息”,“CreateProcessAsUser成功”,2)
其他的
err=Marshal.GetLastWin32Error
GiveFeedback(会话ID,“来自StartAppInSessionAsAdmin的消息”,“CreateProcessAsUser因错误而失败”&err.ToString,5)
如果结束
如果结束
端函数

他还写了一篇博文,提供了更多信息:

事实证明,有一种受支持的方法可以做到这一点。基本上,你需要做一个双重的间接,使这项工作。首先,您希望使用获取用户令牌的会话。接下来,您需要获取与关联的管理用户令牌(查找令牌LinkedToken信息)。现在您有了admintokn,可以使用该令牌调用CreateProcessAsUser。如果需要环境块,可以调用以获取正确的环境变量

下面是我从一位同事那里得到的一段VB代码(他介绍了这个技巧):

公共函数StartAppInSessionAsAdmin(ByVal SessionID作为字符串,ByVal WinstationName作为字符串,ByVal AppName作为字符串)作为整数
作为IntPtr的Dim hToken
将hLinkedToken设置为IntPtr
作为布尔函数的Dim-bRet
Dim pi作为新的过程信息
Dim si作为新的STARTUPINFO
作为整数的Dim err
作为整数的Dim-iret
作为IntPtr的Dim lpEB
Dim TLT作为新令牌\u链接\u令牌
Dim TLT设置为整数
将大小设置为整数
si.lpDesktop=WinstationName“Winsta0\default”
si.cb=Marshal.SizeOf(si)
TLTSize=Marshal.SizeOf(TLT.LinkedToken)
'获取会话ID令牌
bRet=WTSQueryUserToken(Integer.Parse(SessionID),hToken)
'我们需要获取令牌链接令牌
bRet=GetTokenInformation(hToken,TOKEN\u INFORMATION\u CLASS.TokenLinkedToken,hLinkedToken,TLTSize,retSize)
'将CreateEnvironment块与原始令牌一起使用,为具有用户环境的新程序创建环境
bRet=CreateEnvironmentBlock(lpEB、hToken、False)
如果布雷特那么
'调用CreateProcessAsUser以使用用户修改的令牌创建进程
iret=CreateProcessAsUser(hLinkedToken,Nothing,AppName,0,0,False,1072,lpEB,Nothing,si,pi)
'给用户一个反馈
如果iret为0,则
给予反馈(会话ID,“来自StartAppInSessionAsAdmin的消息”,“CreateProcessAsUser成功”,2)
其他的
err=Marshal.GetLastWin32Error
GiveFeedback(会话ID,“来自StartAppInSessionAsAdmin的消息”,“CreateProcessAsUser因错误而失败”&err.ToString,5)
如果结束
如果结束
端函数

他还写了一篇博文,提供了更多信息:

谢谢你,拉里,这正是我想要的。我已经通过修改我感兴趣的对象的访问权限解决了最初的问题,但这在将来会非常方便。回答得很好!还有一个更简单、更简洁的建议:创建一个以用户身份运行的计划任务并启动它。@LarryOsterman您认为可以将代码作为VB6发布吗?我从大约12个小时开始尝试让它工作,但我得到的错误是123,这导致找不到路径。真奇怪。路径确实存在,我甚至尝试将“”放在AppName前面,因为在另一个线程中,我看到可能需要我。我指的是您的代码。我想让我的服务在不触发UAC的情况下安装一个更新,但到目前为止,总是出现一些问题。我想问一下,在这种情况下,你会建议你的哪项职能?StartAppissionSystem正确吗?谢谢拉里,这正是我想要的。我已经通过修改我感兴趣的对象的访问权限解决了最初的问题,但这在将来会非常方便。回答得很好!另一个建议
Public Function StartAppInSessionAsAdmin(ByVal SessionID As String, ByVal WinstationName As String, ByVal AppName As String) As Integer

    Dim hToken As IntPtr
    Dim hLinkedToken As IntPtr
    Dim bRet As Boolean
    Dim pi As New PROCESS_INFORMATION
    Dim si As New STARTUPINFO
    Dim err As Integer
    Dim iret As Integer
    Dim lpEB As IntPtr


    Dim TLT As New TOKEN_LINKED_TOKEN
    Dim TLTSize As Integer
    Dim retSize As Integer

    si.lpDesktop = WinstationName  '”Winsta0\default”
    si.cb = Marshal.SizeOf(si)

    TLTSize = Marshal.SizeOf(TLT.LinkedToken)

    'get SessionID token
    bRet = WTSQueryUserToken(Integer.Parse(SessionID), hToken)

    'we need to get the TokenLinked Token 
    bRet = GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenLinkedToken, hLinkedToken, TLTSize, retSize)

    'Use CreateEnvironment Block with the original token to create an environment for the new program with the USER Environment
    bRet = CreateEnvironmentBlock(lpEB, hToken, False)

    If bRet Then
        'Call CreateProcessAsUser to create the process using the user's modified Token
        iret = CreateProcessAsUser(hLinkedToken, Nothing, AppName, 0, 0, False, 1072, lpEB, Nothing, si, pi)
        'Give user a feedback
        If iret <> 0 Then
            GiveFeedback(SessionID, "Message from StartAppInSessionAsAdmin", "CreateProcessAsUser succeeded", 2)
        Else
            err = Marshal.GetLastWin32Error
            GiveFeedback(SessionID, "Message from StartAppInSessionAsAdmin", "CreateProcessAsUser failed with error " & err.ToString, 5)
        End If
    End If

End Function