From cf4e4a701775cac51e0df623031d1b521c1f13c7 Mon Sep 17 00:00:00 2001 From: Jakob Friedl <71284620+jakobfriedl@users.noreply.github.com> Date: Wed, 23 Jul 2025 15:25:19 +0200 Subject: [PATCH] Updated database to store session key (still unencrypted) --- .gitignore | 2 + src/agents/monarch/nim.cfg | 12 ++--- src/common/crypto.nim | 3 +- src/common/types.nim | 1 - src/server/db/database.nim | 2 +- src/server/db/dbAgent.nim | 101 ++++++++++++++++++++++--------------- src/server/task/packer.nim | 1 - 7 files changed, 71 insertions(+), 51 deletions(-) diff --git a/.gitignore b/.gitignore index 7170930..c8324bf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ # Ignore agents # agents/ *.db +data/* +!data/.gitkeep # Ignore binaries bin/* !bin/.gitkeep diff --git a/src/agents/monarch/nim.cfg b/src/agents/monarch/nim.cfg index 113a71e..404345d 100644 --- a/src/agents/monarch/nim.cfg +++ b/src/agents/monarch/nim.cfg @@ -1,8 +1,8 @@ # Agent configuration --d:ListenerUuid="A5466110" --d:Octet1="172" --d:Octet2="29" --d:Octet3="177" --d:Octet4="43" --d:ListenerPort=8888 +-d:ListenerUuid="D3AC0FF3" +-d:Octet1="127" +-d:Octet2="0" +-d:Octet3="0" +-d:Octet4="1" +-d:ListenerPort=9999 -d:SleepDelay=5 diff --git a/src/common/crypto.nim b/src/common/crypto.nim index 0cf0acd..16d2a66 100644 --- a/src/common/crypto.nim +++ b/src/common/crypto.nim @@ -45,4 +45,5 @@ proc decrypt*(key: Key, iv: Iv, encData: seq[byte], sequenceNumber: uint64): (se ctx.getTag(tag) ctx.clear() - return (data, tag) \ No newline at end of file + return (data, tag) + diff --git a/src/common/types.nim b/src/common/types.nim index be81d89..e867785 100644 --- a/src/common/types.nim +++ b/src/common/types.nim @@ -150,7 +150,6 @@ type pid*: int elevated*: bool sleep*: int - jitter*: float tasks*: seq[Task] firstCheckin*: DateTime latestCheckin*: DateTime diff --git a/src/server/db/database.nim b/src/server/db/database.nim index 7981f62..fd1d44f 100644 --- a/src/server/db/database.nim +++ b/src/server/db/database.nim @@ -33,9 +33,9 @@ proc dbInit*(cq: Conquest) = os TEXT NOT NULL, elevated BOOLEAN NOT NULL, sleep INTEGER DEFAULT 10, - jitter REAL DEFAULT 0.1, firstCheckin DATETIME NOT NULL, latestCheckin DATETIME NOT NULL, + sessionKey BLOB NOT NULL, FOREIGN KEY (listener) REFERENCES listeners(name) ); diff --git a/src/server/db/dbAgent.nim b/src/server/db/dbAgent.nim index b51c84a..714c4f0 100644 --- a/src/server/db/dbAgent.nim +++ b/src/server/db/dbAgent.nim @@ -1,20 +1,23 @@ -import system, terminal, tiny_sqlite, times +import system, terminal, tiny_sqlite, times, sequtils import ../utils import ../../common/[types, utils] #[ - Agent database functions + Agent database functions - Updated with session key support (no jitter) ]# + proc dbStoreAgent*(cq: Conquest, agent: Agent): bool = - try: let conquestDb = openDatabase(cq.dbPath, mode=dbReadWrite) + # Convert session key to blob for storage + let sessionKeyBlob = agent.sessionKey.toSeq() + conquestDb.exec(""" - INSERT INTO agents (name, listener, process, pid, username, hostname, domain, ip, os, elevated, sleep, jitter, firstCheckin, latestCheckin) + INSERT INTO agents (name, listener, process, pid, username, hostname, domain, ip, os, elevated, sleep, firstCheckin, latestCheckin, sessionKey) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?); - """, agent.agentId, agent.listenerId, agent.process, agent.pid, agent.username, agent.hostname, agent.domain, agent.ip, agent.os, agent.elevated, agent.sleep, agent.jitter, agent.firstCheckin.format("dd-MM-yyyy HH:mm:ss"), agent.latestCheckin.format("dd-MM-yyyy HH:mm:ss")) + """, agent.agentId, agent.listenerId, agent.process, agent.pid, agent.username, agent.hostname, agent.domain, agent.ip, agent.os, agent.elevated, agent.sleep, agent.firstCheckin.format("dd-MM-yyyy HH:mm:ss"), agent.latestCheckin.format("dd-MM-yyyy HH:mm:ss"), sessionKeyBlob) conquestDb.close() except: @@ -24,31 +27,39 @@ proc dbStoreAgent*(cq: Conquest, agent: Agent): bool = return true proc dbGetAllAgents*(cq: Conquest): seq[Agent] = - var agents: seq[Agent] = @[] try: let conquestDb = openDatabase(cq.dbPath, mode=dbReadWrite) - for row in conquestDb.iterate("SELECT name, listener, sleep, jitter, process, pid, username, hostname, domain, ip, os, elevated, firstCheckin, latestCheckin FROM agents;"): - let (agentId, listenerId, sleep, jitter, process, pid, username, hostname, domain, ip, os, elevated, firstCheckin, latestCheckin) = row.unpack((string, string, int, float, string, int, string, string, string, string, string, bool, string, string)) + for row in conquestDb.iterate("SELECT name, listener, sleep, process, pid, username, hostname, domain, ip, os, elevated, firstCheckin, latestCheckin, sessionKey FROM agents;"): + let (agentId, listenerId, sleep, process, pid, username, hostname, domain, ip, os, elevated, firstCheckin, latestCheckin, sessionKeyBlob) = row.unpack((string, string, int, string, int, string, string, string, string, string, bool, string, string, seq[byte])) + + # Convert session key blob back to array + var sessionKey: Key + if sessionKeyBlob.len == 32: + copyMem(sessionKey[0].addr, sessionKeyBlob[0].unsafeAddr, 32) + else: + # Handle invalid session key - log error but continue + cq.writeLine(fgYellow, styleBright, "[!] Invalid session key length for agent: ", agentId) let a = Agent( - agentId: agentId, - listenerId: listenerId, - sleep: sleep, - pid: pid, - username: username, - hostname: hostname, - domain: domain, - ip: ip, - os: os, - elevated: elevated, - firstCheckin: parse(firstCheckin, "dd-MM-yyyy HH:mm:ss"), - latestCheckin: parse(latestCheckin, "dd-MM-yyyy HH:mm:ss"), - jitter: jitter, - process: process - ) + agentId: agentId, + listenerId: listenerId, + sleep: sleep, + pid: pid, + username: username, + hostname: hostname, + domain: domain, + ip: ip, + os: os, + elevated: elevated, + firstCheckin: parse(firstCheckin, "dd-MM-yyyy HH:mm:ss"), + latestCheckin: parse(latestCheckin, "dd-MM-yyyy HH:mm:ss"), + process: process, + sessionKey: sessionKey, + tasks: @[] # Initialize empty tasks + ) agents.add(a) @@ -59,31 +70,38 @@ proc dbGetAllAgents*(cq: Conquest): seq[Agent] = return agents proc dbGetAllAgentsByListener*(cq: Conquest, listenerName: string): seq[Agent] = - var agents: seq[Agent] = @[] try: let conquestDb = openDatabase(cq.dbPath, mode=dbReadWrite) - for row in conquestDb.iterate("SELECT name, listener, sleep, jitter, process, pid, username, hostname, domain, ip, os, elevated, firstCheckin, latestCheckin FROM agents WHERE listener = ?;", listenerName): - let (agentId, listenerId, sleep, jitter, process, pid, username, hostname, domain, ip, os, elevated, firstCheckin, latestCheckin) = row.unpack((string, string, int, float, string, int, string, string, string, string, string, bool, string, string)) + for row in conquestDb.iterate("SELECT name, listener, sleep, process, pid, username, hostname, domain, ip, os, elevated, firstCheckin, latestCheckin, sessionKey FROM agents WHERE listener = ?;", listenerName): + let (agentId, listenerId, sleep, process, pid, username, hostname, domain, ip, os, elevated, firstCheckin, latestCheckin, sessionKeyBlob) = row.unpack((string, string, int, string, int, string, string, string, string, string, bool, string, string, seq[byte])) + + # Convert session key blob back to array + var sessionKey: Key + if sessionKeyBlob.len == 32: + copyMem(sessionKey[0].addr, sessionKeyBlob[0].unsafeAddr, 32) + else: + cq.writeLine(fgYellow, styleBright, "[!] Invalid session key length for agent: ", agentId) let a = Agent( - agentId: agentId, - listenerId: listenerId, - sleep: sleep, - pid: pid, - username: username, - hostname: hostname, - domain: domain, - ip: ip, - os: os, - elevated: elevated, - firstCheckin: parse(firstCheckin, "dd-MM-yyyy HH:mm:ss"), - latestCheckin: parse(latestCheckin, "dd-MM-yyyy HH:mm:ss"), - jitter: jitter, - process: process, - ) + agentId: agentId, + listenerId: listenerId, + sleep: sleep, + pid: pid, + username: username, + hostname: hostname, + domain: domain, + ip: ip, + os: os, + elevated: elevated, + firstCheckin: parse(firstCheckin, "dd-MM-yyyy HH:mm:ss"), + latestCheckin: parse(latestCheckin, "dd-MM-yyyy HH:mm:ss"), + process: process, + sessionKey: sessionKey, + tasks: @[] + ) agents.add(a) @@ -101,6 +119,7 @@ proc dbDeleteAgentByName*(cq: Conquest, name: string): bool = conquestDb.close() except: + cq.writeLine(fgRed, styleBright, "[-] ", getCurrentExceptionMsg()) return false return true diff --git a/src/server/task/packer.nim b/src/server/task/packer.nim index a3598e5..18eca6a 100644 --- a/src/server/task/packer.nim +++ b/src/server/task/packer.nim @@ -132,7 +132,6 @@ proc deserializeNewAgent*(cq: Conquest, data: seq[byte]): Agent = pid: int(pid), elevated: isElevated != 0, sleep: int(sleep), - jitter: 0.0, # TODO: Remove jitter tasks: @[], firstCheckin: now(), latestCheckin: now(),