Skip to content
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

Fix PettingZooParallelWrapper to return fresh actions on each call to int_to_cyborg_action #5

Open
wants to merge 29 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
ade2d06
Initial commit
cage-challenge Sep 23, 2022
0f7c13a
adding CAGE Challenge 3
cage-challenge Sep 30, 2022
91d725c
Fixing installation path. Thanks https://github.com/zzj0402 for raisi…
maxstanden Oct 11, 2022
bfae42d
updating evaluation.py for CC3
maxstanden Oct 11, 2022
f94efa0
Update README.md (#2)
hkscy Oct 11, 2022
e562614
updating OpenAIGymWrapper.py and README to improve use of OpenAIGymWr…
maxstanden Oct 12, 2022
a2d03f9
updating RLLib Wrapper and associated documentation
maxstanden Oct 13, 2022
ed830b6
Add Ray latest to Requirements.txt (#7)
hkscy Oct 17, 2022
9943f85
Adding Tutorials
cage-challenge Nov 4, 2022
94ab9d2
Fixing action and observation space in PettingZooParallelWrapper
MitchellKiely Nov 18, 2022
d0d7fa1
Updating tutorials for new CC3 release
maxstanden Dec 15, 2022
f34ad9a
Updating render function on OpenAIGymWrapper.py
maxstanden Dec 15, 2022
dc0e4da
Correcting description of behaviour 3 for RedDroneWormAgent
maxstanden Dec 15, 2022
64bf454
Fixing TrueTableWrapper.py observation change call
maxstanden Dec 15, 2022
204df5f
Updating tests for PettingZooParallelWrapper.py
maxstanden Dec 15, 2022
e1573b7
Updating PettingZooParallelWrapper.py to correctly alter the actionspace
maxstanden Dec 16, 2022
3045f16
Adding example submission
maxstanden Dec 16, 2022
e0ad98a
Fixing AllowTraffic blocking traffic if no blocks exist on that host
maxstanden Dec 20, 2022
d95a8e2
fixing error in the Observation from the PettingZooParallelWrapper.py
maxstanden Dec 20, 2022
581206e
adding Dockerfile
maxstanden Jan 12, 2023
dd586a3
Update to v3.1
maxstanden Jan 25, 2023
2c13fc5
Make sure list is not empty
Feb 27, 2023
44b8211
Merge pull request #30 from Anth0rx/main
cage-challenge Mar 30, 2023
b5a71c4
Uploading the version of the evaluation.py file we used to validate t…
maxstanden Apr 12, 2023
ae2e8d4
Fix Wrapper Actions
hkscy Jun 4, 2023
0143b25
Merge branch 'main' of https://github.com/hkscy/cage-challenge-3
hkscy Jun 4, 2023
08dadcc
fix drone zeros
hkscy Jul 12, 2023
d7738a9
Fix position bug
hkscy Apr 1, 2024
1d6678a
fix setup
hkscy Apr 1, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
34 changes: 34 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
*.*~
__pycache__/
*.pkl
data/
**/*.egg-info
.python-version
../../PycharmProjects/CybORG/.idea/
.vscode/
.DS_Store
.pytest_cache/
profiles/
venv/*
venv
.idea/
CybORG\.egg-info/

_pycache_/
*.pyc

CybORG/Logs/
CybORG/Emulator/Logs/
CybORG/Emulator/logs/
CybORG/Emulator/Config/emulatorconfig.ini
docs/_build/
dist

CybORG/Shared/Config/config.ini

CybORG/Emulator/AWS/Config/awsconfig.ini

*.swp
*.pstats

.ipynb_checkpoints/
1 change: 0 additions & 1 deletion CybORG
Submodule CybORG deleted from dd586a
127 changes: 127 additions & 0 deletions CybORG/Agents/SimpleAgents/B_line.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
from CybORG.Agents import BaseAgent
from CybORG.Shared import Results
from CybORG.Simulator.Actions import PrivilegeEscalate, ExploitRemoteService, DiscoverRemoteSystems, Impact, \
DiscoverNetworkServices, Sleep


class B_lineAgent(BaseAgent):
def __init__(self, np_random=None):
super(B_lineAgent, self).__init__(np_random)
self.action = 0
self.target_ip_address = None
self.last_subnet = None
self.last_ip_address = None
self.action_history = {}
self.jumps = [0,1,2,2,2,2,5,5,5,5,9,9,9,12,13]

def train(self, results: Results):
"""allows an agent to learn a policy"""
pass

def get_action(self, observation, action_space):
# print(self.action)
"""gets an action from the agent that should be performed based on the agent's internal state and provided observation and action space"""
session = 0

while True:
if observation['success'] == True:
self.action += 1 if self.action < 14 else 0
else:
self.action = self.jumps[self.action]

if self.action in self.action_history:
action = self.action_history[self.action]

# Discover Remote Systems
elif self.action == 0:
self.initial_ip = observation['User0']['Interface'][0]['IP Address']
self.last_subnet = observation['User0']['Interface'][0]['Subnet']
action = DiscoverRemoteSystems(session=session, agent='Red', subnet=self.last_subnet)
# Discover Network Services- new IP address found
elif self.action == 1:
hosts = [value for key, value in observation.items() if key not in ['success', 'message']]
get_ip = lambda x : x['Interface'][0]['IP Address']
interfaces = [get_ip(x) for x in hosts if get_ip(x)!= self.initial_ip]
if len(interfaces) < 1:
action = DiscoverRemoteSystems(session=session, agent='Red', subnet=self.last_subnet)
else:
self.last_ip_address = self.np_random.choice(interfaces)
action = DiscoverNetworkServices(session=session, agent='Red', ip_address=self.last_ip_address)

# Exploit User1
elif self.action == 2:
action = ExploitRemoteService(session=session, agent='Red', ip_address=self.last_ip_address)

# Privilege escalation on User Host
elif self.action == 3:
hostname = [value for key, value in observation.items() if key != 'success' and 'System info' in value][0]['System info']['Hostname']
action = PrivilegeEscalate(agent='Red', hostname=hostname, session=session)

# Discover Network Services- new IP address found
elif self.action == 4:
self.enterprise_host = [x for x in observation if 'Enterprise' in x][0]
self.last_ip_address = observation[self.enterprise_host]['Interface'][0]['IP Address']
action = DiscoverNetworkServices(session=session, agent='Red', ip_address=self.last_ip_address)

# Exploit- Enterprise Host
elif self.action == 5:
self.target_ip_address = [value for key, value in observation.items() if key != 'success'][0]['Interface'][0]['IP Address']
action = ExploitRemoteService(session=session, agent='Red', ip_address=self.target_ip_address)

# Privilege escalation on Enterprise Host
elif self.action == 6:
hostname = [value for key, value in observation.items() if key != 'success' and 'System info' in value][0]['System info']['Hostname']
action = PrivilegeEscalate(agent='Red', hostname=hostname, session=session)

# Scanning the new subnet found.
elif self.action == 7:
self.last_subnet = observation[self.enterprise_host]['Interface'][0]['Subnet']
action = DiscoverRemoteSystems(subnet=self.last_subnet, agent='Red', session=session)

# Discover Network Services- Enterprise2
elif self.action == 8:
self.target_ip_address = [value for key, value in observation.items() if key != 'success'][2]['Interface'][0]['IP Address']
action = DiscoverNetworkServices(session=session, agent='Red', ip_address=self.target_ip_address)

# Exploit- Enterprise2
elif self.action == 9:
self.target_ip_address = [value for key, value in observation.items() if key != 'success'][0]['Interface'][0]['IP Address']
action = ExploitRemoteService(session=session, agent='Red', ip_address=self.target_ip_address)

# Privilege escalation on Enterprise2
elif self.action == 10:
hostname = [value for key, value in observation.items() if key != 'success' and 'System info' in value][0]['System info']['Hostname']
action = PrivilegeEscalate(agent='Red', hostname=hostname, session=session)

# Discover Network Services- Op_Server0
elif self.action == 11:
action = DiscoverNetworkServices(session=session, agent='Red', ip_address=observation['Op_Server0']['Interface'][0]['IP Address'])

# Exploit- Op_Server0
elif self.action == 12:
info = [value for key, value in observation.items() if key != 'success']
if len(info) > 0:
action = ExploitRemoteService(agent='Red', session=session, ip_address=info[0]['Interface'][0]['IP Address'])
else:
self.action = 0
continue
# Privilege escalation on Op_Server0
elif self.action == 13:
action = PrivilegeEscalate(agent='Red', hostname='Op_Server0', session=session)
# Impact on Op_server0
elif self.action == 14:
action = Impact(agent='Red', session=session, hostname='Op_Server0')

if self.action not in self.action_history:
self.action_history[self.action] = action
return action

def end_episode(self):
self.action = 0
self.target_ip_address = None
self.last_subnet = None
self.last_ip_address = None
self.action_history = {}

def set_initial_values(self, action_space, observation):
pass
32 changes: 32 additions & 0 deletions CybORG/Agents/SimpleAgents/BaseAgent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from gym.utils import seeding


from CybORG.Shared import Results

class BaseAgent:
def __init__(self, name: str, np_random=None):
self.name = name
if np_random is None:
np_random, seed = seeding.np_random()
self.np_random = np_random

def train(self, results: Results):
"""allows an agent to learn a policy"""
raise NotImplementedError

def get_action(self, observation, action_space):
"""gets an action from the agent that should be performed based on the agent's internal state and provided observation and action space"""
raise NotImplementedError

def end_episode(self):
"""Allows an agent to update its internal state"""
raise NotImplementedError

def set_initial_values(self, action_space, observation):
raise NotImplementedError

def __str__(self):
return f"{self.__class__.__name__}"

def __repr__(self):
return f"{self.__class__.__name__}"
38 changes: 38 additions & 0 deletions CybORG/Agents/SimpleAgents/BlueLoadAgent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import inspect

from stable_baselines3 import PPO

from CybORG import CybORG
from CybORG.Agents.SimpleAgents.BaseAgent import BaseAgent
from CybORG.Agents.Wrappers.EnumActionWrapper import EnumActionWrapper
from CybORG.Agents.Wrappers.FixedFlatWrapper import FixedFlatWrapper
from CybORG.Agents.Wrappers.OpenAIGymWrapper import OpenAIGymWrapper

from CybORG.Agents.Wrappers import ChallengeWrapper

class BlueLoadAgent(BaseAgent):
# agent that loads a StableBaselines3 PPO model file
def train(self, results):
pass

def end_episode(self):
pass

def set_initial_values(self, action_space, observation):
pass

def __init__(self, model_file: str = None):
if model_file is not None:
self.model = PPO.load(model_file)
else:
self.model = None

def get_action(self, observation, action_space):
"""gets an action from the agent that should be performed based on the agent's internal state and provided observation and action space"""
if self.model is None:
path = str(inspect.getfile(CybORG))
path = path[:-7] + f'/Shared/Scenarios/Scenario1b.yaml'
cyborg = ChallengeWrapper(env=CybORG(path, 'sim'), agent_name='Blue')
self.model = PPO('MlpPolicy', cyborg)
action, _states = self.model.predict(observation)
return action
67 changes: 67 additions & 0 deletions CybORG/Agents/SimpleAgents/BlueReactAgent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
from CybORG.Agents.SimpleAgents.BaseAgent import BaseAgent
from CybORG.Shared import Results
from CybORG.Simulator.Actions import Monitor, Remove, Restore


class BlueReactRemoveAgent(BaseAgent):
def __init__(self):
self.host_list = []
self.last_action = None

def train(self, results: Results):
pass

def get_action(self, observation, action_space):
# add suspicious hosts to the hostlist if monitor found something
# added line to allow for automatic monitoring.
if self.last_action is not None and self.last_action == 'Monitor':
for host_name, host_info in [(value['System info']['Hostname'], value) for key, value in observation.items() if key != 'success']:
if host_name not in self.host_list and host_name != 'User0' and 'Processes' in host_info and len([i for i in host_info['Processes'] if 'PID' in i]) > 0:
self.host_list.append(host_name)
# assume a single session in the action space
session = list(action_space['session'].keys())[0]
if len(self.host_list) == 0:
self.last_action = 'Monitor'
return Monitor(agent='Blue', session=session)
else:
self.last_action = 'Remove'
return Remove(hostname=self.host_list.pop(0), agent='Blue', session=session)

def end_episode(self):
self.host_list = []
self.last_action = None

def set_initial_values(self, action_space, observation):
pass


class BlueReactRestoreAgent(BaseAgent):
def __init__(self):
self.host_list = []
self.last_action = None

def train(self, results: Results):
pass

def get_action(self, observation, action_space):
# add suspicious hosts to the hostlist if monitor found something
# added line to reflect changes in blue actions
if self.last_action is not None and self.last_action == 'Monitor':
for host_name, host_info in [(value['System info']['Hostname'], value) for key, value in observation.items() if key != 'success']:
if host_name not in self.host_list and host_name != 'User0' and 'Processes' in host_info and len([i for i in host_info['Processes'] if 'PID' in i]) > 0:
self.host_list.append(host_name)
# assume a single session in the action space
session = list(action_space['session'].keys())[0]
if len(self.host_list) == 0:
self.last_action = 'Monitor'
return Monitor(agent='Blue', session=session)
else:
self.last_action = 'Restore'
return Restore(hostname=self.host_list.pop(0), agent='Blue', session=session)

def end_episode(self):
self.host_list = []
self.last_action = None

def set_initial_values(self, action_space, observation):
pass
35 changes: 35 additions & 0 deletions CybORG/Agents/SimpleAgents/ConstantAgent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from CybORG.Agents.SimpleAgents.BaseAgent import BaseAgent
from CybORG.Shared import Results
from CybORG.Simulator.Actions import Sleep, Monitor

class ConstantAgent(BaseAgent):

def __init__(self, action, name=None):
super().__init__(name)
self.action = action

def train(self, results: Results):
"""allows an agent to learn a policy"""
pass

def get_action(self, observation, action_space):
"""gets an action from the agent that should be performed based on the agent's internal state and provided observation and action space"""
return self.action

def end_episode(self):
"""Allows an agent to update its internal state"""
pass

def set_initial_values(self, action_space, observation):
pass

class SleepAgent(ConstantAgent):
def __init__(self, name=None, **kwargs):
action = Sleep()
super().__init__(action, name)

class MonitorAgent(ConstantAgent):
def __init__(self):
action = Monitor(agent='Blue', session=0)
super().__init__(action)

Loading