penpal package
Submodules
penpal.baseexecutor module
- class penpal.baseexecutor.BaseExecutor(cmdconfig=None)
Bases:
objectThe BaseExecutor is the base class of all Executors. It enables base functionality for all Executors and provides a structure for all Executors.
In order to create a custom Executor, one must simply derive from the BaseExecutor and implement the method _exec_cmd()
- error_if(command: BaseCommand, result: Result)
- error_if_not(command: BaseCommand, result: Result)
- exec(command: BaseCommand)
- log_command(command)
Log starting-status of the command
- loop_if(command: BaseCommand, result: Result)
- loop_if_not(command: BaseCommand, result: Result)
- run(command: BaseCommand)
Execute the command
This method is executed by PenPal and executes the given command. This method sets the run_count to 1 and runs the method exec()
- Parameters:
command (BaseCommand) – The settings for the command to execute
- exception penpal.baseexecutor.ExecException
Bases:
ExceptionException for all Executors
This exception is raised by Executors if anything goes wrong. The BaseExecutor will catch the Exception, writes it to the console and exits gracefully.
penpal.metadata module
penpal.msfexecutor module
- class penpal.msfexecutor.MsfModuleExecutor(cmdconfig=None, *, msfconfig=None, msfsessionstore: MsfSessionStore)
Bases:
BaseExecutor- connect(msfconfig=None)
- log_command(command: BaseCommand)
Log starting-status of the command
- prepare_exploit(command: MsfModuleCommand)
- prepare_payload(command: MsfModuleCommand)
penpal.penpal module
PenPal reads a playbook and executes the attack
A playbook stored in a dictionary with a list of attacks. Attacks are executed by “Executors”. There are many different Executors like: ShellExecutor, SleepExecutor or MsfModuleExecutor This class creates instances of all possible Executors, iterates over all attacks and runs the specific Executor with the given configuration.
- class penpal.penpal.PenPal(config_file: str)
Bases:
object- initialize_executors()
Initialize all Executors
Executors are supposed to execute commands. This method initializes all possible executors.
- initialize_variable_parser()
Initializes the variable-parser
The variable-parser replaces variables with values in certain strings
- main()
The main function
This function calls the variable_parser() and interates over all configured commands and passes them to the executors.
- parse_config(config_file: str)
Config-Parser for PenPal
This parser reads the playbook-file and validates the config-settings.
- Parameters:
config_file (str) – The path to a yaml-playbook
Notes
This method will exit(1) on errors.
penpal.schemas module
- class penpal.schemas.BaseCommand(*, error_if: str | None = None, error_if_not: str | None = None, loop_if: str | None = None, loop_if_not: str | None = None, loop_count: int = 3, exit_on_error: bool = True, cmd: str)
Bases:
BaseModel- cmd: str
- error_if: str | None
- error_if_not: str | None
- exit_on_error: bool
- loop_count: int
- loop_if: str | None
- loop_if_not: str | None
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class penpal.schemas.CommandConfig(*, loop_sleep: int = 5)
Bases:
BaseModel- loop_sleep: int
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class penpal.schemas.Config(*, msf_config: MsfConfig = MsfConfig(password=None, ssl=True, port=55553, server='127.0.0.1', uri='/api/'), cmd_config: CommandConfig = CommandConfig(loop_sleep=5), vars: Dict[str, str] | None = None, commands: List[ShellCommand | MsfModuleCommand | MsfSessionCommand | SleepCommand | SSHCommand])
Bases:
BaseModel- cmd_config: CommandConfig
- commands: List[ShellCommand | MsfModuleCommand | MsfSessionCommand | SleepCommand | SSHCommand]
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- vars: Dict[str, str] | None
- class penpal.schemas.MsfConfig(*, password: str | None = None, ssl: bool = True, port: int = 55553, server: str | None = '127.0.0.1', uri: str | None = '/api/')
Bases:
BaseModel- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- password: str | None
- port: int
- server: str | None
- ssl: bool
- uri: str | None
- class penpal.schemas.MsfModuleCommand(*, error_if: str | None = None, error_if_not: str | None = None, loop_if: str | None = None, loop_if_not: str | None = None, loop_count: int = 3, exit_on_error: bool = True, cmd: str, type: Literal['msf-module'], target: int = 0, creates_session: str | None, session: str | None, payload: str | None, options: Dict[str, str] = {}, payload_options: Dict[str, str] = {})
Bases:
BaseCommand- cmd: str
- creates_session: str | None
- is_interactive()
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- module_path()
- module_type()
- options: Dict[str, str]
- payload: str | None
- payload_options: Dict[str, str]
- session: str | None
- target: int
- type: Literal['msf-module']
- class penpal.schemas.MsfSessionCommand(*, error_if: str | None = None, error_if_not: str | None = None, loop_if: str | None = None, loop_if_not: str | None = None, loop_count: int = 3, exit_on_error: bool = True, cmd: str, type: Literal['msf-session'], stdapi: bool = False, write: bool = False, read: bool = False, session: str, end_str: str | None)
Bases:
BaseCommand- cmd: str
- end_str: str | None
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- read: bool
- session: str
- stdapi: bool
- type: Literal['msf-session']
- write: bool
- class penpal.schemas.SSHCommand(*, error_if: str | None = None, error_if_not: str | None = None, loop_if: str | None = None, loop_if_not: str | None = None, loop_count: int = 3, exit_on_error: bool = True, cmd: str, type: Literal['ssh'], hostname: str | None, port: int | None, username: str | None, password: str | None, passphrase: str | None, key_filename: str | None, creates_session: str | None, session: str | None, clear_cache: bool = False, timeout: float = 60, jmp_hostname: str | None, jmp_port: int | None, jmp_username: str | None)
Bases:
BaseCommand- clear_cache: bool
- creates_session: str | None
- hostname: str | None
- jmp_hostname: str | None
- jmp_port: int | None
- jmp_username: str | None
- key_filename: str | None
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- passphrase: str | None
- password: str | None
- port: int | None
- session: str | None
- timeout: float
- type: Literal['ssh']
- username: str | None
- class penpal.schemas.ShellCommand(*, error_if: str | None = None, error_if_not: str | None = None, loop_if: str | None = None, loop_if_not: str | None = None, loop_count: int = 3, exit_on_error: bool = True, cmd: str, type: Literal['shell'])
Bases:
BaseCommand- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- type: Literal['shell']
- class penpal.schemas.SleepCommand(*, error_if: str | None = None, error_if_not: str | None = None, loop_if: str | None = None, loop_if_not: str | None = None, loop_count: int = 3, exit_on_error: bool = True, cmd: str = 'sleep', type: Literal['sleep'], min_sec: int = 0, seconds: int = 1, random: bool = False)
Bases:
BaseCommand- cmd: str
- min_sec: int
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- random: bool
- seconds: int
- type: Literal['sleep']
penpal.shellexecutor module
shellexecutor.py
This class enables executing shell commands in PenPal.
- class penpal.shellexecutor.ShellExecutor(cmdconfig=None)
Bases:
BaseExecutor- log_command(command: BaseCommand)
Log starting-status of the command
penpal.sleepexecutor module
- class penpal.sleepexecutor.SleepExecutor(cmdconfig=None)
Bases:
BaseExecutor- log_command(command)
Log starting-status of the command
- set_sleeptime(command)