Listener extender
Flow Diagram

Listener Config (config.yaml)
PluginListener Interface
AxScript for Listener (ax_config.axs)
Last updated

Last updated
┌──────────────────────────────────────────────────────────────────────────────────┐
│ EXTERNAL LISTENER FLOW │
├──────────────────────────────────────────────────────────────────────────────────┤
│ │
│ ╔════════════════════════════════════════════════════════════════════════════╗ │
│ ║ CREATE LISTENER ║ │
│ ╚════════════════════════════════════════════════════════════════════════════╝ │
│ │
│ GUI ──> POST /listener/create │
│ │ │
│ V │
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
│ │ TEAMSERVER │ │
│ │ │ │ │
│ │ V │ │
│ │ TsListenerCreate(listenerType, name, config) │ │
│ │ │ │ │
│ │ V │ │
│ │ ┌───────────────────────────────────────────────────────────────────────┐ │ │
│ │ │ EXTENDER │ │ │
│ │ │ │ │ │ │
│ │ │ V │ │ │
│ │ │ PluginListener.Create(name, config, customData) │ │ │
│ │ │ │ │ │ │
│ │ │ ├──> Configuration validation │ │ │
│ │ │ └──> return ExtenderListener, ListenerData, customData │ │ │
│ │ │ │ │ │
│ │ └───────────────────────────────────────────────────────────────────────┘ │ │
│ │ │ │ │
│ │ └──> Save to DBMS, broadcast to clients │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────────────────┘ │
│ │
│ ╔════════════════════════════════════════════════════════════════════════════╗ │
│ ║ START LISTENER ║ │
│ ╚════════════════════════════════════════════════════════════════════════════╝ │
│ │
│ (automatically after Create) │
│ │ │
│ V │
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
│ │ TEAMSERVER │ │
│ │ │ │ │
│ │ V │ │
│ │ TsListenerStart(listenerName) │ │
│ │ │ │ │
│ │ V │ │
│ │ ┌───────────────────────────────────────────────────────────────────────┐ │ │
│ │ │ EXTENDER │ │ │
│ │ │ │ │ │ │
│ │ │ V │ │ │
│ │ │ ExtenderListener.Start() │ │ │
│ │ │ │ │ │ │
│ │ │ └──> Start HTTP/DNS server │ │ │
│ │ │ │ │ │
│ │ └───────────────────────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────────────────┘ │
│ │
│ ╔════════════════════════════════════════════════════════════════════════════╗ │
│ ║ AGENT CONNECTION ║ │
│ ╚════════════════════════════════════════════════════════════════════════════╝ │
│ │
│ Agent ──> [HTTP] Request to Listener │
│ │ │
│ V │
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
│ │ EXTENDER ([HTTP] Handler) │ │
│ │ │ │ │
│ │ V │ │
│ │ [processRequest(ctx)] │ │
│ │ │ │ │
│ │ ├──> Extract AgentID and data │ │
│ │ │ │ │
│ │ V │ │
│ │ ┌───────────────────────────────────────────────────────────────────────┐ │ │
│ │ │ TEAMSERVER API calls │ │ │
│ │ │ │ │ │ │
│ │ │ ├──> if !TsAgentIsExists(agentId): │ │ │
│ │ │ │ TsAgentCreate(agentCrc, agentId, data, listener, IP) │ │ │
│ │ │ │ │ │ │
│ │ │ ├──> TsAgentSetTick(agentId, listener) - last tick update │ │ │
│ │ │ │ │ │ │
│ │ │ ├──> TsAgentProcessData(agentId, bodyData) - process data │ │ │
│ │ │ │ │ │ │
│ │ │ └──> TsAgentGetHostedAll(agentId, maxSize) - send tasks │ │ │
│ │ │ │ │ │
│ │ └───────────────────────────────────────────────────────────────────────┘ │ │
│ │ │ │ │
│ │ └──> return [HTTP] response to agent │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────────────────┘ │
│ │
│ ╔════════════════════════════════════════════════════════════════════════════╗ │
│ ║ STOP LISTENER ║ │
│ ╚════════════════════════════════════════════════════════════════════════════╝ │
│ │
│ GUI ──> POST /listener/stop │
│ │ │
│ V │
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
│ │ TEAMSERVER │ │
│ │ │ │ │
│ │ V │ │
│ │ TsListenerStop(listenerName) │ │
│ │ │ │ │
│ │ V │ │
│ │ ┌───────────────────────────────────────────────────────────────────────┐ │ │
│ │ │ EXTENDER │ │ │
│ │ │ │ │ │ │
│ │ │ V │ │ │
│ │ │ ExtenderListener.Stop() │ │ │
│ │ │ │ │ │ │
│ │ │ └──> Stop server, cleanup resources │ │ │
│ │ │ │ │ │
│ │ └───────────────────────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────────────────┘ │
│ │
└──────────────────────────────────────────────────────────────────────────────────┘extender_type: "listener"
extender_file: "listener.so"
ax_file: "ax_config.axs"
listener_name: "LISTENER_NAME"
listener_type: "external" # or "internal"
protocol: "protocol here"type PluginListener interface {
// Create listener
Create(name string, config string, customData []byte) (ExtenderListener, ListenerData, []byte, error)
}
// ExtenderListener - active listener interface
type ExtenderListener interface {
// Start listener
Start() error
// Edit configuration
Edit(config string) (ListenerData, []byte, error)
// Stop listener
Stop() error
// Get profile for agent generation
GetProfile() ([]byte, error)
// Handle pivot connections (for internal listener)
InternalHandler(data []byte) (string, error)
}function ListenerUI(mode_create) {
// mode_create: true = create, false = edit
// Create UI elements
let labelHost = form.create_label("Host:");
let comboHost = form.create_combo();
comboHost.setEnabled(mode_create); // Non-editable fields when editing
let spinPort = form.create_spin();
spinPort.setRange(1, 65535);
spinPort.setValue(443);
// Layout
let layout = form.create_gridlayout();
layout.addWidget(labelHost, 0, 0, 1, 1);
layout.addWidget(comboHost, 0, 1, 1, 1);
// Container for retrieving values
let container = form.create_container();
container.put("host_bind", comboHost);
container.put("port_bind", spinPort);
let panel = form.create_panel();
panel.setLayout(layout);
// Required return
return {
ui_panel: panel, // Panel with UI
ui_container: container, // Container for retrieving values
ui_height: 400, // Dialog height
ui_width: 500 // Dialog width
}
}