From 2320b705d3af7636695cfb26677391b43037c518 Mon Sep 17 00:00:00 2001 From: Jakob Friedl <71284620+jakobfriedl@users.noreply.github.com> Date: Sun, 7 Sep 2025 17:18:50 +0200 Subject: [PATCH] Experimented with ImGUI tables for session view. --- src/client/layout.ini | 216 ++++++++++++++++++++++++++++++++-- src/client/main.nim | 14 +-- src/client/views/agents.nim | 59 ---------- src/client/views/sessions.nim | 112 ++++++++++++++++++ 4 files changed, 323 insertions(+), 78 deletions(-) delete mode 100644 src/client/views/agents.nim create mode 100644 src/client/views/sessions.nim diff --git a/src/client/layout.ini b/src/client/layout.ini index 0effc56..d10c141 100644 --- a/src/client/layout.ini +++ b/src/client/layout.ini @@ -4,31 +4,31 @@ Size=1908,999 Collapsed=0 [Window][Debug##Default] -Pos=60,60 -Size=400,400 +Pos=289,253 +Size=449,261 Collapsed=0 [Window][Dear ImGui Demo] Pos=10,43 -Size=1187,946 +Size=1453,946 Collapsed=0 -DockId=0x00000003,1 +DockId=0x00000001,1 [Window][Agents [Table View]] Pos=10,43 Size=1187,946 Collapsed=0 -DockId=0x00000003,0 +DockId=0x00000001,0 [Window][Agents [Graph View]] Pos=10,43 Size=1888,473 Collapsed=0 -DockId=0x00000003,1 +DockId=0x00000001,1 [Window][Eventlog] -Pos=1199,43 -Size=699,946 +Pos=1465,43 +Size=433,946 Collapsed=0 DockId=0x00000004,0 @@ -57,12 +57,204 @@ Pos=60,60 Size=564,669 Collapsed=0 +[Window][Sessions [Table View]] +Pos=10,43 +Size=1453,946 +Collapsed=0 +DockId=0x00000001,0 + +[Window][Dear ImGui Demo/ResizableChild_478B81A3] +IsChild=1 +Size=1136,248 + +[Window][Dear ImGui Demo/Red_BEEF922B] +IsChild=1 +Size=200,100 + +[Window][Dear ImGui Demo/##Basket_956142B6] +IsChild=1 +Size=1115,540 + +[Window][Dear ImGui Demo/##Basket_8B4CCC3E] +IsChild=1 +Size=1115,540 + +[Window][Dear ImGui Demo/##Basket_10C9C799] +IsChild=1 +Size=1115,540 + +[Window][Dear ImGui Demo/##Tree_EC99B1DE] +IsChild=1 +Size=1115,540 + +[Window][Sessions [Graph View]] +Pos=10,518 +Size=1453,471 +Collapsed=0 +DockId=0x00000002,0 + [Table][0xB6880529,2] RefScale=27 Column 0 Sort=0v -[Docking][Data] -DockSpace ID=0x85940918 Window=0x260A4489 Pos=10,43 Size=1888,946 Split=X - DockNode ID=0x00000003 Parent=0x85940918 SizeRef=1187,473 CentralNode=1 Selected=0x5E5F7166 - DockNode ID=0x00000004 Parent=0x85940918 SizeRef=699,473 Selected=0x0FA43D88 +[Table][0x951FCC8A,6] +RefScale=27 +Column 0 Width=48 +Column 1 Width=72 Sort=0v +Column 2 Width=108 +Column 3 Weight=0.5480 +Column 4 Weight=1.0000 +Column 5 Weight=-1.0000 + +[Table][0x32886A44,8] +Column 0 Weight=0.7758 +Column 1 Weight=1.1556 +Column 2 Weight=0.7758 +Column 3 Weight=0.9616 +Column 4 Weight=0.9616 +Column 5 Weight=1.1556 +Column 6 Weight=0.3879 +Column 7 Weight=1.8263 + +[Table][0x51D6F5EA,3] +Column 0 Weight=1.0000 +Column 1 Weight=1.0000 +Column 2 Weight=1.0000 + +[Table][0xE102187A,3] +RefScale=27 +Column 0 Width=134 +Column 1 Width=108 +Column 2 Width=108 + +[Table][0xF1421304,3] +RefScale=27 +Column 0 Width=108 +Column 1 Width=108 +Column 2 Weight=1.0000 + +[Table][0xE212E0F0,6] +RefScale=27 +Column 0 Width=108 +Column 1 Width=108 +Column 2 Width=-1 +Column 3 Weight=1.0000 +Column 4 Weight=1.0000 +Column 5 Weight=-1.0000 + +[Table][0x86C9FC97,3] +Column 0 Weight=0.6856 +Column 1 Weight=0.7387 +Column 2 Weight=1.5757 + +[Table][0x95990F63,3] +RefScale=27 +Column 0 Width=108 +Column 1 Width=108 +Column 2 Width=108 + +[Table][0xEB78AB2C,3] +Column 0 Weight=1.0000 +Column 1 Weight=1.0000 +Column 2 Weight=1.0000 + +[Table][0x603C335E,2] +Column 0 Weight=1.0000 +Column 1 Weight=1.0000 + +[Table][0xA6C6558A,2] +Column 0 Weight=1.0000 +Column 1 Weight=1.0000 + +[Table][0xAED4F161,3] +RefScale=27 +Column 0 Width=191 Visible=1 +Column 1 Width=108 Visible=1 Sort=0v +Column 2 Width=-1 Visible=0 + +[Table][0x3A20F3F3,3] +RefScale=27 +Column 0 Width=96 +Column 1 Width=96 +Column 2 Width=96 + +[Table][0x29CD9FF7,3] + +[Table][0x302651AD,14] +RefScale=27 +Column 0 Width=96 Sort=0v +Column 1 Width=33 +Column 2 Width=33 +Column 3 Width=33 +Column 4 Width=33 +Column 5 Width=33 +Column 6 Width=33 +Column 7 Width=33 +Column 8 Width=33 +Column 9 Width=33 +Column 10 Width=33 +Column 11 Width=33 +Column 12 Width=33 +Column 13 Width=33 + +[Table][0x369EB90F,3] +Column 0 Weight=1.0000 +Column 1 Weight=1.0000 +Column 2 Weight=1.0000 + +[Table][0x2ACCE68A,3] +RefScale=27 +Column 0 Width=136 +Column 1 Width=136 +Column 2 Width=136 + +[Table][0x6655AF53,4] +RefScale=27 +Column 0 Width=48 +Column 1 Width=72 Sort=0^ +Column 2 Width=72 +Column 3 Weight=1.0000 + +[Table][0x5145577A,3] +Column 0 Weight=1.0000 +Column 1 Weight=1.0000 +Column 2 Weight=1.0000 + +[Table][0x127BEAD2,7] +RefScale=27 +Column 0 Width=84 +Column 1 Width=167 +Column 2 Width=191 +Column 3 Width=191 +Column 4 Width=191 +Column 5 Width=191 +Column 6 Width=191 + +[Table][0x755BE644,3] +RefScale=27 +Column 0 Width=84 +Column 1 Width=83 +Column 2 Width=84 + +[Table][0xBE0D9DE1,3] +Column 0 Weight=1.0000 +Column 1 Weight=1.0000 +Column 2 Weight=1.0000 + +[Table][0xDE11CCC7,8] +Column 0 Weight=0.7758 +Column 1 Weight=1.1556 +Column 2 Weight=0.7758 +Column 3 Weight=0.9616 +Column 4 Weight=0.9616 +Column 5 Weight=1.1556 +Column 6 Weight=0.3879 +Column 7 Weight=1.8263 + +[Docking][Data] +DockSpace ID=0x85940918 Window=0x260A4489 Pos=10,43 Size=1888,946 Split=X + DockNode ID=0x00000003 Parent=0x85940918 SizeRef=1453,473 Split=Y Selected=0x61E02D75 + DockNode ID=0x00000001 Parent=0x00000003 SizeRef=1453,473 CentralNode=1 Selected=0x61E02D75 + DockNode ID=0x00000002 Parent=0x00000003 SizeRef=1453,471 Selected=0x6D7E7D39 + DockNode ID=0x00000004 Parent=0x85940918 SizeRef=433,473 Selected=0x0FA43D88 diff --git a/src/client/main.nim b/src/client/main.nim index 124f792..1e31195 100644 --- a/src/client/main.nim +++ b/src/client/main.nim @@ -1,6 +1,6 @@ import tables import ./utils/appImGui -import ./views/[dockspace, agents, listeners, eventlog] +import ./views/[dockspace, sessions, listeners, eventlog] proc main() = var app = createApp(1024, 800, imnodes = true, title = "Conquest", docking = true) @@ -9,13 +9,13 @@ proc main() = var views: Table[string, ptr bool] showConquest = true - showAgentsTable = true - showAgentsGraph = false + showSessionsTable = true + showSessionsGraph = false showListeners = false showEventlog = true - views["Agents [Table View]"] = addr showAgentsTable - views["Agents [Graph View]"] = addr showAgentsGraph + views["Sessions [Table View]"] = addr showSessionsTable + views["Sessions [Graph View]"] = addr showSessionsGraph views["Listeners"] = addr showListeners views["Eventlog"] = addr showEventlog @@ -33,8 +33,8 @@ proc main() = # UI components/views Dockspace().draw(addr showConquest, views) - if showAgentsTable: AgentsTable("Agents [Table View]").draw(addr showAgentsTable) - if showAgentsGraph: AgentsTable("Agents [Graph View]").draw(addr showAgentsGraph) + if showSessionsTable: SessionsTable("Sessions [Table View]").draw(addr showSessionsTable) + if showSessionsGraph: SessionsTable("Sessions [Graph View]").draw(addr showSessionsGraph) if showListeners: ListenersTable("Listeners").draw(addr showListeners) if showEventlog:Eventlog("Eventlog").draw(addr showEventlog) diff --git a/src/client/views/agents.nim b/src/client/views/agents.nim deleted file mode 100644 index aeac8ec..0000000 --- a/src/client/views/agents.nim +++ /dev/null @@ -1,59 +0,0 @@ -import times -import imguin/[cimgui, glfw_opengl, simple] -import ../utils/appImGui -import ../../common/[types] - -type - AgentsTableComponent = ref object of RootObj - title: string - agents: seq[Agent] - - -let exampleAgents: seq[Agent] = @[ - Agent( - agentId: "DEADBEEF", - listenerId: "L1234567", - username: "alice", - hostname: "DESKTOP-01", - domain: "CORP", - ip: "192.168.1.10", - os: "Windows 10", - process: "explorer.exe", - pid: 2340, - elevated: true, - sleep: 60, - tasks: @[], - firstCheckin: now() - initDuration(hours = 2), - latestCheckin: now(), - sessionKey: [byte 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31] - ), - Agent( - agentId: "FACEDEAD", - listenerId: "L7654321", - username: "bob", - hostname: "LAPTOP-02", - domain: "SALES", - ip: "10.0.0.5", - os: "Windows 11", - process: "cmd.exe", - pid: 4567, - elevated: false, - sleep: 120, - tasks: @[], - firstCheckin: now() - initDuration(hours = 1, minutes = 30), - latestCheckin: now() - initDuration(minutes = 5), - sessionKey: [byte 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] - ) -] - -proc AgentsTable*(title: string): AgentsTableComponent = - result = new AgentsTableComponent - result.title = title - result.agents = exampleAgents - -proc draw*(component: AgentsTableComponent, showComponent: ptr bool) = - igSetNextWindowSize(vec2(800, 600), ImGuiCond_Once.int32) - igBegin(component.title, showComponent, 0) - defer: igEnd() - - igText("asd") diff --git a/src/client/views/sessions.nim b/src/client/views/sessions.nim new file mode 100644 index 0000000..df49a06 --- /dev/null +++ b/src/client/views/sessions.nim @@ -0,0 +1,112 @@ +import times +import imguin/[cimgui, glfw_opengl, simple] +import ../utils/appImGui +import ../../common/[types] + +type + SessionsTableComponent = ref object of RootObj + title: string + agents: seq[Agent] + + +let exampleAgents: seq[Agent] = @[ + Agent( + agentId: "DEADBEEF", + listenerId: "L1234567", + username: "alice", + hostname: "DESKTOP-01", + domain: "CORP", + ip: "192.168.1.10", + os: "Windows 10", + process: "explorer.exe", + pid: 2340, + elevated: true, + sleep: 60, + tasks: @[], + firstCheckin: now() - initDuration(hours = 2), + latestCheckin: now(), + sessionKey: [byte 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31] + ), + Agent( + agentId: "FACEDEAD", + listenerId: "L7654321", + username: "bob", + hostname: "LAPTOP-02", + domain: "SALES", + ip: "10.0.0.5", + os: "Windows 11", + process: "cmd.exe", + pid: 4567, + elevated: false, + sleep: 120, + tasks: @[], + firstCheckin: now() - initDuration(hours = 1, minutes = 30), + latestCheckin: now() - initDuration(minutes = 5), + sessionKey: [byte 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] + ) +] + +proc SessionsTable*(title: string): SessionsTableComponent = + result = new SessionsTableComponent + result.title = title + result.agents = exampleAgents + +proc draw*(component: SessionsTableComponent, showComponent: ptr bool) = + igSetNextWindowSize(vec2(800, 600), ImGuiCond_Once.int32) + + igBegin(component.title, showComponent, 0) + defer: igEnd() + + let tableFlags = ( + ImGuiTableFlags_Resizable.int32 or + ImGuiTableFlags_Reorderable.int32 or + ImGuiTableFlags_Hideable.int32 or + ImGuiTableFlags_HighlightHoveredColumn.int32 or + ImGuiTableFlags_ContextMenuInBody.int32 or + ImGuiTableFlags_RowBg.int32 or + ImGuiTableFlags_BordersV.int32 or + ImGuiTableFlags_BordersH.int32 or + ImGuiTableFlags_ScrollY.int32 or + ImGuiTableFlags_ScrollX.int32 or + ImGuiTableFlags_NoBordersInBodyUntilResize.int32 or + ImGui_TableFlags_SizingStretchProp.int32 + ) + + let cols: int32 = 8 + if igBeginTable("Sessions", cols, tableFlags, vec2(0.0f, 0.0f), 0.0f): + + igTableSetupColumn("AgentID", ImGuiTableColumnFlags_NoReorder.int32 or ImGuiTableColumnFlags_NoHide.int32, 0.0f, 0) + igTableSetupColumn("Address", ImGuiTableColumnFlags_None.int32, 0.0f, 0) + igTableSetupColumn("Username", ImGuiTableColumnFlags_None.int32, 0.0f, 0) + igTableSetupColumn("Hostname", 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) + igTableSetupColumn("Activity", ImGuiTableColumnFlags_None.int32, 0.0f, 0) + + igTableSetupScrollFreeze(0, 1) + igTableHeadersRow() + + for row in 0..< component.agents.len(): + igTableNextRow(ImGuiTableRowFlags_None.int32, 0.0f) + let agent = component.agents[row] + if igTableSetColumnIndex(0): + igText(agent.agentId) + if igTableSetColumnIndex(1): + igText(agent.ip) + if igTableSetColumnIndex(2): + igText(agent.username) + if igTableSetColumnIndex(3): + igText(agent.hostname) + if igTableSetColumnIndex(4): + igText(agent.os) + if igTableSetColumnIndex(5): + igText(agent.process) + if igTableSetColumnIndex(6): + igText($agent.pid) + if igTableSetColumnIndex(7): + igText(agent.latestCheckin.format("yyyy-MM-dd HH:mm:ss")) + + igEndTable() + + \ No newline at end of file