Started porting over command input & task output to the ImGui client.
This commit is contained in:
@@ -3,6 +3,7 @@ import strformat, strutils, times
|
|||||||
import imguin/[cimgui, glfw_opengl, simple]
|
import imguin/[cimgui, glfw_opengl, simple]
|
||||||
import ../utils/[appImGui, colors]
|
import ../utils/[appImGui, colors]
|
||||||
import ../../common/[types]
|
import ../../common/[types]
|
||||||
|
import ../websocket
|
||||||
|
|
||||||
const MAX_INPUT_LENGTH = 512
|
const MAX_INPUT_LENGTH = 512
|
||||||
type
|
type
|
||||||
@@ -270,6 +271,7 @@ proc draw*(component: ConsoleComponent, ws: WebSocket) =
|
|||||||
component.addItem(LOG_COMMAND, command)
|
component.addItem(LOG_COMMAND, command)
|
||||||
|
|
||||||
# Send command to team server
|
# Send command to team server
|
||||||
|
ws.sendAgentCommand(component.agent.agentId, command)
|
||||||
|
|
||||||
# Add command to console history
|
# Add command to console history
|
||||||
component.history.add(command)
|
component.history.add(command)
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
|
import whisky
|
||||||
import strutils
|
import strutils
|
||||||
import imguin/[cimgui, glfw_opengl, simple]
|
import imguin/[cimgui, glfw_opengl, simple]
|
||||||
import ../utils/appImGui
|
import ../utils/appImGui
|
||||||
import ../../common/[types, utils]
|
import ../../common/[types, utils]
|
||||||
import ./modals/[startListener, generatePayload]
|
import ./modals/[startListener, generatePayload]
|
||||||
import ../websocket
|
import ../websocket
|
||||||
import whisky
|
|
||||||
|
|
||||||
type
|
type
|
||||||
ListenersTableComponent* = ref object of RootObj
|
ListenersTableComponent* = ref object of RootObj
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import whisky
|
import whisky
|
||||||
import times, tables, json
|
import times, tables, json
|
||||||
import ./views/[sessions, listeners, console, eventlog]
|
|
||||||
import ../common/[types, utils, serialize, event]
|
import ../common/[types, utils, serialize, event]
|
||||||
export sendHeartbeat, recvEvent
|
export sendHeartbeat, recvEvent
|
||||||
|
|
||||||
@@ -39,26 +38,13 @@ proc sendAgentBuild*(ws: WebSocket, buildInformation: AgentBuildInformation) =
|
|||||||
)
|
)
|
||||||
ws.sendEvent(event)
|
ws.sendEvent(event)
|
||||||
|
|
||||||
# proc sendAgentCommand*(ws: WebSocket, agentId: string, command: string) =
|
proc sendAgentCommand*(ws: WebSocket, agentId: string, command: string) =
|
||||||
# var packer = Packer.init()
|
let event = Event(
|
||||||
|
eventType: CLIENT_AGENT_COMMAND,
|
||||||
# packer.add(cast[uint8](CLIENT_AGENT_COMMAND))
|
timestamp: now().toTime().toUnix(),
|
||||||
# packer.add(string.toUuid(agentId))
|
data: %*{
|
||||||
# packer.addDataWithLengthPrefix(string.toBytes(command))
|
"agentId": agentId,
|
||||||
# let data = packer.pack()
|
"command": command
|
||||||
|
}
|
||||||
# ws.send(Bytes.toString(data), BinaryMessage)
|
)
|
||||||
|
ws.sendEvent(event)
|
||||||
# proc sendAgentBuild*(ws: WebSocket, listenerId: string, sleepDelay: int, sleepMask: SleepObfuscationTechnique, spoofStack: bool, modules: uint32) =
|
|
||||||
# var packer = Packer.init()
|
|
||||||
|
|
||||||
# packer.add(cast[uint8](CLIENT_AGENT_BUILD))
|
|
||||||
# packer.add(string.toUuid(listenerId))
|
|
||||||
# packer.add(cast[uint32](sleepDelay))
|
|
||||||
# packer.add(cast[uint8](sleepMask))
|
|
||||||
# packer.add(cast[uint8](spoofStack))
|
|
||||||
# packer.add(modules)
|
|
||||||
# let data = packer.pack()
|
|
||||||
|
|
||||||
# ws.send(Bytes.toString(data), BinaryMessage)
|
|
||||||
|
|
||||||
|
|||||||
@@ -91,14 +91,17 @@ proc handleResult*(resultData: seq[byte]) =
|
|||||||
taskId = Uuid.toString(taskResult.taskId)
|
taskId = Uuid.toString(taskResult.taskId)
|
||||||
agentId = Uuid.toString(taskResult.header.agentId)
|
agentId = Uuid.toString(taskResult.header.agentId)
|
||||||
|
|
||||||
|
cq.client.sendConsoleItem(agentId, LOG_INFO, fmt"{$resultData.len} bytes received.")
|
||||||
cq.info(fmt"{$resultData.len} bytes received.")
|
cq.info(fmt"{$resultData.len} bytes received.")
|
||||||
|
|
||||||
# Update task queue to include all tasks, except the one that was just completed
|
# Update task queue to include all tasks, except the one that was just completed
|
||||||
case cast[StatusType](taskResult.status):
|
case cast[StatusType](taskResult.status):
|
||||||
of STATUS_COMPLETED:
|
of STATUS_COMPLETED:
|
||||||
|
cq.client.sendConsoleItem(agentId, LOG_SUCCESS, fmt"Task {taskId} completed.")
|
||||||
cq.success(fmt"Task {taskId} completed.")
|
cq.success(fmt"Task {taskId} completed.")
|
||||||
cq.agents[agentId].tasks = cq.agents[agentId].tasks.filterIt(it.taskId != taskResult.taskId)
|
cq.agents[agentId].tasks = cq.agents[agentId].tasks.filterIt(it.taskId != taskResult.taskId)
|
||||||
of STATUS_FAILED:
|
of STATUS_FAILED:
|
||||||
|
cq.client.sendConsoleItem(agentId, LOG_ERROR, fmt"Task {taskId} failed.")
|
||||||
cq.error(fmt"Task {taskId} failed.")
|
cq.error(fmt"Task {taskId} failed.")
|
||||||
cq.agents[agentId].tasks = cq.agents[agentId].tasks.filterIt(it.taskId != taskResult.taskId)
|
cq.agents[agentId].tasks = cq.agents[agentId].tasks.filterIt(it.taskId != taskResult.taskId)
|
||||||
of STATUS_IN_PROGRESS:
|
of STATUS_IN_PROGRESS:
|
||||||
@@ -106,8 +109,11 @@ proc handleResult*(resultData: seq[byte]) =
|
|||||||
|
|
||||||
case cast[ResultType](taskResult.resultType):
|
case cast[ResultType](taskResult.resultType):
|
||||||
of RESULT_STRING:
|
of RESULT_STRING:
|
||||||
if int(taskResult.length) > 0:
|
if int(taskResult.length) > 0:
|
||||||
|
cq.client.sendConsoleItem(agentId, LOG_INFO, "Output:")
|
||||||
cq.info("Output:")
|
cq.info("Output:")
|
||||||
|
cq.client.sendConsoleItem(agentId, LOG_OUTPUT, Bytes.toString(taskResult.data))
|
||||||
|
|
||||||
# Split result string on newline to keep formatting
|
# Split result string on newline to keep formatting
|
||||||
for line in Bytes.toString(taskResult.data).split("\n"):
|
for line in Bytes.toString(taskResult.data).split("\n"):
|
||||||
cq.output(line)
|
cq.output(line)
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import ../utils
|
|||||||
import ../core/logger
|
import ../core/logger
|
||||||
import ../db/database
|
import ../db/database
|
||||||
import ../../common/types
|
import ../../common/types
|
||||||
|
import ../websocket
|
||||||
|
|
||||||
# Utility functions
|
# Utility functions
|
||||||
proc addMultiple*(cq: Conquest, agents: seq[Agent]) =
|
proc addMultiple*(cq: Conquest, agents: seq[Agent]) =
|
||||||
@@ -123,7 +124,7 @@ proc agentInteract*(cq: Conquest, name: string) =
|
|||||||
|
|
||||||
while command.replace(" ", "") != "back":
|
while command.replace(" ", "") != "back":
|
||||||
command = cq.prompt.readLine()
|
command = cq.prompt.readLine()
|
||||||
cq.handleAgentCommand(command)
|
cq.handleAgentCommand(name, command)
|
||||||
|
|
||||||
# Reset interactAgent field after interaction with agent is ended using 'back' command
|
# Reset interactAgent field after interaction with agent is ended using 'back' command
|
||||||
cq.interactAgent = nil
|
cq.interactAgent = nil
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import prompt, terminal, argparse, parsetoml, times, json
|
import prompt, terminal, argparse, parsetoml, times, json
|
||||||
import strutils, strformat, system, tables
|
import strutils, strformat, system, tables
|
||||||
|
|
||||||
import ./[agent, listener, builder]
|
import ./[agent, listener, task, builder]
|
||||||
import ../globals
|
import ../globals
|
||||||
import ../db/database
|
import ../db/database
|
||||||
import ../core/logger
|
import ../core/logger
|
||||||
@@ -175,7 +175,9 @@ proc websocketHandler(ws: WebSocket, event: WebSocketEvent, message: Message) {.
|
|||||||
|
|
||||||
case event.eventType:
|
case event.eventType:
|
||||||
of CLIENT_AGENT_COMMAND:
|
of CLIENT_AGENT_COMMAND:
|
||||||
discard
|
let agentId = event.data["agentId"].getStr()
|
||||||
|
let command = event.data["command"].getStr()
|
||||||
|
cq.handleAgentCommand(agentId, command)
|
||||||
|
|
||||||
of CLIENT_LISTENER_START:
|
of CLIENT_LISTENER_START:
|
||||||
let listener = event.data.to(UIListener)
|
let listener = event.data.to(UIListener)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import strformat, terminal, tables, sequtils, strutils
|
|||||||
|
|
||||||
import ../protocol/parser
|
import ../protocol/parser
|
||||||
import ../core/logger
|
import ../core/logger
|
||||||
|
import ../websocket
|
||||||
import ../../modules/manager
|
import ../../modules/manager
|
||||||
import ../../common/types
|
import ../../common/types
|
||||||
|
|
||||||
@@ -50,33 +51,28 @@ proc handleHelp(cq: Conquest, parsed: seq[string]) =
|
|||||||
# Command was not found
|
# Command was not found
|
||||||
cq.error(fmt"The command '{parsed[1]}' does not exist." & '\n')
|
cq.error(fmt"The command '{parsed[1]}' does not exist." & '\n')
|
||||||
|
|
||||||
proc handleAgentCommand*(cq: Conquest, input: string) =
|
proc handleAgentCommand*(cq: Conquest, agentId: string, input: string) =
|
||||||
# Return if no command (or just whitespace) is entered
|
|
||||||
if input.replace(" ", "").len == 0: return
|
|
||||||
|
|
||||||
cq.input(input)
|
cq.input(input)
|
||||||
|
|
||||||
# Convert user input into sequence of string arguments
|
# Convert user input into sequence of string arguments
|
||||||
let parsedArgs = parseInput(input)
|
let parsedArgs = parseInput(input)
|
||||||
|
|
||||||
# Handle 'back' command
|
|
||||||
if parsedArgs[0] == "back":
|
|
||||||
cq.interactAgent = nil
|
|
||||||
return
|
|
||||||
|
|
||||||
# Handle 'help' command
|
# Handle 'help' command
|
||||||
if parsedArgs[0] == "help":
|
if parsedArgs[0] == "help":
|
||||||
cq.handleHelp(parsedArgs)
|
cq.handleHelp(parsedArgs)
|
||||||
return
|
return
|
||||||
|
|
||||||
# Handle commands with actions on the agent
|
# Handle commands with actions on the agent
|
||||||
try:
|
try:
|
||||||
let
|
let
|
||||||
command = getCommandByName(parsedArgs[0])
|
command = getCommandByName(parsedArgs[0])
|
||||||
task = cq.createTask(command, parsedArgs[1..^1])
|
task = cq.createTask(agentId, command, parsedArgs[1..^1])
|
||||||
|
|
||||||
# Add task to queue
|
# Add task to queue
|
||||||
cq.interactAgent.tasks.add(task)
|
cq.agents[agentId].tasks.add(task)
|
||||||
|
|
||||||
|
cq.client.sendConsoleItem(agentId, LOG_INFO, fmt"Tasked agent to {command.description.toLowerAscii()}")
|
||||||
cq.info(fmt"Tasked agent to {command.description.toLowerAscii()}")
|
cq.info(fmt"Tasked agent to {command.description.toLowerAscii()}")
|
||||||
|
|
||||||
except CatchableError:
|
except CatchableError:
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import std/paths
|
import std/paths
|
||||||
import strutils, sequtils, times
|
import strutils, sequtils, times, tables
|
||||||
import ../../common/[types, sequence, crypto, utils, serialize]
|
import ../../common/[types, sequence, crypto, utils, serialize]
|
||||||
|
|
||||||
proc parseInput*(input: string): seq[string] =
|
proc parseInput*(input: string): seq[string] =
|
||||||
@@ -84,12 +84,12 @@ proc parseArgument*(argument: Argument, value: string): TaskArg =
|
|||||||
|
|
||||||
return arg
|
return arg
|
||||||
|
|
||||||
proc createTask*(cq: Conquest, command: Command, arguments: seq[string]): Task =
|
proc createTask*(cq: Conquest, agentId: string, command: Command, arguments: seq[string]): Task =
|
||||||
|
|
||||||
# Construct the task payload prefix
|
# Construct the task payload prefix
|
||||||
var task: Task
|
var task: Task
|
||||||
task.taskId = string.toUuid(generateUUID())
|
task.taskId = string.toUuid(generateUUID())
|
||||||
task.listenerId = string.toUuid(cq.interactAgent.listenerId)
|
task.listenerId = string.toUuid(cq.agents[agentId].listenerId)
|
||||||
task.timestamp = uint32(now().toTime().toUnix())
|
task.timestamp = uint32(now().toTime().toUnix())
|
||||||
task.command = cast[uint16](command.commandType)
|
task.command = cast[uint16](command.commandType)
|
||||||
task.argCount = uint8(arguments.len)
|
task.argCount = uint8(arguments.len)
|
||||||
@@ -116,7 +116,7 @@ proc createTask*(cq: Conquest, command: Command, arguments: seq[string]): Task =
|
|||||||
taskHeader.packetType = cast[uint8](MSG_TASK)
|
taskHeader.packetType = cast[uint8](MSG_TASK)
|
||||||
taskHeader.flags = cast[uint16](FLAG_ENCRYPTED)
|
taskHeader.flags = cast[uint16](FLAG_ENCRYPTED)
|
||||||
taskHeader.size = 0'u32
|
taskHeader.size = 0'u32
|
||||||
taskHeader.agentId = string.toUuid(cq.interactAgent.agentId)
|
taskHeader.agentId = string.toUuid(agentId)
|
||||||
taskHeader.seqNr = nextSequence(taskHeader.agentId)
|
taskHeader.seqNr = nextSequence(taskHeader.agentId)
|
||||||
taskHeader.iv = generateBytes(Iv) # Generate a random IV for AES-256 GCM
|
taskHeader.iv = generateBytes(Iv) # Generate a random IV for AES-256 GCM
|
||||||
taskHeader.gmac = default(AuthenticationTag)
|
taskHeader.gmac = default(AuthenticationTag)
|
||||||
|
|||||||
Reference in New Issue
Block a user