tags:

views:

158

answers:

1

Hi

I am trying to make a running process of mine which is elevated to restart explorer using the standard user token.

What I'm doing is first I run the main process as an administrator, then I take a snapshot of the running:

if (Process32First(hSnapshot,&pe32))
    {
        do
        {
            if (!wcsicmp(pe32.szExeFile, L"explorer.exe"))
            {
                DWORD dwExplorerSessId = 0;
                if (ProcessIdToSessionId(pe32.th32ProcessID, &dwExplorerSessId) && dwExplorerSessId == dwSessionId)
                {
                    dwExplorerLogonPid = pe32.th32ProcessID;
                    break;
                }
            }

        } while (Process32Next(hSnapshot, &pe32));
    }

    CloseHandle(hSnapshot);

then once I get the PID of explorer which is running under the standard user account, I call:

OpenProcessToken(hProcess,TOKEN_DUPLICATE | TOKEN_QUERY | TOKEN_IMPERSONATE
            ,&hPToken))

then I call:

ImpersonateLoggedOnUser(hPToken);

and finally I taskkill explorer.exe and shell execute it again but its running under the administrators privileges.

Its as if the impersonateLoggedonUser is not working. Although its returning true and GetLastError() returns 0;

I have also tried using CreateProcessAsUser() but this always gives an ERROR_FILE_NOT_FOUND:

    STARTUPINFO si;
    GetStartupInfo(&si);                
    PROCESS_INFORMATION pi;
    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));

    TCHAR tchcmd[MAX_PATH];
    _tcscpy(tchcmd, _T("explorer.exe"));
    PVOID penv;
    CreateEnvironmentBlock(&penv, hToken, FALSE);
HANDLE hNewToken;
DuplicateTokenEx(hToken, TOKEN_ALL_ACCESS, NULL, SecurityIdentification, TokenImpersonation, &hNewToken);
    CreateProcessAsUser(, NULL, tchcmd, 0, 0, 0, CREATE_DEFAULT_ERROR_MODE, penv, 0, &si, &pi );

Any Ideas or suggestions.

+1  A: 

Are you calling DuplicateTokenEx on the token before using it? You should.

Instead of ImpersonateLoggedOnUser, you could more easily just call CreateProcessAsUser.

Edit to match yours:

  • Your CreateProcessAsUser by the way should be passing: CREATE_DEFAULT_ERROR_MODE | CREATE_UNICODE_ENVIRONMENT for the dwCreationFlags.

  • You should also be error checking your CreateEnvironmentBlock.

  • You should also be adjusting the Ace of the desktop and window station.

  • Instead of specifying the path directly in CreateProcessByUser you should first expand any environment variables in the string by using ExpandEnvironmentStringsForUser. This will for example convert: %windir%\explorer.exe to C:\windows\explorer.exe

.

wchar_t szNewCommandLine[MAX_PATH];
if(!::ExpandEnvironmentStringsForUser(hNewToken, tchcmd, szNewCommandLine, MAX_PATH - 1))
{
    DWORD dwExpandEnvLastError = GetLastError();
    //error handling
}   

For further reading please see this post on Session, Window Station, and Desktop management.

Brian R. Bondy
I tried it also but its returning INVALID_PARAMETER_ERRORI edited the question for the method I'm using..
Red Serpent
What is returning INVALID_PARAMETER_ERROR? Are you calling DuplicateTokenEx?
Brian R. Bondy
Added more info.
Brian R. Bondy
I have made adjustments to the code and added the duplicatetokenex and gave it a TOKEN_ALL_ACCESS right, but now when I call CreateProcessAsUser it gives error code 2 ERROR_FILE_NOT_FOUND.Any Ideas
Red Serpent
Try specifying the full path of explorer.exe. You didn't set the working directory and maybe the CreateEnvironment block is not working as you expected. You could possibly try calling LoadUserProfile Win32 API to help.
Brian R. Bondy
So how can I check if the environment block is working, I am debugging the code and there is no error returned from creating the environment block. And I'm not sure how LoadUserProfile can help.
Red Serpent
Added more details, what happens when you call CreateProcessAsUser with `"C:\\windows\\explorer.exe"` directly?
Brian R. Bondy
"So how can I check if the environment block is working" - via its return value.
Brian R. Bondy
Well after hours of trials and errors I finally reached the point where CreateProcessAsUser returns 1314... Now its more of a privilege problem. The problem is when I try to set the privileges (SE_ASSIGNPRIMARYTOKEN_NAME and SE_INCREASE_QUOTA_NAME) but it seems that the token does not hold those privileges to begin with as AdjustTokenPrivilege returns ERROR_NOT_ALL_ASSIGNED. I'm using the MSDN example http://msdn.microsoft.com/en-us/library/aa446619%28VS.85%29.aspx if thats worth something.
Red Serpent
Perhaps you need to add the ace to the desktop and windows station and you need to set the desktop member to winsta0\default
Brian R. Bondy