🟢 The green part except Mininet API
resides in Mininet/AdapterComponents
. They are the subcomponents that lives entirely in the object created by a class called MininetAdapter
which is in Mininet/MininetAdapter.py
.
Mininet API
resides in Mininet/MininetAPI
, and it deals with configuring and setting up a Mininet process. This module is originally developed by Dr. Gokhale's lab.
🟠 The orange part resides in a class called CybORGFactory
in Mininet/CustomFactory.py
.
🟣 The purple part resides in a class called AgentFactory
in Mininet/CustomFactory.py
.
A good way to understand how each component fits each other is to take a look at the integration test in Mininet/Tests/test_exploit_action.py
The current implementation only supports Ubuntu 20.04 and 22.04.
Take a look at setup.md
# Create your virtual environment
python3 -m venv venv
source venv/bin/activate
# Clone the repo
git clone https://github.com/CASTLEGym/CybORG.git
cd CybORG
git checkout mininet-cyborg2
# Install packages
pip install -e .
📌 Modify the value based on your system configuration in config.cfg
[PYTHON]
FILE_PATH=<YOUR ABSOLUTE PYTHON EXECUTION FILE PATH>
[SSH]
PASSWORD=<your desired root user password>
cd CybORG/Mininet
python3 main.py --env <sim | emu> --max_step <step size> --max_episode <number of episodes> --scenario <your desired scenario file located in Shared/Scenarios>
📗 Please follow the workflow in MininetAdapter.step()
to support a new action.
Let's take Impact
Action as an example,
First, make sure you understand the action string spitted out from Agents. In this case, it could be Impact Op_Server0
.
MininetAdapter.parse_action_string(action_string)
will parse this into Op_Server0
, IP ADDRESS OF Op_Server0
, Impact
Then, you should update BlueActionTranslator
class or RedActionTranslator
class. The goal is to translate the action string (Here it would be IP ADDRESS OF Op_Server0
and Impact
) into a bash command that will be sent to mininet cli
There are two things to look after when updating BlueActionTranslator
class or RedActionTranslator
class in action_translator.py
,
- Implement the translation function
# One could decide its own method signature
def impact(self, target_host: str) -> str:
action_string = ""
# Translation happens here ...
return action_string
- Register your action translation function into the member field
action_map
self.action_map = {
...
"Impact": self.impact
}
But what exactly should be in the
impact
function?
- I would recommend creating a new folder in
Mininet/Actions
, let's call itImpact/
. Write a bash script that runs inside the Mininet process. Be aware that this process runs asroot
user ❗️
After doing so, think about what the observation should look like. Please take a look at results_bundler.py
and its utility functions.
Remember to think about the side effects caused by this action, it could affect the member fields in MininetAdapter
class such as
self.md5: Dict[str, dict] = {}
self.connection_key: Dict = {}
self.used_ports: Dict = {}
self.exploited_hosts: List = []
self.priviledged_hosts: List = []
self.old_exploit_outcome: Dict = {}
self.network_state: Dict = {}
self.available_ports: List = random.sample(range(4000, 5000 + 1), 50)
Finally, write an integration test to test your idea!
-
Continue to monitor and sync with the new implementations in
wrapper
branch, such as the newly updatedImpact
Action implementation. -
Use Docker containers as hosts within Mininet. Containernet
Benefits: It helps isolate the environment, especially as we will configure the root user's password 👀