From 21f70feb40e6bc2cdd26da0659a1448b1d7c1fa5 Mon Sep 17 00:00:00 2001 From: Jakob Friedl <71284620+jakobfriedl@users.noreply.github.com> Date: Wed, 29 Oct 2025 19:05:49 +0100 Subject: [PATCH] Fixed username display error when target is connected to a domain. --- src/agent/core/sleepmask.nim | 2 +- src/agent/protocol/registration.nim | 3 ++- src/client/views/sessions.nim | 18 ++++++++---------- src/common/crypto.nim | 10 +++++----- src/common/event.nim | 4 +--- src/common/profile.nim | 1 - src/common/serialize.nim | 6 +++--- src/common/utils.nim | 2 +- src/server/core/websocket.nim | 24 ------------------------ src/server/db/dbAgent.nim | 2 +- 10 files changed, 22 insertions(+), 50 deletions(-) diff --git a/src/agent/core/sleepmask.nim b/src/agent/core/sleepmask.nim index dd969c4..a53c5cc 100644 --- a/src/agent/core/sleepmask.nim +++ b/src/agent/core/sleepmask.nim @@ -644,7 +644,7 @@ proc sleepObfuscate*(sleepSettings: SleepSettings) = # Generate random encryption key var keyBuffer: string = Bytes.toString(generateBytes(Key16)) - key.Buffer = keyBuffer.addr + key.Buffer = addr keyBuffer key.Length = cast[DWORD](keyBuffer.len()) # Execute sleep obfuscation technique diff --git a/src/agent/protocol/registration.nim b/src/agent/protocol/registration.nim index 9fa1ddb..e95a5b5 100644 --- a/src/agent/protocol/registration.nim +++ b/src/agent/protocol/registration.nim @@ -33,11 +33,12 @@ proc getUsername(): string = if getDomain() != "": # If domain-joined, return username in format DOMAIN\USERNAME GetUserNameExW(NameSamCompatible, &buffer, &dwSize) + return $buffer[0 ..< int(dwSize)] else: # If not domain-joined, only return USERNAME discard GetUsernameW(&buffer, &dwSize) + return $buffer[0 ..< int(dwSize) - 1] - return $buffer[0 ..< int(dwSize) - 1] # Current process name proc getProcessExe(): string = diff --git a/src/client/views/sessions.nim b/src/client/views/sessions.nim index 521b3e1..ae0a82c 100644 --- a/src/client/views/sessions.nim +++ b/src/client/views/sessions.nim @@ -64,7 +64,7 @@ proc draw*(component: SessionsTableComponent, showComponent: ptr bool, connectio ImGui_TableFlags_SizingStretchSame.int32 ) - let cols: int32 = 11 + let cols: int32 = 12 if igBeginTable("Sessions", cols, tableFlags, vec2(0.0f, 0.0f), 0.0f): igTableSetupColumn("AgentID", ImGuiTableColumnFlags_NoReorder.int32 or ImGuiTableColumnFlags_NoHide.int32, 0.0f, 0) @@ -73,6 +73,7 @@ proc draw*(component: SessionsTableComponent, showComponent: ptr bool, connectio igTableSetupColumn("IP (External)", ImGuiTableColumnFlags_DefaultHide.int32, 0.0f, 0) igTableSetupColumn("Username", ImGuiTableColumnFlags_None.int32, 0.0f, 0) igTableSetupColumn("Hostname", ImGuiTableColumnFlags_None.int32, 0.0f, 0) + igTableSetupColumn("Domain", ImGuiTableColumnFlags_None.int32, 0.0f, 0) igTableSetupColumn("OS", ImGuiTableColumnFlags_None.int32, 0.0f, 0) igTableSetupColumn("Process", ImGuiTableColumnFlags_None.int32, 0.0f, 0) igTableSetupColumn("PID", ImGuiTableColumnFlags_None.int32, 0.0f, 0) @@ -108,12 +109,7 @@ proc draw*(component: SessionsTableComponent, showComponent: ptr bool, connectio igText(agent.ipExternal) if igTableSetColumnIndex(4): - if not agent.domain.isEmptyOrWhitespace(): - igText(agent.domain & "\\") - igSameLine(0.0f, 0.0f) - igText(agent.username) - if component.agentImpersonation.hasKey(agent.agentId): igSameLine(0.0f, textSpacing) igText(fmt"[{component.agentImpersonation[agent.agentId]}]") @@ -121,12 +117,14 @@ proc draw*(component: SessionsTableComponent, showComponent: ptr bool, connectio if igTableSetColumnIndex(5): igText(agent.hostname) if igTableSetColumnIndex(6): - igText(agent.os) + igText(agent.domain) if igTableSetColumnIndex(7): - igText(agent.process) + igText(agent.os) if igTableSetColumnIndex(8): - igText($agent.pid) + igText(agent.process) if igTableSetColumnIndex(9): + igText($agent.pid) + if igTableSetColumnIndex(10): let duration = now() - agent.firstCheckin.fromUnix().local() let totalSeconds = duration.inSeconds @@ -136,7 +134,7 @@ proc draw*(component: SessionsTableComponent, showComponent: ptr bool, connectio igText(fmt"{hours:02d}:{minutes:02d}:{seconds:02d} ago") - if igTableSetColumnIndex(10): + if igTableSetColumnIndex(11): let duration = now() - component.agentActivity[agent.agentId].fromUnix().local() let totalSeconds = duration.inSeconds diff --git a/src/common/crypto.nim b/src/common/crypto.nim index cb814de..b2dc94a 100644 --- a/src/common/crypto.nim +++ b/src/common/crypto.nim @@ -67,15 +67,15 @@ proc crypto_wipe*(data: ptr byte, size: csize_t) {.importc, cdecl.} # Generate X25519 public key from private key proc getPublicKey*(privateKey: Key): Key = - crypto_x25519_public_key(result[0].addr, privateKey[0].addr) + crypto_x25519_public_key(addr result[0], addr privateKey[0]) # Perform X25519 key exchange proc keyExchange*(privateKey: Key, publicKey: Key): Key = - crypto_x25519(result[0].addr, privateKey[0].addr, publicKey[0].addr) + crypto_x25519(addr result[0], addr privateKey[0], addr publicKey[0]) # Calculate Blake2b hash func pointerAndLength*(bytes: openArray[byte]): (ptr[byte], uint) = - result = (cast[ptr[byte]](unsafeAddr bytes), uint(len(bytes))) + result = (cast[ptr[byte]](addr bytes), uint(len(bytes))) func blake2b*(message: openArray[byte], key: openArray[byte] = []): array[64, byte] = let (messagePtr, messageLen) = pointerAndLength(message) @@ -86,7 +86,7 @@ func blake2b*(message: openArray[byte], key: openArray[byte] = []): array[64, by # Secure memory wiping proc wipeKey*(data: var openArray[byte]) = if data.len > 0: - crypto_wipe(data[0].addr, data.len.csize_t) + crypto_wipe(addr data[0], data.len.csize_t) # Key pair generation proc generateKeyPair*(): KeyPair = @@ -114,7 +114,7 @@ proc deriveSessionKey*(keyPair: KeyPair, publicKey: Key): Key = # Calculate Blake2b hash and extract the first 32 bytes for the AES key (https://monocypher.org/manual/blake2b) let hash = blake2b(hashMessage, sharedSecret) - copyMem(key[0].addr, hash[0].addr, sizeof(Key)) + copyMem(addr key[0], addr hash[0], sizeof(Key)) # Cleanup wipeKey(sharedSecret) diff --git a/src/common/event.nim b/src/common/event.nim index 3c4d6af..8d0979b 100644 --- a/src/common/event.nim +++ b/src/common/event.nim @@ -10,9 +10,7 @@ proc sendEvent*(ws: WebSocket, event: Event, key: Key = default(Key)) = var packer = Packer.init() let iv = generateBytes(Iv) - - var - data = string.toBytes($event.data) + var data = string.toBytes($event.data) packer.add(cast[uint8](event.eventType)) packer.add(cast[uint32](event.timestamp)) diff --git a/src/common/profile.nim b/src/common/profile.nim index 99de27c..4204231 100644 --- a/src/common/profile.nim +++ b/src/common/profile.nim @@ -30,7 +30,6 @@ proc getRandom*(values: seq[TomlValueRef]): TomlValueRef = return values[rand(values.len - 1)] proc getStringValue*(key: TomlValueRef, default: string = ""): string = - # In some cases, the profile can define multiple values for a key, e.g. for HTTP headers # A random entry is selected from these specifications var value: string = "" diff --git a/src/common/serialize.nim b/src/common/serialize.nim index 04f9632..325c439 100644 --- a/src/common/serialize.nim +++ b/src/common/serialize.nim @@ -17,7 +17,7 @@ proc add*[T: uint8 | uint16 | uint32 | uint64](packer: Packer, value: T): Packer return packer proc addData*(packer: Packer, data: openArray[byte]): Packer {.discardable.} = - packer.stream.writeData(data[0].unsafeAddr, data.len) + packer.stream.writeData(addr data[0], data.len) return packer proc addArgument*(packer: Packer, arg: TaskArg): Packer {.discardable.} = @@ -97,7 +97,7 @@ proc getBytes*(unpacker: Unpacker, length: int): seq[byte] = return @[] result = newSeq[byte](length) - let bytesRead = unpacker.stream.readData(result[0].addr, length) + let bytesRead = unpacker.stream.readData(addr result[0], length) unpacker.position += bytesRead if bytesRead != length: @@ -106,7 +106,7 @@ proc getBytes*(unpacker: Unpacker, length: int): seq[byte] = proc getByteArray*(unpacker: Unpacker, T: typedesc[Key | Iv | AuthenticationTag]): array = var bytes: array[sizeof(T), byte] - let bytesRead = unpacker.stream.readData(bytes[0].unsafeAddr, sizeof(T)) + let bytesRead = unpacker.stream.readData(addr bytes[0], sizeof(T)) unpacker.position += bytesRead if bytesRead != sizeof(T): diff --git a/src/common/utils.nim b/src/common/utils.nim index dd3b587..cb6ef55 100644 --- a/src/common/utils.nim +++ b/src/common/utils.nim @@ -101,4 +101,4 @@ proc toKey*(value: string): Key = if value.len != 32: raise newException(ValueError, protect("Invalid key length.")) - copyMem(result[0].addr, value[0].unsafeAddr, 32) \ No newline at end of file + copyMem(addr result[0], addr value[0], 32) \ No newline at end of file diff --git a/src/server/core/websocket.nim b/src/server/core/websocket.nim index 61121e4..50225c3 100644 --- a/src/server/core/websocket.nim +++ b/src/server/core/websocket.nim @@ -148,30 +148,6 @@ proc sendBuildlogItem*(client: WsConnection, logType: LogType, message: string) if client != nil: client.ws.sendEvent(event, client.sessionKey) -proc createThumbnail(data: string, maxHeight: int = 1024, quality: int = 80): string = - let img: Image = decodeImage(data) - - # Resize image - let aspectRatio = img.width.float / img.height.float - let - height = min(maxHeight, img.height) - width = int(height.float * aspectRatio) - let thumbnail = img.resize(width, height) - - # Convert to JPEG image for smaller file size - var rgbaData = newSeq[byte](width * height * 4) - var i = 0 - for y in 0..