Skip to content

Conversation

@whotwagner
Copy link
Contributor

  • Added executor that communicates with the bettercap rest-api
  • Added docs for the bettercap-commands
  • Added tests for the bettercap-executor

This commit adds a bettercapexecutor to attackmate that
allows to orchestrate commands via bettercap-rest-api.
pre-commit complained about some mypy and flake8 issues.
Mostly whitespaces or linelenght-issues.
@whotwagner whotwagner added the enhancement New feature or request label Aug 25, 2025
@whotwagner whotwagner marked this pull request as draft November 27, 2025 12:37
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: avoid the same pain as with the different sliver commands we can try to have one Bettercap Command with type "bettercap" and a list of possible literals for the "cmd" attribute

BettercapCmds = Literal[
    'get_events',
    'get_session_modules',
    'get_session_env',
    'get_session_gateway',
    'get_session_hid',
    'get_session_ble',
    'get_session_interface',
    'get_session_lan',
    'get_session_options',
    'get_session_packets',
    'get_session_started_at',
    'get_session_wifi',
    'get_file',
    'post_api_session',
    'delete_api_events'
]

then

class BettercapCommand(BaseCommand):
    type: Literal['bettercap'] = 'bettercap'
    cmd: BettercapCmds
etc.

and enforce the required fields for certain commands (like get_file needing a file name, does post_api session needs "data"?) with model validators (like in vnc.py)

required_fields = {
            'get_file': ['filename'],
etc.
        }       

 if cmd in required_fields:
            missing_fields = [field for field in required_fields[cmd] if getattr(values, field, None) is None]
            if missing_fields:
                raise ValueError(f'Command "{cmd}" requires {", ".join(missing_fields)} field(s).')

and then in the executor itself to decide what to do not check for what instance of a command class but which value of cmd the Bettercap command has. (and if it has a mac value -> treat it as a mac command)

BettercapDeleteApiEventsCommand)):
raise ExecException('Wrong command-type')
self.setup_connection(command)
if isinstance(command, BettercapGetWithMacCommand):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of checking what command instance checking for value of cmd (pseudocody)

command_name = command.cmd
# treat mac commands
if command_name.startswith('get_session_') and hasattr(command, 'mac'):
                (code, headers, result) = getattr(self.client, command_name)(command.mac)

#treat other commands
elif command_name.startswith('get_') or command_name.startswith('delete_'):
                #exception for get file
                if command_name == 'get_file':
                    (code, headers, result) = self.client.get_file(command.filename)
                # other exceptions?
                elif
                # commands without parameters

@whotwagner whotwagner marked this pull request as ready for review December 4, 2025 11:47
@whotwagner whotwagner merged commit 82a41a3 into ait-testbed:development Dec 4, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants