Core concepts
Use-Cases and Agents
Naming is hard.
Usecase
We use the term 'Use-Case' for anything that can be executed within HackingBuddyGPT. That's the origin of the naming: HackingBuddyGPT is our tool, and it can run diverse use-cases.
Examples for use-cases include executing a Linux-based Privilege-Escalation Attack, Performing Web Penetration-Testing, or specialized version of the already mentioned Linux Privilege-Escalation Attack utilizing additional information such as human hints.
Custom usecases are subclasses of UseCase and have to have to implement two abstract methods:
run: this is the main method that will be called when a usecase is started throughhackingBuddyGPTget_name: this should return a name for the usecase, it will be used for logging and debugging.
Usecases automatically utilize our configuration mechanism. Usecases themselves are typically implemented using one or more agents.
Agent
The agent acts on behalf of the user and try to achieve a task given to them. In a security context, they are often given security-related tasks, i.e., they are given the goal to hack a test system.
Within hackingBuddyGPT, agents can be created by sub-classing Agent and implementing the perform_round abstract method. While traditional agents often incorporate a control-loop and run continously, due to safety reasons, our agents do not contain the control loop but only the perform_round step function which will be called through hackingBuddyGPT. This allows our infrastructure to implement a hard round limit as well as keep the human in the loop after each performed round.
The following are fragments of an agent, showing off hackingBuddyGPT features:
# ...
class MinimalLinuxPrivesc(Agent):
# configured through the configuration subsystem
conn: SSHConnection = None
# instance variables starting with _ are not auto-configured
_sliding_history: SlidingCliHistory = None
def init(self):
super().init()
self._sliding_history = SlidingCliHistory(self.llm)
# configure agent capabilities
self.add_capability(SSHRunCommand(conn=self.conn), default=True)
self.add_capability(SSHTestCredential(conn=self.conn))
# ..
# during each round, ask the configured LLM for a hacking command and execute it
def perform_round(self, turn: int) -> bool:
# do something ..
# if this method returns True, execution is stopped
return False
To summarize what is happening here:
- instance variables will automatically be set by the configuration subsystem. In this case, the variable
hack_levelwill be exposed by hackingBuddyGPT and can be set within either an.envfile or through a command line option.wintermute.pyallows listing of all detected configuration options for each use-case. - The usecase itself is quite simple, we provide two over-writable methods:
initshould initially callsuper().init()and then include all needed initialization code for this use-case.perform_roundwill be called repeatably through hackingBuddyGPT
Matching Agents and UseCases
How do we connect usecases with agents? Typically, developers will create an autonomous agent which should be called by hackingBuddyGPT until it returns True (the goal has been achieved) or the maximum round number has been reached.
hackingBuddyGPT provides helper methods for this:
@use_case("Showcase Minimal Linux Priv-Escalation")
class MinimalLinuxPrivescUseCase(AutonomousAgentUseCase[MinimalLinuxPrivesc]):
pass
In this case we define a new UseCase (MinimalLinuxPrivescUseCase) which inherits from AutonomousAgentUseCase which in turn is parametrized with our MinimalLinuxPrivesc agent. AutonomousAgentUseCase incorporates all needed logic to make an agent runable.
Adding this subclass will achieve the following:
- through usage of the
use_caseannotation, hackingBuddyGPT will be able to automatically detect that this should be a callable use-case and adds it to the command line tool with the given name and description during run-time. - When called, the encapsulated agent will be configured and their
perform_roundmethod called until the task has been achieved or a configurable round limit reached - Both usecase and agent are configured using our Configuration System.
For a fully fleshed-out example, please see our Minimal LinuxPrivesc Usecase.
