0

LocalSystem Windows 서비스의CreateProcessAsUser가 사용자를 올바르게 설정하지 않습니다.

[DllImport(
    "advapi32.dll", 
    EntryPoint = "CreateProcessAsUser", 
    SetLastError = true, 
    CharSet = CharSet.Ansi, 
    CallingConvention = CallingConvention.StdCall)] 
private static extern bool CreateProcessAsUser(
    IntPtr hToken, 
    string lpApplicationName, 
    string lpCommandLine, 
    ref SECURITY_ATTRIBUTES lpProcessAttributes, 
    ref SECURITY_ATTRIBUTES lpThreadAttributes, 
    bool bInheritHandle, 
    int dwCreationFlags, 
    IntPtr lpEnvironment, 
    string lpCurrentDirectory, 
    ref STARTUPINFO lpStartupInfo, 
    out PROCESS_INFORMATION lpProcessInformation); 


bool result = CreateProcessAsUser(
    hUserTokenDup, 
    null, 
    applicationName + " " + arguments, 
    ref sa,     // pointer to process SECURITY_ATTRIBUTES 
    ref sa,     // pointer to thread SECURITY_ATTRIBUTES 
    false,     // handles are not inheritable 
    NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE,  // creation flags 
    IntPtr.Zero,   // pointer to new environment block 
    null,     // name of current directory 
    ref si,     // pointer to STARTUPINFO structure 
    out procInfo);   // receives information about new process 

를 사용하여 GUI 응용 프로그램 호출. 사용자 화면에서 창이 나타나지만 프로세스 사용자는 여전히 LocalSystem입니다. 그것을 바꿀 방법이 있습니까?

PS 요청에 따라

hUserTokenDup
[DllImport("advapi32.dll", EntryPoint = "DuplicateTokenEx")] 
private static extern bool DuplicateTokenEx(
    IntPtr ExistingTokenHandle, 
    uint dwDesiredAccess, 
    ref SECURITY_ATTRIBUTES lpThreadAttributes, 
    int TokenType, 
    int ImpersonationLevel, 
    ref IntPtr DuplicateTokenHandle); 

DuplicateTokenEx(
    hPToken, 
    MAXIMUM_ALLOWED, 
    ref sa, 
    (int)SECURITY_IMPERSONATION_LEVEL.SecurityIdentification, 
    (int)TOKEN_TYPE.TokenPrimary, 
    ref hUserTokenDup); 
+0

hUserTokenDup을 어디에서 얻을 수 있습니까? 나는 그것이 그 문제의 핵심이라고 믿는다. –

+0

@Josh 요청한 정보를 추가했습니다 –

+0

'hPToken '은 어디에서 왔습니까? –

답변

2

, 나는 CreateProcessAsUser()를 호출하기 전에 WTSGetActiveConsoleSessionId(), WTSQueryUserToken()DuplicationTokenEx()을 사용하고 나를 위해 잘 작동합니다. 스폰 된 프로세스는 서비스 계정이 아닌 사용자 계정에서 실행됩니다. WTSGetActiveConsoleSessionId()를

기능 아래 윈 - 서비스 같은 "시스템"-user에서 호출해야하고 실행중인 물리적 콘솔이 필요합니다 (일반 사용자 사용하는 힌트 레미 Lebeau에

+0

메소드 내가 사용하지 않는 것은'WTSQueryUserToken'뿐입니다. 나는 그것을 들여다 볼 것이다. –

+0

대신에'OpenProcess'와'OpenProcessToken'을 사용합니다 –

+1

그 코드를 보여줄 수 있습니까? 또한, 내가 사용하지 않는 다른 것들은'CreateEnvironmentBlock()'이며'CreateProcessAsUser()'의'CREATE_UNICODE_ENVIRONMENT' 플래그와 함께 사용됩니다 (또한'DETACHED_PROCESS' 플래그를 사용합니다). –

2

에서 hUserTokenDup를 얻을 요청했다. 간단히 DuplicateTokenEx를 호출하면 Local System 사용자의 토큰이 생성됩니다. 코드 스 니펫을 올바르게 이해하면됩니다.

또한 대화식 사용자를 대상으로하기 때문에 CreateProcessWithLogonW 함수를 대신 사용하십시오. 내 서비스에서

+0

LogonUser 및 CreateProcessWithLogonW에 필요한 사용자 자격 증명이 없습니다 –

0

감사합니다 -logon-session, 원격 터미널 세션 없음). 이 사용자 보안 속성을 사용하여 실행중인 로그온 세션에서 win-service로부터 새로운 프로세스를 시작할 수 있습니다. 호출자가 "시스템"이 아닌 경우 가장 할 수있는 사용자로 새 프로세스를 시작할 수 없습니다.

public static bool StartProcessAndBypassUAC(ProcessStartInfo ps, out PROCESS_INFORMATION procInfo) 
{ 
// code based on http://www.codeproject.com/Articles/35773/Subverting-Vista-UAC-in-Both-32-and-64-bit-Archite 
    uint winlogonPid = 0; 
    IntPtr hUserTokenDup = IntPtr.Zero, hPToken = IntPtr.Zero, hProcess = IntPtr.Zero; 
    procInfo = new PROCESS_INFORMATION(); 

    // obtain the currently active session id; every logged on user in the system has a unique session id 
    uint dwSessionId = WTSGetActiveConsoleSessionId(); 

    if (dwSessionId == 0xFFFFFFFF) 
    { 
     // no physical console 
     return false; 
    } 

    if (!WTSQueryUserToken(dwSessionId, ref hPToken)) 
    { 
     return false ; 
    } 

    // Security attibute structure used in DuplicateTokenEx and CreateProcessAsUser 
    // I would prefer to not have to use a security attribute variable and to just 
    // simply pass null and inherit (by default) the security attributes 
    // of the existing token. However, in C# structures are value types and therefore 
    // cannot be assigned the null value. 
    SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES(); 
    sa.Length = Marshal.SizeOf(sa); 

    // copy the access token of the winlogon process; the newly created token will be a primary token 
    if (!DuplicateTokenEx(hPToken, MAXIMUM_ALLOWED, ref sa, (int)SECURITY_IMPERSONATION_LEVEL.SecurityIdentification, (int)TOKEN_TYPE.TokenPrimary, ref hUserTokenDup)) 
    { 
     CloseHandle(hProcess); 
     CloseHandle(hPToken); 
     return false; 
    } 

    // By default CreateProcessAsUser creates a process on a non-interactive window station, meaning 
    // the window station has a desktop that is invisible and the process is incapable of receiving 
    // user input. To remedy this we set the lpDesktop parameter to indicate we want to enable user 
    // interaction with the new process. 
    STARTUPINFO si = new STARTUPINFO(); 
    si.cb = (int)Marshal.SizeOf(si); 
    si.lpDesktop = @"winsta0\default"; // interactive window station parameter; basically this indicates that the process created can display a GUI on the desktop 

    // flags that specify the priority and creation method of the process 
    int dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE; 

    // create a new process in the current user's logon session 
    bool result = CreateProcessAsUser(hUserTokenDup,  // client's access token 
            null,     // file to execute 
            ps.FileName,   // command line 
            ref sa,     // pointer to process SECURITY_ATTRIBUTES 
            ref sa,     // pointer to thread SECURITY_ATTRIBUTES 
            true,     // handles are not inheritable 
            dwCreationFlags,  // creation flags 
            IntPtr.Zero,   // pointer to new environment block 
            ps.WorkingDirectory, // name of current directory 
            ref si,     // pointer to STARTUPINFO structure 
            out procInfo   // receives information about new process 
            ); 

    // invalidate the handles 
    CloseHandle(hProcess); 
    CloseHandle(hPToken); 
    CloseHandle(hUserTokenDup); 

    return result; // return the result 
} 
관련 문제