Intended Process is not created as impersonated/logged on user. Stack: Waffle, Spring security and JNA

149 Views Asked by At

When user tries to access the controller method from web application, the below code will be executed to create a process as impersonated/logged on user. Below code executed without any issues. New Notepad has been created but the process owner is server user not the logged on user. Please let me know what I am missing from the below code to create a process as impersonated user.

Note: Running eclipse/sts as Admin user and the primary token (processToken) has all the required privilege for impersonation.

public String createProcessAsUser(HttpServletRequest req) {

        // Enabled Error handler to all the functions -- No Errors
        HANDLEByReference processToken = new HANDLEByReference();
        HANDLE processHandle = Kernel32.INSTANCE.GetCurrentProcess();

        // Get Current process Handle -- Access Token of the active user
        if (!Advapi32.INSTANCE.OpenProcessToken(
                processHandle, WinNT.TOKEN_DUPLICATE | WinNT.TOKEN_QUERY | WinNT.TOKEN_ALL_ACCESS
                        | WinNT.TOKEN_ASSIGN_PRIMARY | WinNT.TOKEN_ADJUST_PRIVILEGES | WinNT.TOKEN_IMPERSONATE,
                processToken)) {
            int rc = Kernel32.INSTANCE.GetLastError();
            if (rc != W32Errors.ERROR_NO_TOKEN) {
                throw new Win32Exception(rc);
            }
        }

        WinNT.LUID luid = null;
        WinNT.TOKEN_PRIVILEGES tp = new WinNT.TOKEN_PRIVILEGES(2);

        /*
         * Required privileges to assign token for Impersonation. 
           User doesn't have SE_ASSIGNPRIMARYTOKEN_NAME privilege, so couldn't be 
           enabled/disabled
         * 
         */
        String[] privileges = { WinNT.SE_INCREASE_QUOTA_NAME, WinNT.SE_ASSIGNPRIMARYTOKEN_NAME };

        for (int i = 0; i < privileges.length; i++) {
            luid = new WinNT.LUID();
            if (Advapi32.INSTANCE.LookupPrivilegeValue("", privileges[i], luid)) {
                tp.Privileges[i] = new LUID_AND_ATTRIBUTES(luid, new DWORD(WinNT.SE_PRIVILEGE_ENABLED));
            } else {
                throw new Win32Exception(Kernel32.INSTANCE.GetLastError());
            }
        }

        // Enable Privileges to the existing Process handle/Token
        if (!Advapi32.INSTANCE.AdjustTokenPrivileges(processToken.getValue(), false, tp, tp.size(), null,
                new IntByReference())) {
            Win32Exception error = new Win32Exception(Kernel32.INSTANCE.GetLastError());
            System.out.println(error.getMessage());
            throw new Win32Exception(Kernel32.INSTANCE.GetLastError());
        }

        // Impersonate logged on user
        if (!Advapi32.INSTANCE.ImpersonateLoggedOnUser(processToken.getValue())) { /* This returns true */
            throw new Win32Exception(Kernel32.INSTANCE.GetLastError());
        }

        WinNT.HANDLEByReference primaryToken = new WinNT.HANDLEByReference();

        // Duplicate impersonated token to create a primary token to invoke the
        // CreateProcessAsUser
        if (!Advapi32.INSTANCE.DuplicateTokenEx(processToken.getValue(),
                WinNT.TOKEN_DUPLICATE | WinNT.TOKEN_QUERY | WinNT.TOKEN_ASSIGN_PRIMARY | WinNT.TOKEN_ADJUST_DEFAULT
                        | WinNT.TOKEN_ALL_ACCESS,
                null, WinNT.SECURITY_IMPERSONATION_LEVEL.SecurityDelegation, WinNT.TOKEN_TYPE.TokenPrimary,
                primaryToken)) {
            throw new Win32Exception(Kernel32.INSTANCE.GetLastError());
        }

        WinBase.STARTUPINFO startupInfo = new WinBase.STARTUPINFO();
        WinBase.PROCESS_INFORMATION processInfo = new WinBase.PROCESS_INFORMATION();
        if (!Advapi32.INSTANCE.CreateProcessAsUser(primaryToken.getValue(), "C:\\Windows\\notepad.exe", null, null,
                null, false, WinNT.CREATE_NEW_CONSOLE | WinNT.CREATE_UNICODE_ENVIRONMENT, null, null, startupInfo,
                processInfo)) {
            throw new Win32Exception(Kernel32.INSTANCE.GetLastError());
        }
        return String.format("New Process created ");
    }

Notepad Process privileges from process explorer

Token Assign Primary

SeAssignPrimaryTokenPrivilege

User Rights Assignment

0

There are 0 best solutions below