> For the complete documentation index, see [llms.txt](https://adaptix-framework.gitbook.io/adaptix-framework/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://adaptix-framework.gitbook.io/adaptix-framework/development/extenders/agent-plugin.md).

# Agent plugin

Agent Plugin is responsible for payload generation, data parsing, and command handling.

### Flow Diagram

<figure><img src="/files/P277ckAkHXfoUqHrvevj" alt=""><figcaption></figcaption></figure>

```
┌──────────────────────────────────────────────────────────────────────────────────┐
│                            AGENT PLUGIN FLOW                                     │
├──────────────────────────────────────────────────────────────────────────────────┤
│                                                                                  │
│  ╔════════════════════════════════════════════════════════════════════════════╗  │
│  ║                          AGENT GENERATION                                  ║  │
│  ╚════════════════════════════════════════════════════════════════════════════╝  │
│                                                                                  │
│  GUI ──> WS /channel (agent/generate)                                            │
│                   │                                                              │
│                   V                                                              │
│  ┌─────────────────────────────────────────────────────────────────────────────┐ │
│  │ TEAMSERVER                                                                  │ │
│  │         │                                                                   │ │
│  │         V                                                                   │ │
│  │  TsAgentGenerate(agentType, config)                                         │ │
│  │         │                                                                   │ │
│  │         V                                                                   │ │
│  │  ┌───────────────────────────────────────────────────────────────────────┐  │ │
│  │  │ EXTENDER                                                              │  │ │
│  │  │         │                                                             │  │ │
│  │  │         V                                                             │  │ │
│  │  │  PluginAgent.GenerateProfiles(BuildProfile)                           │  │ │
│  │  │         │                                                             │  │ │
│  │  │         └──> Create profiles for each listener                        │  │ │
│  │  │              return [][]byte (agentProfiles)                          │  │ │
│  │  │                                                                       │  │ │
│  │  │  PluginAgent.BuildPayload(BuildProfile, agentProfiles)                │  │ │
│  │  │         │                                                             │  │ │
│  │  │         ├──> TsAgentBuildExecute() ←── Run build commands             │  │ │
│  │  │         ├──> TsAgentBuildLog()     ←── Build logging                  │  │ │
│  │  │         │                                                             │  │ │
│  │  │         └──> return []byte (payload), filename                        │  │ │
│  │  │                                                                       │  │ │
│  │  └───────────────────────────────────────────────────────────────────────┘  │ │
│  │                                                                             │ │
│  └─────────────────────────────────────────────────────────────────────────────┘ │
│                                                                                  │
│  ╔════════════════════════════════════════════════════════════════════════════╗  │
│  ║                          AGENT REGISTRATION                                ║  │
│  ╚════════════════════════════════════════════════════════════════════════════╝  │
│                                                                                  │
│  Agent ──> Request to Listener (first contact)                                   │
│                   │                                                              │
│                   V                                                              │
│  ┌─────────────────────────────────────────────────────────────────────────────┐ │
│  │ EXTENDER (Listener Plugin)                                                  │ │
│  │         │                                                                   │ │
│  │         V                                                                   │ │
│  │  processRequest(ctx) ──> Parse data                                         │ │
│  │         │                                                                   │ │
│  │         V                                                                   │ │
│  │  ┌───────────────────────────────────────────────────────────────────────┐  │ │
│  │  │ TEAMSERVER                                                            │  │ │
│  │  │         │                                                             │  │ │
│  │  │         V                                                             │  │ │
│  │  │  TsAgentCreate(agentCrc, agentId, data, listenerName, IP, async)      │  │ │
│  │  │         │                                                             │  │ │
│  │  │         V                                                             │  │ │
│  │  │  ┌─────────────────────────────────────────────────────────────────┐  │  │ │
│  │  │  │ EXTENDER (Agent Plugin)                                         │  │  │ │
│  │  │  │         │                                                       │  │  │ │
│  │  │  │         V                                                       │  │  │ │
│  │  │  │  PluginAgent.CreateAgent(data)                                  │  │  │ │
│  │  │  │         │                                                       │  │  │ │
│  │  │  │         ├──> Decrypt data                                       │  │  │ │
│  │  │  │         ├──> Parse agent info (OS, user, computer, etc.)        │  │  │ │
│  │  │  │         │                                                       │  │  │ │
│  │  │  │         └──> return AgentData, ExtenderAgent                    │  │  │ │
│  │  │  │                                                                 │  │  │ │
│  │  │  └─────────────────────────────────────────────────────────────────┘  │  │ │
│  │  │         │                                                             │  │ │
│  │  │         └──> Save to DBMS, broadcast to clients                       │  │ │
│  │  │                                                                       │  │ │
│  │  └───────────────────────────────────────────────────────────────────────┘  │ │
│  │                                                                             │ │
│  └─────────────────────────────────────────────────────────────────────────────┘ │
│                                                                                  │
│  ╔════════════════════════════════════════════════════════════════════════════╗  │
│  ║                          COMMAND EXECUTION                                 ║  │
│  ╚════════════════════════════════════════════════════════════════════════════╝  │
│                                                                                  │
│  GUI ──> POST /agent/command/execute                                             │
│                   │                                                              │
│                   V                                                              │
│  ┌─────────────────────────────────────────────────────────────────────────────┐ │
│  │ TEAMSERVER                                                                  │ │
│  │         │                                                                   │ │
│  │         V                                                                   │ │
│  │  TsTaskCreate(agentId, command, args)                                       │ │
│  │         │                                                                   │ │
│  │         V                                                                   │ │
│  │  ┌───────────────────────────────────────────────────────────────────────┐  │ │
│  │  │ EXTENDER                                                              │  │ │
│  │  │         │                                                             │  │ │
│  │  │         V                                                             │  │ │
│  │  │  ExtenderAgent.CreateCommand(agentData, args)                         │  │ │
│  │  │         │                                                             │  │ │
│  │  │         ├──> Parse command and arguments                              │  │ │
│  │  │         ├──> Create TaskData with packed command                      │  │ │
│  │  │         │                                                             │  │ │
│  │  │         └──> return TaskData, ConsoleMessageData                      │  │ │
│  │  │                                                                       │  │ │
│  │  └───────────────────────────────────────────────────────────────────────┘  │ │
│  │         │                                                                   │ │
│  │         └──> Add to agent queue, broadcast to clients                       │ │
│  │                                                                             │ │
│  └─────────────────────────────────────────────────────────────────────────────┘ │
│                                                                                  │
│  ╔════════════════════════════════════════════════════════════════════════════╗  │
│  ║                          DATA PROCESSING (Agent → Server)                  ║  │
│  ╚════════════════════════════════════════════════════════════════════════════╝  │
│                                                                                  │
│  Agent ──> Request to Listener (with results)                                    │
│                   │                                                              │
│                   V                                                              │
│  ┌─────────────────────────────────────────────────────────────────────────────┐ │
│  │ EXTENDER (Listener Plugin)                                                  │ │
│  │         │                                                                   │ │
│  │         V                                                                   │ │
│  │  processRequest(ctx) ──> Parse body data                                    │ │
│  │         │                                                                   │ │
│  │         V                                                                   │ │
│  │  ┌───────────────────────────────────────────────────────────────────────┐  │ │
│  │  │ TEAMSERVER                                                            │  │ │
│  │  │         │                                                             │  │ │
│  │  │         V                                                             │  │ │
│  │  │  TsAgentProcessData(agentId, bodyData)                                │  │ │
│  │  │         │                                                             │  │ │
│  │  │         V                                                             │  │ │
│  │  │  ┌─────────────────────────────────────────────────────────────────┐  │  │ │
│  │  │  │ EXTENDER (Agent Plugin)                                         │  │  │ │
│  │  │  │         │                                                       │  │  │ │
│  │  │  │         V                                                       │  │  │ │
│  │  │  │  ExtenderAgent.Decrypt() + ProcessTasksResult()                 │  │  │ │
│  │  │  │         │                                                       │  │  │ │
│  │  │  │         ├──> case COMMAND_OUTPUT: TsTaskUpdate                  │  │  │ │
│  │  │  │         ├──> case COMMAND_DOWNLOAD: TsDownloadAdd/Update/Close  │  │  │ │
│  │  │  │         ├──> case COMMAND_SCREENSHOT: TsScreenshotAdd           │  │  │ │
│  │  │  │         ├──> case COMMAND_LINK: TsPivotCreate                   │  │  │ │
│  │  │  │         ├──> case COMMAND_TUNNEL_*: TsTunnelConnection*         │  │  │ │
│  │  │  │         └──> ... other commands                                 │  │  │ │
│  │  │  │                                                                 │  │  │ │
│  │  │  └─────────────────────────────────────────────────────────────────┘  │  │ │
│  │  │                                                                       │  │ │
│  │  └───────────────────────────────────────────────────────────────────────┘  │ │
│  │                                                                             │ │
│  └─────────────────────────────────────────────────────────────────────────────┘ │
│                                                                                  │
└──────────────────────────────────────────────────────────────────────────────────┘
```

### Agent Config (config.yaml)

```yaml
extender_type: "agent"
extender_file: "agent.so"
ax_file: "ax_config.axs"

agent_name: "AGENT_NAME"
agent_watermark: "deadbeef"
listeners:
  - "LISTENER_NAME_1"
  - "LISTENER_NAME_2"
# - ....
multi_listeners: false
```

### PluginAgent Interface

```go
type PluginAgent interface {
    // Get ExtenderAgent
    GetExtender() ExtenderAgent
    
    // Generate profiles for listeners
    GenerateProfiles(profile BuildProfile) ([][]byte, error)
    
    // Build agent payload
    BuildPayload(profile BuildProfile, agentProfiles [][]byte) ([]byte, string, error)
    
    // Create agent from beat data
    CreateAgent(beat []byte) (AgentData, ExtenderAgent, error)
}

// ExtenderAgent - interface for working with agent
type ExtenderAgent interface {
    // Encrypt data
    Encrypt(data []byte, key []byte) ([]byte, error)
    
    // Decrypt data
    Decrypt(data []byte, key []byte) ([]byte, error)
    
    // Pack tasks for sending to agent
    PackTasks(agentData AgentData, tasks []TaskData) ([]byte, error)
    
    // Pack data for pivot agent
    PivotPackData(pivotId string, data []byte) (TaskData, error)
    
    // Create task from command
    CreateCommand(agentData AgentData, args map[string]any) (TaskData, ConsoleMessageData, error)
    
    // Callbacks for tunnels
    TunnelCallbacks() TunnelCallbacks
    
    // Callbacks for terminal
    TerminalCallbacks() TerminalCallbacks
}

// TunnelCallbacks - functions for tunnel management
type TunnelCallbacks struct {
    ConnectTCP func(channelId, tunnelType, addressType int, address string, port int) TaskData
    ConnectUDP func(channelId, tunnelType, addressType int, address string, port int) TaskData
    WriteTCP   func(channelId int, data []byte) TaskData
    WriteUDP   func(channelId int, data []byte) TaskData
    Close      func(channelId int) TaskData
    Reverse    func(tunnelId, port int) TaskData
}

// TerminalCallbacks - functions for terminal management
type TerminalCallbacks struct {
    Start func(terminalId int, program string, sizeH, sizeW int, oemCP int) TaskData
    Write func(terminalId int, oemCP int, data []byte) TaskData
    Close func(terminalId int) TaskData
}
```

### AxScript for Agent (ax\_config.axs)

The `.axs` file defines agent commands, context menus, and UI for payload generation.

**Required functions:**

```javascript
// 1. Register agent commands (called when plugin loads)
function RegisterCommands(listenerType) {
    // listenerType: "BeaconHTTP", "BeaconDNS", "BeaconSMB", "BeaconTCP", etc.
    
    // Create command
    let cmd_ls = ax.create_command("ls", "List files", "ls /tmp", "Task: list files");
    cmd_ls.addArgString("path", false, ".");  // name, required, default
    
    let cmd_cd = ax.create_command("cd", "Change directory", "cd /tmp", "Task: change dir");
    cmd_cd.addArgString("path", true);
    
    // Command with subcommands
    let cmd_ps_list = ax.create_command("list", "Show processes", "ps list");
    let cmd_ps_kill = ax.create_command("kill", "Kill process", "ps kill 1234");
    cmd_ps_kill.addArgInt("pid", true);
    let cmd_ps = ax.create_command("ps", "Process manager");
    cmd_ps.addSubCommands([cmd_ps_list, cmd_ps_kill]);
    
    // Alias with pre-hook
    let cmd_shell = ax.create_command("shell", "Execute via cmd.exe", "shell whoami");
    cmd_shell.addArgString("cmd", true);
    cmd_shell.setPreHook(function(id, cmdline, parsed_json) {
        ax.execute_alias(id, cmdline, "ps run -o cmd.exe /c " + parsed_json["cmd"]);
    });
    
    // Commands group
    let commands = ax.create_commands_group("beacon", [cmd_ls, cmd_cd, cmd_ps, cmd_shell]);
    
    return { 
        commands_windows: commands,  // Commands for Windows
        // commands_linux: commands, // Commands for Linux (optional)
    }
}

// 2. UI for payload generation (called when generation dialog opens)
function GenerateUI(listeners_type) {
    // listeners_type: array of selected listener types
    
    let labelArch = form.create_label("Arch:");
    let comboArch = form.create_combo();
    comboArch.addItems(["x64", "x86"]);
    
    let labelFormat = form.create_label("Format:");
    let comboFormat = form.create_combo();
    comboFormat.addItems(["Exe", "DLL", "Shellcode"]);
    
    let layout = form.create_gridlayout();
    layout.addWidget(labelArch, 0, 0);
    layout.addWidget(comboArch, 0, 1);
    layout.addWidget(labelFormat, 1, 0);
    layout.addWidget(comboFormat, 1, 1);
    
    let container = form.create_container();
    container.put("arch", comboArch);
    container.put("format", comboFormat);
    
    let panel = form.create_panel();
    panel.setLayout(layout);
    
    return {
        ui_panel: panel,
        ui_container: container,
        ui_height: 300,
        ui_width: 400
    }
}
```

**Optional elements:**

```javascript
// Context menus for agent sessions
let exit_action = menu.create_action("Terminate", function(agents) {
    agents.forEach(a => ax.execute_command(a, "terminate process"));
});
menu.add_session_agent(exit_action, ["beacon"]);  // For agents of type "beacon"

// Context menus for File Browser
let download_action = menu.create_action("Download", function(files) {
    files.forEach(f => ax.execute_command(f.agent_id, "download " + f.path + f.name));
});
menu.add_filebrowser(download_action, ["beacon"]);

// Browser event handlers
event.on_filebrowser_disks(function(id) {
    ax.execute_browser(id, "disks");
}, ["beacon"]);

event.on_filebrowser_list(function(id, path) {
    ax.execute_browser(id, "ls " + path);
}, ["beacon"]);

event.on_processbrowser_list(function(id) {
    ax.execute_browser(id, "ps list");
}, ["beacon"]);
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://adaptix-framework.gitbook.io/adaptix-framework/development/extenders/agent-plugin.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
