2025-11-21 15:55:41 +01:00
|
|
|
import times, json, base64, strformat
|
2025-10-09 16:25:05 +02:00
|
|
|
import stb_image/write as stbiw
|
2025-10-03 12:44:28 +02:00
|
|
|
import ./logger
|
|
|
|
|
import ../../common/[types, utils, event]
|
2025-09-27 13:54:12 +02:00
|
|
|
export sendHeartbeat, recvEvent
|
2025-09-25 19:22:17 +02:00
|
|
|
|
2025-10-01 15:27:06 +02:00
|
|
|
proc `%`*(agent: Agent): JsonNode =
|
|
|
|
|
result = newJObject()
|
|
|
|
|
result["agentId"] = %agent.agentId
|
|
|
|
|
result["listenerId"] = %agent.listenerId
|
|
|
|
|
result["username"] = %agent.username
|
2025-10-17 13:01:12 +02:00
|
|
|
result["impersonationToken"] = %agent.impersonationToken
|
2025-10-01 15:27:06 +02:00
|
|
|
result["hostname"] = %agent.hostname
|
|
|
|
|
result["domain"] = %agent.domain
|
2025-10-02 10:25:37 +02:00
|
|
|
result["ipInternal"] = %agent.ipInternal
|
|
|
|
|
result["ipExternal"] = %agent.ipExternal
|
2025-10-01 15:27:06 +02:00
|
|
|
result["os"] = %agent.os
|
|
|
|
|
result["process"] = %agent.process
|
|
|
|
|
result["pid"] = %agent.pid
|
|
|
|
|
result["elevated"] = %agent.elevated
|
|
|
|
|
result["sleep"] = %agent.sleep
|
2025-10-23 11:14:26 +02:00
|
|
|
result["jitter"] = %agent.jitter
|
2025-10-02 10:25:37 +02:00
|
|
|
result["modules"] = %agent.modules
|
|
|
|
|
result["firstCheckin"] = %agent.firstCheckin
|
|
|
|
|
result["latestCheckin"] = %agent.latestCheckin
|
2025-10-01 15:27:06 +02:00
|
|
|
|
|
|
|
|
proc `%`*(listener: Listener): JsonNode =
|
|
|
|
|
result = newJObject()
|
|
|
|
|
result["listenerId"] = %listener.listenerId
|
2025-10-11 17:10:18 +02:00
|
|
|
result["hosts"] = %listener.hosts
|
2025-10-01 15:27:06 +02:00
|
|
|
result["address"] = %listener.address
|
|
|
|
|
result["port"] = %listener.port
|
|
|
|
|
result["protocol"] = %listener.protocol
|
|
|
|
|
|
2025-09-25 19:22:17 +02:00
|
|
|
#[
|
|
|
|
|
Server -> Client
|
|
|
|
|
]#
|
2025-10-01 21:57:26 +02:00
|
|
|
proc sendPublicKey*(client: WsConnection, publicKey: Key) =
|
|
|
|
|
let event = Event(
|
|
|
|
|
eventType: CLIENT_KEY_EXCHANGE,
|
|
|
|
|
timestamp: now().toTime().toUnix(),
|
|
|
|
|
data: %*{
|
|
|
|
|
"publicKey": encode(Bytes.toString(publicKey))
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
if client != nil:
|
|
|
|
|
client.ws.sendEvent(event, client.sessionKey)
|
|
|
|
|
|
2025-11-21 15:55:41 +01:00
|
|
|
proc sendProfile*(client: WsConnection, profileString: string) =
|
2025-09-25 19:22:17 +02:00
|
|
|
let event = Event(
|
|
|
|
|
eventType: CLIENT_PROFILE,
|
|
|
|
|
timestamp: now().toTime().toUnix(),
|
|
|
|
|
data: %*{
|
2025-11-21 15:55:41 +01:00
|
|
|
"profile": profileString
|
2025-09-25 19:22:17 +02:00
|
|
|
}
|
|
|
|
|
)
|
2025-09-26 15:30:14 +02:00
|
|
|
if client != nil:
|
2025-10-01 21:57:26 +02:00
|
|
|
client.ws.sendEvent(event, client.sessionKey)
|
2025-09-25 19:22:17 +02:00
|
|
|
|
2025-10-01 21:57:26 +02:00
|
|
|
proc sendEventlogItem*(client: WsConnection, logType: LogType, message: string) =
|
2025-09-25 19:22:17 +02:00
|
|
|
let event = Event(
|
|
|
|
|
eventType: CLIENT_EVENTLOG_ITEM,
|
|
|
|
|
timestamp: now().toTime().toUnix(),
|
|
|
|
|
data: %*{
|
|
|
|
|
"logType": cast[uint8](logType),
|
|
|
|
|
"message": message
|
|
|
|
|
}
|
|
|
|
|
)
|
2025-10-02 13:51:04 +02:00
|
|
|
|
|
|
|
|
# Log event
|
|
|
|
|
let timestamp = event.timestamp.fromUnix().local().format("dd-MM-yyyy HH:mm:ss")
|
|
|
|
|
log(fmt"[{timestamp}]{$logType}{message}")
|
|
|
|
|
|
2025-09-26 15:30:14 +02:00
|
|
|
if client != nil:
|
2025-10-01 21:57:26 +02:00
|
|
|
client.ws.sendEvent(event, client.sessionKey)
|
2025-09-25 19:22:17 +02:00
|
|
|
|
2025-10-01 21:57:26 +02:00
|
|
|
proc sendAgent*(client: WsConnection, agent: Agent) =
|
2025-09-25 19:22:17 +02:00
|
|
|
let event = Event(
|
|
|
|
|
eventType: CLIENT_AGENT_ADD,
|
|
|
|
|
timestamp: now().toTime().toUnix(),
|
|
|
|
|
data: %agent
|
|
|
|
|
)
|
2025-09-26 15:30:14 +02:00
|
|
|
if client != nil:
|
2025-10-01 21:57:26 +02:00
|
|
|
client.ws.sendEvent(event, client.sessionKey)
|
2025-09-25 19:22:17 +02:00
|
|
|
|
2025-10-01 21:57:26 +02:00
|
|
|
proc sendListener*(client: WsConnection, listener: Listener) =
|
2025-09-25 19:22:17 +02:00
|
|
|
let event = Event(
|
|
|
|
|
eventType: CLIENT_LISTENER_ADD,
|
|
|
|
|
timestamp: now().toTime().toUnix(),
|
|
|
|
|
data: %listener
|
|
|
|
|
)
|
2025-09-26 15:30:14 +02:00
|
|
|
if client != nil:
|
2025-10-01 21:57:26 +02:00
|
|
|
client.ws.sendEvent(event, client.sessionKey)
|
2025-09-25 19:22:17 +02:00
|
|
|
|
2025-10-01 21:57:26 +02:00
|
|
|
proc sendAgentCheckin*(client: WsConnection, agentId: string) =
|
2025-09-25 19:22:17 +02:00
|
|
|
let event = Event(
|
|
|
|
|
eventType: CLIENT_AGENT_CHECKIN,
|
|
|
|
|
timestamp: now().toTime().toUnix(),
|
|
|
|
|
data: %*{
|
|
|
|
|
"agentId": agentId
|
|
|
|
|
}
|
|
|
|
|
)
|
2025-09-26 15:30:14 +02:00
|
|
|
if client != nil:
|
2025-10-01 21:57:26 +02:00
|
|
|
client.ws.sendEvent(event, client.sessionKey)
|
2025-09-25 19:22:17 +02:00
|
|
|
|
2025-10-01 21:57:26 +02:00
|
|
|
proc sendAgentPayload*(client: WsConnection, bytes: seq[byte]) =
|
2025-09-25 19:22:17 +02:00
|
|
|
let event = Event(
|
|
|
|
|
eventType: CLIENT_AGENT_PAYLOAD,
|
|
|
|
|
timestamp: now().toTime().toUnix(),
|
|
|
|
|
data: %*{
|
|
|
|
|
"payload": encode(bytes)
|
|
|
|
|
}
|
|
|
|
|
)
|
2025-10-02 13:51:04 +02:00
|
|
|
|
2025-09-26 15:30:14 +02:00
|
|
|
if client != nil:
|
2025-10-01 21:57:26 +02:00
|
|
|
client.ws.sendEvent(event, client.sessionKey)
|
2025-09-25 19:22:17 +02:00
|
|
|
|
2025-10-01 21:57:26 +02:00
|
|
|
proc sendConsoleItem*(client: WsConnection, agentId: string, logType: LogType, message: string) =
|
2025-09-25 19:22:17 +02:00
|
|
|
let event = Event(
|
|
|
|
|
eventType: CLIENT_CONSOLE_ITEM,
|
|
|
|
|
timestamp: now().toTime().toUnix(),
|
|
|
|
|
data: %*{
|
|
|
|
|
"agentId": agentId,
|
|
|
|
|
"logType": cast[uint8](logType),
|
|
|
|
|
"message": message
|
|
|
|
|
}
|
|
|
|
|
)
|
2025-10-02 13:51:04 +02:00
|
|
|
|
|
|
|
|
# Log agent console item
|
|
|
|
|
let timestamp = event.timestamp.fromUnix().local().format("dd-MM-yyyy HH:mm:ss")
|
|
|
|
|
if logType != LOG_OUTPUT:
|
|
|
|
|
log(fmt"[{timestamp}]{$logType}{message}", agentId)
|
|
|
|
|
else:
|
|
|
|
|
log(message, agentId)
|
|
|
|
|
|
2025-09-26 15:30:14 +02:00
|
|
|
if client != nil:
|
2025-10-01 21:57:26 +02:00
|
|
|
client.ws.sendEvent(event, client.sessionKey)
|
2025-10-02 12:10:46 +02:00
|
|
|
|
|
|
|
|
proc sendBuildlogItem*(client: WsConnection, logType: LogType, message: string) =
|
|
|
|
|
let event = Event(
|
|
|
|
|
eventType: CLIENT_BUILDLOG_ITEM,
|
|
|
|
|
timestamp: now().toTime().toUnix(),
|
|
|
|
|
data: %*{
|
|
|
|
|
"logType": cast[uint8](logType),
|
|
|
|
|
"message": message
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
if client != nil:
|
|
|
|
|
client.ws.sendEvent(event, client.sessionKey)
|
2025-10-09 12:14:38 +02:00
|
|
|
|
|
|
|
|
proc sendLoot*(client: WsConnection, loot: LootItem) =
|
|
|
|
|
let event = Event(
|
|
|
|
|
eventType: CLIENT_LOOT_ADD,
|
|
|
|
|
timestamp: now().toTime().toUnix(),
|
|
|
|
|
data: %loot
|
|
|
|
|
)
|
|
|
|
|
if client != nil:
|
|
|
|
|
client.ws.sendEvent(event, client.sessionKey)
|
2025-10-09 16:25:05 +02:00
|
|
|
|
2025-10-14 22:04:04 +02:00
|
|
|
proc sendLootData*(client: WsConnection, loot: LootItem, data: string) =
|
2025-10-09 16:25:05 +02:00
|
|
|
let event = Event(
|
2025-10-14 22:04:04 +02:00
|
|
|
eventType: CLIENT_LOOT_DATA,
|
2025-10-09 16:25:05 +02:00
|
|
|
timestamp: now().toTime().toUnix(),
|
|
|
|
|
data: %*{
|
2025-10-14 22:04:04 +02:00
|
|
|
"loot": %loot,
|
|
|
|
|
"data": encode(data)
|
2025-10-09 16:25:05 +02:00
|
|
|
}
|
|
|
|
|
)
|
2025-10-17 13:01:12 +02:00
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
)
|
2025-10-09 16:25:05 +02:00
|
|
|
if client != nil:
|
|
|
|
|
client.ws.sendEvent(event, client.sessionKey)
|