1

I use Java JNA to execute Windows API commands.

I have a background service running as local-system. From this background service, I'd like to spawn a new process, e.g. notepad.exe on the currently active desktop and user. The new process should not run elevated but with the active logged-in users rights.

I use

  • WTSGetActiveConsoleSessionId to get the active session
  • WTSQueryUserToken to get the related token
  • CreateProcessAsUser to start the process

This works fine if I build a jar and launch the jar with java -jar my.jar from the local-system account.

However, I run the code from an Install4j Installer, which is, more or less, a JVM wrapped in an exe. The same code fails now, and CreateProcessAsUser results in error code 5 (no access)

  • I compared the tokens, and could not find any difference. Same user, owner, groups, and privileges.
  • I tried using process monitor to find anything special: nothing
  • I tried to use CreateProcessWithTokenW instead of CreateProcessAsUser. The process launches but exits immediately(Maybe a Windowstation/Desktop issue)

Expected result: The "child" process starts and shows the UI on the currently active desktop.

Actual result: Errorcode 5 on CreateProcessAsUser

        final PROCESS_INFORMATION processInformation = new PROCESS_INFORMATION();
        final int activeConsoleSessionId = Kernel32Ext.INSTANCE.WTSGetActiveConsoleSessionId();
        final PointerByReference userPrimaryProcessToken = new PointerByReference();
        if (!Wtsapi32Ext.INSTANCE.WTSQueryUserToken(activeConsoleSessionId, userPrimaryProcessToken)) {
            throw new Win32Exception(Kernel32.INSTANCE.GetLastError());
        }
        final STARTUPINFO startupInfo = new STARTUPINFO();
        startupInfo.clear();
        startupInfo.lpDesktop = "winsta0\\default";
        startupInfo.wShowWindow = new WORD(1);
        startupInfo.cb = new DWORD(processInformation.size());
        final String cmdString = "C:\\Windows\\System32\\notepad.exe";
        if (!AdvapiExt.INSTANCE.CreateProcessAsUser(new HANDLE(userPrimaryProcessToken.getValue()), null, cmdString, null, null, true, Kernel32.CREATE_UNICODE_ENVIRONMENT, null, "c:\\", startupInfo, processInformation)) {
            final int error = Kernel32.INSTANCE.GetLastError();
            throw new Win32Exception(error);
        }

TRec
  • 21
  • 4
  • `DuplicateTokenEx` not required. impersonation token - fatal error - it and give you access denied – RbMm Jul 17 '19 at 14:47
  • @RdMm: I used DuplicateTokenEx(new HANDLE(userPrimaryProcessToken.getValue()), WinNT.TOKEN_ALL_ACCESS, null, SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, TOKEN_TYPE.TokenPrimary, userPrimaryProcessTokenew) this should create a primary token. But since WTSQueryUserToken should already return a primary one, I removed this call. But: Still the same error code 5 – TRec Jul 17 '19 at 15:15
  • what api return error code ? post your code instead describe it – RbMm Jul 17 '19 at 15:45
  • error code 5. I added the code to the question above – TRec Jul 17 '19 at 16:07
  • I noticed, that if I execute my.jar directly, it works, if I launch Install4j which starts my.jar, it does not work. The Install4j Installer in the "Launch" chain must be doing something to the security context... – TRec Jul 17 '19 at 19:22
  • "I compared the tokens, and could not find any difference." Which tokens? The caller's in both contexts, which should use the SYSTEM logon, or the user's session token from `WTSQueryUserToken` in both contexts? – Eryk Sun Jul 17 '19 at 23:37
  • I looked at both, the "Parent" process ThreadToken and the "Target" Token received from WTSQueryUserToken. I could not check all information due to limitations in JNA, but user, owner, groups and privileges were the same – TRec Jul 18 '19 at 10:02
  • Are you running the system service with elevated permissions? – Daniel Widdis Jul 19 '19 at 15:40
  • Yes,...local system permissions – TRec Jul 19 '19 at 20:23

1 Answers1

0

This is not a real answer, but after a system restart and windows updates, I cannot reproduce the problem anymore. If I ever manage to reproduce it again, I will continue the investigation.

A few things a noticed before the problem "disappeared":

1. Before updating windows, I enabled the program execution audit(local security policies), and saw in the windows logs, that, according to the logs, the application got started, even there was no window or running process, and the CreateProcessAsUser returned with an error...

2. The problem did only happen if services.exe was in the calling-chain. If I started the application directly via psexe as a local system process, everything went fine.

TRec
  • 21
  • 4