Skip to main content
  1. Documentation/
  2. Plugins/

Plugin Architecture

Table of Contents
TantoC2’s entire feature set is built on a unified plugin architecture.

How Plugins Work
#

TantoC2 uses a generic PluginRegistry class that discovers plugins from designated directories. All plugin types share the same discovery mechanism:

  1. Scan .py files in the plugin directory (excluding _-prefixed files)
  2. Import each file
  3. Find all concrete subclasses of the base class
  4. Register by plugin_name()

No code changes to the core system are required to add new plugins.

Plugin Base Class
#

Every plugin extends PluginBase:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
from tantoc2.server.plugins import PluginBase

class PluginBase(ABC):
    @classmethod
    @abstractmethod
    def plugin_name(cls) -> str:
        """Unique name for this plugin."""

    @classmethod
    @abstractmethod
    def plugin_type(cls) -> str:
        """Type of plugin (e.g., 'transport', 'module', 'agentless')."""

Plugin Types
#

TypeBase Class / FormatDirectoryDescription
TransportTransportBaseplugins/transports/Listener implementations
Tools ModuleAgentlessModuleBaseplugins/agentless/Direct service interaction (SSH, SMB, etc.) from the teamserver
Agent PackageAgentPackageBaseplugins/agent_packages/Crypto, codec, build pipeline, and capability declarations
Agent ModuleYAML manifest + compiled payloadagent_modules/Compiled payloads loadable by agents (BOF, shellcode, DLL, etc.)

Hot-Reload
#

Drop a .py file into the appropriate directory and trigger a refresh:

CLI:

1
2
tantoc2> modules refresh
tantoc2> tools refresh

API:

1
2
POST /api/v1/agentless/modules/refresh
POST /api/v1/agent-modules/refresh

No server restart required.

Plugin Inbox
#

For easy deployment, drop files into the plugin inbox directory (plugin_inbox_dir config). The plugin watcher automatically handles them:

  • .py files: Auto-detected by type and moved to the correct plugin directory
  • .whl files: Installed via pip, then registered through entry points

The inbox is checked every bg_plugin_watcher_interval seconds (default: 30).

Dependency Auto-Install
#

Modules can declare pip dependencies in their metadata via dependencies: list[str]. Missing packages are auto-installed at discovery time. If installation fails, the module is tracked as unavailable with a reason — queryable via the unavailable_modules property on the module manager.

Deployment
#

Place your plugin file in the correct directory:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
plugins/
  transports/
    my_transport.py
  agentless/
    my_agentless.py
  agent_packages/
    my_agent.py
modules/
  my_module.py
agent_modules/
  bof/
    windows/
      my_module/
        manifest.yaml
        payload.o

Or drop into the plugin inbox for automatic routing.

The plugin is discovered on the next server start, refresh, or inbox scan.

Next Steps
#