Experimented with ImGUI tables for session view.

This commit is contained in:
Jakob Friedl
2025-09-07 17:18:50 +02:00
parent 87059ced4c
commit 2320b705d3
4 changed files with 323 additions and 78 deletions

View File

@@ -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

View File

@@ -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)

View File

@@ -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")

View File

@@ -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()