[Reference] [1]: Create process as different user with Java and Kerberos
As mentioned in the code, we need to pass hToken in the below snippets:
Advapi32.INSTANCE.ImpersonateLoggedOnUser(/* provide the security context token */)
In the below code primaryToken is just a empty object,
// create primary token by duplicating impersonation token
WinNT.HANDLEByReference primaryToken = new WinNT.HANDLEByReference();
boolean createProcessResult = Advapi32.INSTANCE.CreateProcessAsUser(
primaryToken.getValue(), /* hToken */
null, /* lpApplicationName */
command, /* lpCommandLine */
null, /* lpProcessAttributes */
null, /* lpThreadAttributes */
false, /* bInheritHandles */
WinNT.CREATE_NEW_CONSOLE | WinNT.CREATE_UNICODE_ENVIRONMENT, /* dwCreationFlags */
environment, /* lpEnvironment */
processDirectory, /* lpCurrentDirectory */
startupInfo, /* lpStartupInfo */
processInfo); /* lpProcessInformation */
These referenced code is stated as working solution, but mostly it has custom empty objects and other than getting token bytes from authorization Header. We haven't done anything with windowsIdentity object from security context.
Kindly anyone let me know how to get the hToken from the security context.
Enable SE_INCREASE_QUOTA_NAME Privilege -- Returns true
private void adjustProcessPrivilege() {
HANDLEByReference hToken = new HANDLEByReference();
WinNT.LUID luid = new WinNT.LUID();
Advapi32.INSTANCE.OpenProcessToken(Kernel32.INSTANCE.GetCurrentProcess(),
WinNT.TOKEN_ADJUST_PRIVILEGES, hToken);
Advapi32.INSTANCE.LookupPrivilegeValue("", WinNT.SE_INCREASE_QUOTA_NAME, luid);
WinNT.TOKEN_PRIVILEGES tp = new WinNT.TOKEN_PRIVILEGES(1);
tp.Privileges[0] = new LUID_AND_ATTRIBUTES(luid, new DWORD(WinNT.SE_PRIVILEGE_ENABLED));
boolean isPrivilegeAdjusted = Advapi32.INSTANCE.AdjustTokenPrivileges(hToken.getValue(), false, tp, tp.size(), null,
new IntByReference());
System.out.println(isPrivilegeAdjusted); //Returns True
}
CreateProcessAsUserA -- Impersonation has failed
@GetMapping("createProcessAsUserNew")
public String createProcessAsUserNew() {
adjustProcessPrivilege();
HANDLEByReference phToken = new HANDLEByReference();
HANDLE processHandle = null;
HANDLE threadHandle = null;
Win32Exception err = null;
HANDLE hToken = null;
try {
// open thread or process token
threadHandle = Kernel32.INSTANCE.GetCurrentThread();
if (!Advapi32.INSTANCE.OpenThreadToken(threadHandle, WinNT.TOKEN_DUPLICATE | WinNT.TOKEN_QUERY | WinNT.TOKEN_ASSIGN_PRIMARY, false, phToken)) {
int rc = Kernel32.INSTANCE.GetLastError();
if (rc != W32Errors.ERROR_NO_TOKEN) {
throw new Win32Exception(rc);
}
processHandle = Kernel32.INSTANCE.GetCurrentProcess();
if (!Advapi32.INSTANCE.OpenProcessToken(processHandle, WinNT.TOKEN_DUPLICATE | WinNT.TOKEN_QUERY | WinNT.TOKEN_ASSIGN_PRIMARY, phToken)) {
throw new Win32Exception(Kernel32.INSTANCE.GetLastError());
}
}
}
catch (Win32Exception e) {
err = e;
throw err;
} finally {
hToken = phToken.getValue();
if (!WinBase.INVALID_HANDLE_VALUE.equals(hToken)) {
try {
Kernel32Util.closeHandle(hToken);
} catch (Win32Exception e) {
if (err == null) {
err = e;
} else {
err.addSuppressed(e);
}
}
}
if (err != null) {
throw err;
}
}
boolean isUserImpersonated = Advapi32.INSTANCE.ImpersonateLoggedOnUser(hToken); //This returns false
System.out.printf("User Impersonated:",isUserImpersonated);
// create primary token by duplicating impersonation token
WinNT.HANDLEByReference impersonateUserToken = new WinNT.HANDLEByReference();
boolean primaryTokenResult = Advapi32.INSTANCE.DuplicateTokenEx(
threadHandle, /* hExistingToken */
WinNT.TOKEN_DUPLICATE | WinNT.TOKEN_QUERY | WinNT.TOKEN_ASSIGN_PRIMARY, /* dwDesiredAccess */
null, /* lpTokenAttributes */
WinNT.SECURITY_IMPERSONATION_LEVEL.SecurityDelegation, /* ImpersonationLevel */
WinNT.TOKEN_TYPE.TokenPrimary, /* TokenType */
impersonateUserToken);
WinBase.STARTUPINFO startupInfo = new WinBase.STARTUPINFO();
WinBase.PROCESS_INFORMATION processInfo = new WinBase.PROCESS_INFORMATION();
boolean createProcessResult = Advapi32.INSTANCE.CreateProcessAsUser(
impersonateUserToken.getValue(), /* hToken */
"C:\\Windows\\notepad.exe", /* lpApplicationName */
null, /* lpCommandLine */
null, /* lpProcessAttributes */
null, /* lpThreadAttributes */
false, /* j */
WinNT.CREATE_NEW_CONSOLE | WinNT.CREATE_UNICODE_ENVIRONMENT, /* dwCreationFlags */
null, /* lpEnvironment */
null, /* lpCurrentDirectory */
startupInfo, /* lpStartupInfo */
processInfo); /* lpProcessInformation */
System.out.println(createProcessResult);
return String.format("New Process created ",createProcessResult);
}