NASim
Description
NASim is a single-agent, multi-step penetration-testing environment ported from Jonathon
Schwartz's Network Attack Simulator. It
wraps the simulator side of NASim (its pure-Python sim mode — not the VM/container emu
side). The agent faces an abstract network of subnets and hosts, each running services, an OS,
and processes, behind firewalls. Starting from the internet-facing subnet, the agent must scan
hosts, exploit services to gain a foothold, escalate privileges to ROOT, and pivot through the
network to compromise a set of hidden sensitive hosts. The environment is partially observable:
hosts and their attributes are unknown until discovered through scanning, and exploits/privilege
escalations are probabilistic and may fail.
Capabilities
- Multi-step planning under partial observability
- Network reconnaissance: service, OS, process, and subnet scanning
- Exploitation and privilege escalation against a documented attack catalog
- Pivoting through compromised hosts and reasoning about firewall topology
- Detecting and recovering from probabilistic action failures
Compute Requirements
NASim sim mode is pure Python (gymnasium + numpy + networkx). It needs no GPU, no Docker-in-Docker,
and minimal RAM (well under 1 GB for the shipped scenarios). One system dependency is required: nasim
imports tkinter unconditionally (nasim/envs/render.py), so the Tk runtime libraries (libtk8.6,
libtcl8.6) must be present even though this environment never renders. The Dockerfile installs them;
most desktop Python installs already ship Tk.
License
MIT (inherited from the
upstream nasim package).
Tasks
Two splits:
- test (9 tasks): one task per curated, hand-authored benchmark scenario —
tiny,tiny-hard,tiny-small,small,small-honeypot,small-linear,medium,medium-single-site,medium-multi-site. Each uses a fixed seed for reproducibility. - train (100 tasks): procedurally generated benchmarks (
tiny-gen,small-gen,medium-gen,large-gen) crossed with 25 seeds. Within a family the network topology and sensitive-host placement are fixed; the seed deterministically varies the per-host service/OS/process configuration and the in-episode exploit/privilege-escalation RNG. (tiny-genis degenerate: its 3-host network yields a single host configuration across all 25 seeds, so those tasks differ only in RNG.)
Each task is a TaskSpec with id, scenario (benchmark name), seed, and an optional
max_steps step budget. If max_steps is omitted it is derived from network size
(clamp(num_hosts * 8, 40, 300)), since NASim's native step limit (1000–30000) is far too large for
an LLM rollout.
Reward Structure
Reward is forwarded directly from NASim. Each action yields reward = value_gained - action_cost:
every action costs reward (typically 1), and compromising a sensitive host grants its value. An
episode is solved (finished with goal reached) when every sensitive host has been escalated to
ROOT; it also ends when the step budget is exhausted. Invalid client requests (an out-of-range
target, or an exploit/privilege-escalation name not in the catalog) return a helpful error, yield
reward 0, and do not consume the step budget.
We do not use LLM graders for this task.
Data
No external data is required. Scenarios are loaded from the nasim package's bundled benchmark
definitions or generated procedurally from a seed.
Tools
One tool per NASim action type. Scans take a target (subnet, host); exploits and privilege
escalations additionally take a catalog name.
service_scan(subnet, host): reveal which network services a host runs.os_scan(subnet, host): reveal a host's operating system.process_scan(subnet, host): reveal a host's processes (requires access to the host).subnet_scan(subnet, host): from a compromised host, discover hosts in connected subnets.exploit(subnet, host, name): run a named exploit to gain access remotely.privilege_escalation(subnet, host, name): escalate to ROOT via a named process exploit.
Each tool returns the agent's accumulated knowledge of the network (only discovered hosts, with their learned services/OS/processes and access status), a one-line result of the last action, and a status line (steps used / budget, cumulative reward, sensitive hosts rooted).
Time Horizon
Multi-turn. A task runs until the goal is reached or the step budget is exhausted (tens to a few hundred actions depending on scenario size).
Safety
NASim is a fully abstract simulator. The agent issues structured actions against an in-memory model of a network; there is no real host, network access, or external system involved. The "exploits" are named entries in a synthetic catalog with success probabilities, not real exploit code.
Running
# install deps (pure Python; works headless)
pip install -r requirements.txt
# run the environment server
python server.py
# run tests
pytest tests.py
Citations
@misc{schwartz2019nasim,
author = {Jonathon Schwartz},
title = {NASim: Network Attack Simulator},
year = {2019},
howpublished = {\url{https://github.com/Jjschwartz/NetworkAttackSimulator}}
}