-
Notifications
You must be signed in to change notification settings - Fork 8
Feature bettercap #176
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature bettercap #176
Conversation
whotwagner
commented
Aug 25, 2025
- 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.
There was a problem hiding this comment.
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): |
There was a problem hiding this comment.
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