Implemented agent registration to match new binary structure instead of json.

This commit is contained in:
Jakob Friedl
2025-07-21 22:07:25 +02:00
parent 99f55cc04f
commit 9f15026fd1
28 changed files with 452 additions and 327 deletions

View File

@@ -1,7 +1,7 @@
import times, strformat, terminal, tables, json, sequtils, strutils
import ./[parser]
import ../utils
import ../../common/types
import ../../common/[types, utils]
proc initAgentCommands*(): Table[string, Command] =
var commands = initTable[string, Command]()
@@ -158,7 +158,7 @@ proc handleAgentCommand*(cq: Conquest, input: string) =
if input.replace(" ", "").len == 0: return
let date: string = now().format("dd-MM-yyyy HH:mm:ss")
cq.writeLine(fgBlue, styleBright, fmt"[{date}] ", fgYellow, fmt"[{cq.interactAgent.name}] ", resetStyle, styleBright, input)
cq.writeLine(fgBlue, styleBright, fmt"[{date}] ", fgYellow, fmt"[{cq.interactAgent.agentId}] ", resetStyle, styleBright, input)
# Convert user input into sequence of string arguments
let parsedArgs = parseInput(input)

View File

@@ -1,7 +1,6 @@
import strutils, strformat, streams
import strutils, strformat, streams, times
import ../utils
import ../../common/types
import ../../common/serialize
import ../../common/[types, utils, serialize]
proc serializeTask*(task: Task): seq[byte] =
@@ -98,4 +97,66 @@ proc deserializeTaskResult*(resultData: seq[byte]): TaskResult =
resultType: resultType,
length: length,
data: data
)
)
proc deserializeNewAgent*(data: seq[byte]): Agent =
var unpacker = initUnpacker(data.toString)
let
magic = unpacker.getUint32()
version = unpacker.getUint8()
packetType = unpacker.getUint8()
flags = unpacker.getUint16()
seqNr = unpacker.getUint32()
size = unpacker.getUint32()
hmacBytes = unpacker.getBytes(16)
# Explicit conversion from seq[byte] to array[16, byte]
var hmac: array[16, byte]
copyMem(hmac.addr, hmacBytes[0].unsafeAddr, 16)
# Packet Validation
if magic != MAGIC:
raise newException(CatchableError, "Invalid magic bytes.")
# TODO: Validate sequence number
# TODO: Validate HMAC
# TODO: Decrypt payload
# let payload = unpacker.getBytes(size)
let
agentId = unpacker.getUint32()
listenerId = unpacker.getUint32()
username = unpacker.getVarLengthMetadata()
hostname = unpacker.getVarLengthMetadata()
domain = unpacker.getVarLengthMetadata()
ip = unpacker.getVarLengthMetadata()
os = unpacker.getVarLengthMetadata()
process = unpacker.getVarLengthMetadata()
pid = unpacker.getUint32()
isElevated = unpacker.getUint8()
sleep = unpacker.getUint32()
return Agent(
agentId: uuidToString(agentId),
listenerId: uuidToString(listenerId),
username: username,
hostname: hostname,
domain: domain,
ip: ip,
os: os,
process: process,
pid: int(pid),
elevated: isElevated != 0,
sleep: int(sleep),
jitter: 0.0, # TODO: Remove jitter
tasks: @[],
firstCheckin: now(),
latestCheckin: now()
)

View File

@@ -1,6 +1,6 @@
import strutils, strformat, times
import ../utils
import ../../common/types
import ../../common/[types, utils]
proc parseInput*(input: string): seq[string] =
var i = 0
@@ -77,8 +77,8 @@ proc parseTask*(cq: Conquest, command: Command, arguments: seq[string]): Task =
# Construct the task payload prefix
var task: Task
task.taskId = uuidToUint32(generateUUID())
task.agentId = uuidToUint32(cq.interactAgent.name)
task.listenerId = uuidToUint32(cq.interactAgent.listener)
task.agentId = uuidToUint32(cq.interactAgent.agentId)
task.listenerId = uuidToUint32(cq.interactAgent.listenerId)
task.timestamp = uint32(now().toTime().toUnix())
task.command = cast[uint16](command.commandType)
task.argCount = uint8(arguments.len)