I need to invoke windows process by another user with primary token, using jna (java). I am able to peform:
- Login with username, domain & password
- Duplicate token, to generate primary token with dwDesiredAccess set to 33554432 . I'm not sure on the value, this may be the culprit here. Please guide what's the correct value for this. I need to give MAXIMUM_ALLOWED permission, not sure what's equivalent for that in terms of java Integer
- Invoking some random windows command.
On step 3, i'm getting issue that A required privilege is not held by the client
. I have tried different ways, OpenThreadToken and AdjustTokenPrivilege, but that didn't work for me.
Can someone please guide me on how to invoke a process using jna with below code.
Note: I need to invoke multiple commands thus, need to use primary token way.
public static void main(String[] args) throws Exception {
HANDLE loginToken = null;
HANDLE primaryToken = null;
try {
loginToken = performLogin("username", "domain", "password");
setThreadToken(loginToken);
primaryToken = createPrimaryToken(loginToken, 33554432);
invokeCommand(primaryToken);
} catch (ProcessCreationException e) {
e.printStackTrace();
} finally {
if (loginToken != null)
Kernel32.INSTANCE.CloseHandle(loginToken);
if (primaryToken != null)
Kernel32.INSTANCE.CloseHandle(primaryToken);
}
}
private static HANDLE performLogin(String username, String domain, String password) throws ProcessCreationException {
HANDLEByReference pointer = new HANDLEByReference();
invokeWindowsMethod("login", () -> Advapi32.INSTANCE.LogonUser(username, domain,
password, WinBase.LOGON32_LOGON_NETWORK, WinBase.LOGON32_PROVIDER_DEFAULT, pointer));
return pointer.getValue();
}
private static HANDLE createPrimaryToken(HANDLE loginToken, int desiredAccess) throws ProcessCreationException {
System.out.println("dwDesiredAccess:" + desiredAccess);
HANDLEByReference pointer = new HANDLEByReference();
invokeWindowsMethod("duplicated", () -> Advapi32.INSTANCE.DuplicateTokenEx(
loginToken,
desiredAccess,
null,
SECURITY_IMPERSONATION_LEVEL.SecurityDelegation,
TOKEN_TYPE.TokenPrimary,
pointer
));
return pointer.getValue();
}
private static void invokeCommand(HANDLE primaryToken) throws ProcessCreationException {
STARTUPINFO si = new STARTUPINFO();
PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
pi.clear();
invokeWindowsMethod("invokeCommand", () -> Advapi32.INSTANCE.CreateProcessAsUser(
primaryToken,
null,
"whoami",
null,
null,
true,
1024,
null,
null,
si,
pi));
}
private static void invokeWindowsMethod(String method, Supplier<Boolean> processor) throws ProcessCreationException {
Boolean res = processor.get();
System.out.println(method + " : " + res);
if (!res) {
throw lastErrorProcessCreationException(method, Kernel32.INSTANCE.GetLastError());
}
}
private static ProcessCreationException lastErrorProcessCreationException(String context, int errorCode) {
return new ProcessCreationException(String.format("[%s] %s", context,
Kernel32Util.formatMessageFromLastErrorCode(errorCode)));
}