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

@@ -3,84 +3,71 @@ import sequtils, strutils, times, base64
import ./handlers
import ../[utils, globals]
import ../../common/types
proc encode(bytes: seq[seq[byte]]): string =
result = ""
for task in bytes:
result &= encode(task)
import ../../common/[types, utils]
proc error404*(ctx: Context) {.async.} =
resp "", Http404
#[
POST /{listener-uuid}/register
POST /register
Called from agent to register itself to the conquest server
]#
proc register*(ctx: Context) {.async.} =
# Check headers
# If POST data is not JSON data, return 404 error code
if ctx.request.contentType != "application/json":
# If POST data is not binary data, return 404 error code
if ctx.request.contentType != "application/octet-stream":
resp "", Http404
return
# The JSON data for the agent registration has to be in the following format
#[
{
"username": "username",
"hostname":"hostname",
"domain": "domain.local",
"ip": "ip-address",
"os": "operating-system",
"process": "agent.exe",
"pid": 1234,
"elevated": false.
"sleep": 10
}
]#
try:
let
postData: JsonNode = parseJson(ctx.request.body)
agentRegistrationData: AgentRegistrationData = postData.to(AgentRegistrationData)
agentUuid: string = generateUUID()
listenerUuid: string = ctx.getPathParams("listener")
date: DateTime = now()
let agent: Agent = Agent(
name: agentUuid,
listener: listenerUuid,
username: agentRegistrationData.username,
hostname: agentRegistrationData.hostname,
domain: agentRegistrationData.domain,
process: agentRegistrationData.process,
pid: agentRegistrationData.pid,
ip: agentRegistrationData.ip,
os: agentRegistrationData.os,
elevated: agentRegistrationData.elevated,
sleep: agentRegistrationData.sleep,
jitter: 0.2,
tasks: @[],
firstCheckin: date,
latestCheckin: date
)
# Fully register agent and add it to database
if not agent.register():
# Either the listener the agent tries to connect to does not exist in the database, or the insertion of the agent failed
# Return a 404 error code either way
resp "", Http404
return
# If registration is successful, the agent receives it's UUID, which is then used to poll for tasks and post results
resp agent.name
let agentId = register(ctx.request.body.toBytes())
resp "Ok", Http200
except CatchableError:
# JSON data is invalid or does not match the expected format (described above)
resp "", Http404
return
# try:
# let
# postData: JsonNode = parseJson(ctx.request.body)
# agentRegistrationData: AgentRegistrationData = postData.to(AgentRegistrationData)
# agentUuid: string = generateUUID()
# listenerUuid: string = ctx.getPathParams("listener")
# date: DateTime = now()
# let agent: Agent = Agent(
# name: agentUuid,
# listener: listenerUuid,
# username: agentRegistrationData.username,
# hostname: agentRegistrationData.hostname,
# domain: agentRegistrationData.domain,
# process: agentRegistrationData.process,
# pid: agentRegistrationData.pid,
# ip: agentRegistrationData.ip,
# os: agentRegistrationData.os,
# elevated: agentRegistrationData.elevated,
# sleep: agentRegistrationData.sleep,
# jitter: 0.2,
# tasks: @[],
# firstCheckin: date,
# latestCheckin: date
# )
# # Fully register agent and add it to database
# if not agent.register():
# # Either the listener the agent tries to connect to does not exist in the database, or the insertion of the agent failed
# # Return a 404 error code either way
# resp "", Http404
# return
# # If registration is successful, the agent receives it's UUID, which is then used to poll for tasks and post results
# resp agent.name
# except CatchableError:
# # JSON data is invalid or does not match the expected format (described above)
# resp "", Http404
# return
#[
GET /{listener-uuid}/{agent-uuid}/tasks
@@ -122,17 +109,11 @@ proc getTasks*(ctx: Context) {.async.} =
resp "", Http404
#[
POST /{listener-uuid}/{agent-uuid}/{task-uuid}/results
POST /results
Called from agent to post results of a task
]#
proc postResults*(ctx: Context) {.async.} =
let
listener = ctx.getPathParams("listener")
agent = ctx.getPathParams("agent")
task = ctx.getPathParams("task")
# Check headers
# If POST data is not binary data, return 404 error code
if ctx.request.contentType != "application/octet-stream":