The elements of Zuthaka are instances over implemented abstract classes that define the general behavior of a C2.
Class Handlers
Class handlers are the core of every new Zuthaka integration. These represent the base functionality and contract given by the integration. The attributes defined in the class handler frame the representation exposed in the web interface and the functions implemented in the class shape the service behavior.
Implementing C2 Type Class handler connections:
The handlers should only provide the basic C2 interaction while managing consistency. Error tracking tasks are done by Zuthaka's service.
Attributes and Options Descriptions
The attributes "name", "description", "documentation", and a list of "registered_options" is mandatory for the correct function of Zuthaka. This helps guide the user through the steps necessary to use the specific implementation.
template.py
from..c2 import C2, Listener, ListenerType, Launcher, LauncherType, Options, OptionDescclassTemplateC2Type(C2):# all this information is given to the user when using the interface name ='template_c2' description ='this is an example C2' documentation ='https://super.awesome.c2/docs/' registered_options = [ OptionDesc( name='url', description='Url of the corresponding API', example='https://127.0.0.1:31337', field_type='string', required=True ),OptionDesc( name='username', description='user owner of the API', example='pucara', field_type='string', required=True ),OptionDesc( name='password', description='Url of the corresponding API', example='p4ssw0rd', field_type='string', required=True ), ] ...
The descriptions of the integration helps to populate the user interface, for a guided experience.
Behavior Abstract Methods
The behavior is defined through the implementation of abstract methods with an specific "contract".
health check method: is_alive
...asyncdefis_alive(self) ->bool:""" This method is used to collect latency from C2, and validate connection before perisisting the data to Zuthaka's DB. raises ConectionError in case of not be able to connect to c2 instance raises ConnectionRefusedError in case of not be able to authenticate """pass...
A good practice to implement "is_alive" is to query the API for a given response. For REST APIs, generating a token is a good way to guarantee the C2 is processing the requests given through the handler.
Implementing Listener Type Class
The Listeners are the services awaiting for connections from different Agents and generally delivering the instructions to be executed by them.
Listener Types are integrated with a similar logic that responds to the C2 API to handle Listeners.
Attributes and Options Descriptions
....classTemplateListenerType(ListenerType): name ='http' description ='standard http listener, messages are delivered in enconded comment' registered_options = [OptionDesc( name='useSSL', description='ssl enabled communication between agent and listener', example='false', field_type='string', required=True ),OptionDesc( name='bindAdress', description='interfaces to which the listener is bind', example='0.0.0.0', field_type='string', required=True ),OptionDesc( name='connectAddresses', description='address to which the agent is going to try to connect', example='192.168.0.14', field_type='string', required=True ),OptionDesc( name='connectPort', description='port to which the agent is going to try to connect', example=80, field_type='integer', required=True ), ]...
Behavior Abstract Methods
Listeners must be able to be created and destroyed.
classListenerType(ABC):""" Listener Factory """@abstractmethodasyncdefcreate(self,options: Options) ->'Listener':""" creates an listener on the corresponding C2 and return a Listener with listener_internal_id for the corresponding API
raises ValueError in case of invalid dto raises ConectionError in case of not be able to connect to c2 instance raises ResourceExistsError in case of not be able to create the objectdue it already exists """pass@abstractmethodasyncdefdelete(self,internal_id:str,options: Options) ->None:""" removes a listener from a corresponding c2 instance raises ValueError in case of invalid dto raises ConectionError in case of not be able to connect to c2 instance raises ResourceNotFoundError in case of not be able to remove the object due to unfound resource """pass
The creation or elimination of elements requires a consistency check by the class handler. This allows Zuthaka to catch at an early stage any consistency problem with the infrastructure handled.
Implementing Launcher Type Class
The Launchers represent the capabilities of a given C2 to encapsulate the implant for later execution on the victim's machine.
Attributes and Options Descriptions
....classTemplateLauncherType(ListenerType): name ='Powershell Launcher' description ='Uses powershell.exe to launch Agent using [systemm.reflection.assemly::load()' registered_options = [OptionDesc( name='Dotnet Version', description='version of dotnet in which the launcher is going to take place', example='Net35', field_type='string', required=True ), ]...
Behavior Abstract Methods
...asyncdefcreate_launcher(self,dto: Dict[str, Any]) ->str:""" creates a laucnher on the corresponding C2 and return an launcher_internal_id raises ValueError in case of invalid dto
raises ConectionError in case of not be able to connect to c2 instance raises ResourceExistsError in case of not be able to create the objectdue it already exists """passasyncdefdownload_launcher(self,dto: Dict[str, Any]) ->bytes:""" retrives a created launcher using an launcher_internal_id raises ValueError in case of invalid dto raises ConectionError in case of not be able to connect to c2 instance raises ResourceNotFoundError """...
Implementing Agent Type Class
Agents are controlled victim's machines. The integration of Agents on Zuthaka allows the user to manage the computer through the UI.
Behavior Abstract Methods
classTemplateAgent(AgentType):asyncdefretreive_agents(self,dto: Dict[str, Any]) ->bytes:""" retrives all available Agents on the given C2 raises ValueError in case of invalid dto raises ConectionError in case of not be able to connect to c2 instance raises ResourceNotFoundError [*] EXAMPLES dto = { 'c2_type' :'EmpireC2Type', 'c2_options': { "url": "https://127.0.0.1:7443", "username": "cobbr", "password": "NewPassword!" }, 'listeners_internal_ids' : ['1','2','3'] } """passasyncdefshell_execute(self,dto: Dict[str, Any]) ->bytes:""" executes a command string on the raises ValueError in case of invalid dto raises ConectionError in case of not be able to connect to c2 instance raises ResourceNotFoundError """pass