1

I have a user token duplicated from a restricted UAC launched process and I want to remove the deny group SIDs from it. How do I do that? If I call SetTokenInformation with the TOKEN_GROUPS information class type I get an invalid parameter error.

Thank you.

Chris
  • 100
  • 8

1 Answers1

4

It turns out that there is a supported way of doing this. Basically you need to do a double indirect to make this work. First you want to get the session for the user's token with WTSQueryUserToken. Next you need to get the associated administrative user token with GetTokenInformation (looking for TokenLinkedToken information). Now that you have the admintokn, you can call CreateProcessAsUser with that token. If you need the environment block, you can call CreateEnvironmentBlock to get the correct environment variables.

Here's a chunk of VB code I got from a co-worker (who passed on this tip):

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

He also wrote up a blog post with more information: http://blogs.msdn.com/b/itasupport/archive/2010/03/29/uac-bypass-o-meglio-il-modo-supportato-e-by-design-di-aggirare-la-uac.aspx

Larry Osterman
  • 16,086
  • 32
  • 60
  • Thank you Larry, this is exactly what I was looking for. I have solved the original problem by modifying the access rights to the objects I was interested in, but this will come very handy in the future. Excellent answer! – Chris Apr 20 '11 at 18:04
  • One other suggestion that might be easier and cleaner: Create a scheduled task to run as the user and launch it. – Larry Osterman Apr 20 '11 at 22:23
  • @LarryOsterman Do you think you could post your code as VB6? I am trying since around 12 hours to make it work, but the error I'm getting is 123 which results in Path Not Found. So strange. The path does exist, and I have even tried putting " " in front of AppName because in another thread I saw that I might be required. – Maiken Roskilde May 25 '16 at 19:00
  • I mean your code at http://blogs.msdn.com/b/itasupport/archive/2010/03/29/uac-bypass-o-meglio-il-modo-supportato-e-by-design-di-aggirare-la-uac.aspx. I would like to make my service install an update without triggering the UAC, but so far, something has always gone wrong. May I ask you which one of your functions you would suggest for this situation? Is StartAppInSessionAsSystem correct? – Maiken Roskilde May 25 '16 at 19:21