Cleanup types.nim to only contain type definitions.
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
# Agent configuration
|
||||
-d:ListenerUuid="JEBFQPEP"
|
||||
-d:ListenerUuid="CFD80565"
|
||||
-d:Octet1="127"
|
||||
-d:Octet2="0"
|
||||
-d:Octet3="0"
|
||||
-d:Octet4="1"
|
||||
-d:ListenerPort=5555
|
||||
-d:SleepDelay=5
|
||||
-d:ListenerPort=9999
|
||||
-d:SleepDelay=10
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import winim, tables
|
||||
import winim
|
||||
import ../../types
|
||||
export Task, CommandType, TaskResult, TaskStatus
|
||||
|
||||
@@ -9,20 +9,19 @@ type
|
||||
DC = 2
|
||||
SERVER = 3
|
||||
|
||||
|
||||
# API Structs
|
||||
type OSVersionInfoExW* {.importc: "OSVERSIONINFOEXW", header: "<windows.h>".} = object
|
||||
dwOSVersionInfoSize*: ULONG
|
||||
dwMajorVersion*: ULONG
|
||||
dwMinorVersion*: ULONG
|
||||
dwBuildNumber*: ULONG
|
||||
dwPlatformId*: ULONG
|
||||
szCSDVersion*: array[128, WCHAR]
|
||||
wServicePackMajor*: USHORT
|
||||
wServicePackMinor*: USHORT
|
||||
wSuiteMask*: USHORT
|
||||
wProductType*: UCHAR
|
||||
wReserved*: UCHAR
|
||||
dwOSVersionInfoSize*: ULONG
|
||||
dwMajorVersion*: ULONG
|
||||
dwMinorVersion*: ULONG
|
||||
dwBuildNumber*: ULONG
|
||||
dwPlatformId*: ULONG
|
||||
szCSDVersion*: array[128, WCHAR]
|
||||
wServicePackMajor*: USHORT
|
||||
wServicePackMinor*: USHORT
|
||||
wSuiteMask*: USHORT
|
||||
wProductType*: UCHAR
|
||||
wReserved*: UCHAR
|
||||
|
||||
type
|
||||
AgentConfig* = ref object
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
import terminal, strformat, strutils, sequtils, tables, json, times, base64, system
|
||||
|
||||
import ../globals
|
||||
import ../[utils, globals]
|
||||
import ../db/database
|
||||
import ../../types
|
||||
|
||||
# Utility functions
|
||||
proc add*(cq: Conquest, agent: Agent) =
|
||||
cq.agents[agent.name] = agent
|
||||
|
||||
#[
|
||||
Agent API
|
||||
Functions relevant for dealing with the agent API, such as registering new agents, querying tasks and posting results
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import prologue, nanoid, json
|
||||
import prologue, json
|
||||
import sequtils, strutils, times
|
||||
|
||||
import ./handlers
|
||||
import ../utils
|
||||
import ../../types
|
||||
|
||||
proc error404*(ctx: Context) {.async.} =
|
||||
@@ -38,12 +39,28 @@ proc register*(ctx: Context) {.async.} =
|
||||
let
|
||||
postData: JsonNode = parseJson(ctx.request.body)
|
||||
agentRegistrationData: AgentRegistrationData = postData.to(AgentRegistrationData)
|
||||
agentUuid: string = generate(alphabet=join(toSeq('A'..'Z'), ""), size=8)
|
||||
agentUuid: string = generateUUID()
|
||||
listenerUuid: string = ctx.getPathParams("listener")
|
||||
date: DateTime = now()
|
||||
|
||||
let agent: Agent = newAgent(agentUuid, listenerUuid, date, agentRegistrationData)
|
||||
|
||||
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
|
||||
|
||||
@@ -5,10 +5,23 @@ import ../task/handler
|
||||
import ../db/database
|
||||
import ../../types
|
||||
|
||||
#[
|
||||
Agent management mode
|
||||
These console commands allow dealing with agents from the Conquest framework's prompt interface
|
||||
]#
|
||||
# Utility functions
|
||||
proc addMultiple*(cq: Conquest, agents: seq[Agent]) =
|
||||
for a in agents:
|
||||
cq.agents[a.name] = a
|
||||
|
||||
proc delAgent*(cq: Conquest, agentName: string) =
|
||||
cq.agents.del(agentName)
|
||||
|
||||
proc getAgentsAsSeq*(cq: Conquest): seq[Agent] =
|
||||
var agents: seq[Agent] = @[]
|
||||
for agent in cq.agents.values:
|
||||
agents.add(agent)
|
||||
return agents
|
||||
|
||||
#[
|
||||
Agent management
|
||||
]#
|
||||
proc agentUsage*(cq: Conquest) =
|
||||
cq.writeLine("""Manage, build and interact with agents.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import strformat, strutils, sequtils, nanoid, terminal
|
||||
import strformat, strutils, sequtils, terminal
|
||||
import prologue
|
||||
|
||||
import ../utils
|
||||
@@ -6,6 +6,25 @@ import ../api/routes
|
||||
import ../db/database
|
||||
import ../../types
|
||||
|
||||
# Utility functions
|
||||
proc delListener(cq: Conquest, listenerName: string) =
|
||||
cq.listeners.del(listenerName)
|
||||
|
||||
proc add(cq: Conquest, listener: Listener) =
|
||||
cq.listeners[listener.name] = listener
|
||||
|
||||
proc newListener*(name: string, address: string, port: int): Listener =
|
||||
var listener = new Listener
|
||||
listener.name = name
|
||||
listener.address = address
|
||||
listener.port = port
|
||||
listener.protocol = HTTP
|
||||
|
||||
return listener
|
||||
|
||||
#[
|
||||
Listener management
|
||||
]#
|
||||
proc listenerUsage*(cq: Conquest) =
|
||||
cq.writeLine("""Manage, start and stop listeners.
|
||||
|
||||
@@ -36,7 +55,7 @@ proc listenerStart*(cq: Conquest, host: string, portStr: string) =
|
||||
|
||||
# Create new listener
|
||||
let
|
||||
name: string = generate(alphabet=join(toSeq('A'..'Z'), ""), size=8)
|
||||
name: string = generateUUID()
|
||||
listenerSettings = newSettings(
|
||||
appName = name,
|
||||
debug = false,
|
||||
|
||||
@@ -2,8 +2,8 @@ import prompt, terminal, argparse
|
||||
import strutils, strformat, times, system, tables
|
||||
|
||||
import ./[agent, listener]
|
||||
import ../[globals, utils]
|
||||
import ../db/database
|
||||
import ../globals
|
||||
import ../../types
|
||||
|
||||
#[
|
||||
@@ -127,6 +127,17 @@ proc header(cq: Conquest) =
|
||||
cq.writeLine("─".repeat(21))
|
||||
cq.writeLine("")
|
||||
|
||||
proc initConquest*(dbPath: string): Conquest =
|
||||
var cq = new Conquest
|
||||
var prompt = Prompt.init()
|
||||
cq.prompt = prompt
|
||||
cq.dbPath = dbPath
|
||||
cq.listeners = initTable[string, Listener]()
|
||||
cq.agents = initTable[string, Agent]()
|
||||
cq.interactAgent = nil
|
||||
|
||||
return cq
|
||||
|
||||
proc startServer*() =
|
||||
# Handle CTRL+C,
|
||||
proc exit() {.noconv.} =
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import system, terminal, tiny_sqlite
|
||||
|
||||
import ./[dbAgent, dbListener]
|
||||
import ../utils
|
||||
import ../../types
|
||||
|
||||
# Export functions so that only ./db/database is required to be imported
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import system, terminal, tiny_sqlite, times
|
||||
|
||||
import ../utils
|
||||
import ../../types
|
||||
|
||||
#[
|
||||
|
||||
@@ -1,6 +1,15 @@
|
||||
import system, terminal, tiny_sqlite
|
||||
|
||||
import ../utils
|
||||
import ../../types
|
||||
|
||||
# Utility functions
|
||||
proc stringToProtocol*(protocol: string): Protocol =
|
||||
case protocol
|
||||
of "http":
|
||||
return HTTP
|
||||
else: discard
|
||||
|
||||
#[
|
||||
Listener database functions
|
||||
]#
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import random
|
||||
import core/server
|
||||
|
||||
# Conquest framework entry point
|
||||
when isMainModule:
|
||||
randomize()
|
||||
startServer()
|
||||
@@ -1,11 +1,12 @@
|
||||
import argparse, times, strformat, terminal, nanoid, sequtils
|
||||
import argparse, times, strformat, terminal, sequtils
|
||||
import ../../types
|
||||
import ../utils
|
||||
|
||||
proc createTask*(cq: Conquest, command: CommandType, args: string, message: string) =
|
||||
let
|
||||
date = now().format("dd-MM-yyyy HH:mm:ss")
|
||||
task = Task(
|
||||
id: generate(alphabet=join(toSeq('A'..'Z'), ""), size=8),
|
||||
id: generateUUID(),
|
||||
agent: cq.interactAgent.name,
|
||||
command: command,
|
||||
args: args,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import times, strformat, terminal, tables, json, sequtils, strutils
|
||||
import ./[parser, packer, dispatcher]
|
||||
import ../utils
|
||||
import ../../types
|
||||
|
||||
proc initAgentCommands*(): Table[CommandType, Command] =
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import strutils, terminal, tables, sequtils, times, strformat
|
||||
import strutils, terminal, tables, sequtils, times, strformat, random, prompt
|
||||
import std/wordwrap
|
||||
|
||||
import ../types
|
||||
|
||||
# Utility functions
|
||||
proc parseOctets*(ip: string): tuple[first, second, third, fourth: int] =
|
||||
# TODO: Verify that address is in correct, expected format
|
||||
let octets = ip.split('.')
|
||||
@@ -15,8 +16,33 @@ proc validatePort*(portStr: string): bool =
|
||||
except ValueError:
|
||||
return false
|
||||
|
||||
# Table border characters
|
||||
proc generateUUID*(): string =
|
||||
# Create a 4-byte HEX UUID string (8 characters)
|
||||
(0..<4).mapIt(rand(255)).mapIt(fmt"{it:02X}").join()
|
||||
|
||||
# Function templates and overwrites
|
||||
template writeLine*(cq: Conquest, args: varargs[untyped]) =
|
||||
cq.prompt.writeLine(args)
|
||||
proc readLine*(cq: Conquest): string =
|
||||
return cq.prompt.readLine()
|
||||
template setIndicator*(cq: Conquest, indicator: string) =
|
||||
cq.prompt.setIndicator(indicator)
|
||||
template showPrompt*(cq: Conquest) =
|
||||
cq.prompt.showPrompt()
|
||||
template hidePrompt*(cq: Conquest) =
|
||||
cq.prompt.hidePrompt()
|
||||
template setStatusBar*(cq: Conquest, statusBar: seq[StatusBarItem]) =
|
||||
cq.prompt.setStatusBar(statusBar)
|
||||
template clear*(cq: Conquest) =
|
||||
cq.prompt.clear()
|
||||
|
||||
# Overwrite withOutput function to handle function arguments
|
||||
proc withOutput*(cq: Conquest, outputFunction: proc(cq: Conquest, args: string), args: string) =
|
||||
cq.hidePrompt()
|
||||
outputFunction(cq, args)
|
||||
cq.showPrompt()
|
||||
|
||||
# Table border characters
|
||||
type
|
||||
Cell = object
|
||||
text: string
|
||||
|
||||
107
src/types.nim
107
src/types.nim
@@ -1,11 +1,8 @@
|
||||
import prompt
|
||||
import prologue
|
||||
import tables
|
||||
import times
|
||||
|
||||
#[
|
||||
Agent types & procs
|
||||
]#
|
||||
# Task structure
|
||||
type
|
||||
CommandType* = enum
|
||||
ExecuteShell = "shell"
|
||||
@@ -62,6 +59,8 @@ type
|
||||
args*: string # Json string containing all the positional arguments
|
||||
# Example: """{"command": "whoami", "arguments": "/all"}"""
|
||||
|
||||
# Agent structure
|
||||
type
|
||||
AgentRegistrationData* = object
|
||||
username*: string
|
||||
hostname*: string
|
||||
@@ -90,30 +89,7 @@ type
|
||||
firstCheckin*: DateTime
|
||||
latestCheckin*: DateTime
|
||||
|
||||
# TODO: Take sleep value from agent registration data (set via nim.cfg file)
|
||||
proc newAgent*(name, listener: string, firstCheckin: DateTime, postData: AgentRegistrationData): Agent =
|
||||
var agent = new Agent
|
||||
agent.name = name
|
||||
agent.listener = listener
|
||||
agent.username = postData.username
|
||||
agent.hostname = postData.hostname
|
||||
agent.domain = postData.domain
|
||||
agent.process = postData.process
|
||||
agent.pid = postData.pid
|
||||
agent.ip = postData.ip
|
||||
agent.os = postData.os
|
||||
agent.elevated = postData.elevated
|
||||
agent.sleep = postData.sleep
|
||||
agent.jitter = 0.2
|
||||
agent.tasks = @[]
|
||||
agent.firstCheckin = firstCheckin
|
||||
agent.latestCheckin = firstCheckin
|
||||
|
||||
return agent
|
||||
|
||||
#[
|
||||
Listener types and procs
|
||||
]#
|
||||
# Listener structure
|
||||
type
|
||||
Protocol* = enum
|
||||
HTTP = "http"
|
||||
@@ -124,82 +100,11 @@ type
|
||||
port*: int
|
||||
protocol*: Protocol
|
||||
|
||||
proc newListener*(name: string, address: string, port: int): Listener =
|
||||
var listener = new Listener
|
||||
listener.name = name
|
||||
listener.address = address
|
||||
listener.port = port
|
||||
listener.protocol = HTTP
|
||||
|
||||
return listener
|
||||
|
||||
proc stringToProtocol*(protocol: string): Protocol =
|
||||
case protocol
|
||||
of "http":
|
||||
return HTTP
|
||||
else: discard
|
||||
|
||||
#[
|
||||
Conquest framework types & procs
|
||||
]#
|
||||
# Server structure
|
||||
type
|
||||
Conquest* = ref object
|
||||
prompt*: Prompt
|
||||
dbPath*: string
|
||||
listeners*: Table[string, Listener]
|
||||
agents*: Table[string, Agent]
|
||||
interactAgent*: Agent
|
||||
|
||||
proc add*(cq: Conquest, listener: Listener) =
|
||||
cq.listeners[listener.name] = listener
|
||||
|
||||
proc add*(cq: Conquest, agent: Agent) =
|
||||
cq.agents[agent.name] = agent
|
||||
|
||||
proc addMultiple*(cq: Conquest, agents: seq[Agent]) =
|
||||
for a in agents:
|
||||
cq.agents[a.name] = a
|
||||
|
||||
proc delListener*(cq: Conquest, listenerName: string) =
|
||||
cq.listeners.del(listenerName)
|
||||
|
||||
proc delAgent*(cq: Conquest, agentName: string) =
|
||||
cq.agents.del(agentName)
|
||||
|
||||
proc getAgentsAsSeq*(cq: Conquest): seq[Agent] =
|
||||
var agents: seq[Agent] = @[]
|
||||
for agent in cq.agents.values:
|
||||
agents.add(agent)
|
||||
return agents
|
||||
|
||||
proc initConquest*(dbPath: string): Conquest =
|
||||
var cq = new Conquest
|
||||
var prompt = Prompt.init()
|
||||
cq.prompt = prompt
|
||||
cq.dbPath = dbPath
|
||||
cq.listeners = initTable[string, Listener]()
|
||||
cq.agents = initTable[string, Agent]()
|
||||
cq.interactAgent = nil
|
||||
|
||||
return cq
|
||||
|
||||
template writeLine*(cq: Conquest, args: varargs[untyped]) =
|
||||
cq.prompt.writeLine(args)
|
||||
proc readLine*(cq: Conquest): string =
|
||||
return cq.prompt.readLine()
|
||||
template setIndicator*(cq: Conquest, indicator: string) =
|
||||
cq.prompt.setIndicator(indicator)
|
||||
template showPrompt*(cq: Conquest) =
|
||||
cq.prompt.showPrompt()
|
||||
template hidePrompt*(cq: Conquest) =
|
||||
cq.prompt.hidePrompt()
|
||||
template setStatusBar*(cq: Conquest, statusBar: seq[StatusBarItem]) =
|
||||
cq.prompt.setStatusBar(statusBar)
|
||||
template clear*(cq: Conquest) =
|
||||
cq.prompt.clear()
|
||||
|
||||
# Overwrite withOutput function to handle function arguments
|
||||
proc withOutput*(cq: Conquest, outputFunction: proc(cq: Conquest, args: string), args: string) =
|
||||
cq.hidePrompt()
|
||||
outputFunction(cq, args)
|
||||
cq.showPrompt()
|
||||
interactAgent*: Agent
|
||||
Reference in New Issue
Block a user