These tutorials start with local trusted specimens and move toward workflows you would use for suspicious or untrusted binaries. Build the example specimens once:
uv sync
make -C specimensGoal: create a run and inspect the summary.
uv run containre run specimens/bin/hello --net deny
uv run containre lsPick the run_id from containre ls, then inspect metadata and the first events:
uv run containre show <run_id> --events --limit 20
uv run containre summarize <run_id>Use this workflow to confirm your local install and run directory are working. The summary view is the fastest way to spot grouped network endpoints, detections, and repeated blocked-egress patterns.
Goal: see egress containment in the event stream.
uv run containre run specimens/bin/netbeacon --net deny
uv run containre show <run_id> --events --kind netExpected result: a connect event with a blocked decision. Under deny, the
specimen is traced but does not get real egress.
Goal: make a specimen reveal HTTP behavior without real network access.
uv run containre run specimens/bin/httpbeacon --net simulate
uv run containre show <run_id> --events --kind netExpected result: HTTP-related network events from the built-in sink. This is the default analysis pattern for specimens that need a response before they expose their next behavior.
Goal: plant a canary file and trigger detection when a specimen touches it.
uv run containre run specimens/bin/ransomemu --net deny --decoy wallet.dat
uv run containre show <run_id> --events --kind detectionExpected result: a decoy-related detection and captured file activity. The
ransomemu specimen is a safe emulator: it operates in the harness work
directory and does not encrypt user files.
Goal: watch runs live and inspect memory, detections, artifacts, and pcap output.
uv run containre serveOpen http://127.0.0.1:8787. Launch a specimen from the UI or start one from the
CLI while the server is running:
uv run containre run specimens/bin/filewriter --net deny --decoy wallet.datUse the dashboard for live event streams and post-hoc review of completed runs.
Goal: decrypt HTTPS C2-like traffic in the simulated sink.
uv run containre run specimens/bin/httpsbeacon --net simulate --mitm
uv run containre show <run_id> --events --kind netExpected result: HTTPS events that include decoded request information. TLS MITM is detectable by real malware and is intentionally opt-in.
Goal: inspect authorized TLS traffic to a real allowlisted service by hooking
OpenSSL SSL_read and SSL_write inside the specimen process.
Use TLS Plaintext Capture for the detailed workflow. This is different from TLS MITM: the remote service remains real, and the capture happens before encryption and after decryption in the client process.
Goal: rerun a service-dependent specimen without letting it contact any outside machine.
First capture an authorized, narrowly allowlisted real exchange with OpenSSL plaintext observation. Then infer an offline sink fragment:
uv run containre infer-h2-grpc-replay /path/to/tls_plaintext_capture.logFor a low-overhead rerun where Docker isolation and the emulator remain enabled but ptrace/snapshots/detectors are turned off:
uv run containre infer-h2-grpc-replay /path/to/tls_plaintext_capture.log \
--service-host service.example.internal \
--service-port 443 \
--no-trace \
--assert-no-egressUse the generated network.sink.type: h2-grpc-replay policy fragment with
network.docker_network: none, rerun the specimen, and compare outputs against
the real baseline. The report's network.real_allowed_remote_endpoint_event_count
metric should be 0.
Use Offline Service Emulation for the full workflow and interpretation checklist.
Goal: run one batch driver inside one isolated Docker namespace, with local helper services and an offline service emulator.
Use policy runtime.setup_commands to start local helper services, run the
batch driver as the specimen, and keep Docker networking disabled. For repeated
low-overhead no-trace batches, add:
runtime:
docker_reuse_container: true
docker_reuse_key: batch-screenUse Batch Runs and Helper Services for the full policy shape, limitations, and benchmark guidance.
Goal: record per-instruction disassembly and register/memory deltas.
uv run containre run specimens/bin/l2demo --l2 singlestep --l2-max 64
uv run containre show <run_id> --events --kind instr --limit 20Single-step tracing is faithful but slow. Keep windows small and use it after L1 events tell you where to focus.
Goal: emulate an isolated region seeded from the live process.
uv run containre run specimens/bin/l2demo --l2 unicorn --l2-region 0x401000:0x401028
uv run containre show <run_id> --events --kind instr --limit 20Use Unicorn mode for function-level algorithm or unpacking analysis. It is useful for exploration, but it can diverge from full OS behavior.
Goal: answer questions such as "who calls this symbol?" without manually
copying objdump output into notes.
Run or choose a completed specimen run, then extract static evidence:
uv run containre static <run_id>
uv run containre callers <run_id> connect
uv run containre callees <run_id> mainThe analysis is cached under the run directory as static/static.json. The
dashboard also has a Static tab: search for a symbol or name fragment to see
matches, callers, callees, strings, and a compact call graph.
Use --refresh when the target binary changed or when you want to recompute the
artifact:
uv run containre static <run_id> --refreshStatic call graphs are conservative. Confirmed edges come from direct disassembled calls. Indirect calls, vtables, plugins, and dynamic dispatch may need manual review or deeper tooling.
Goal: run with the safer backend.
uv run containre run /path/to/specimen --runtime docker --net deny --timeout 120Use docker for real suspicious binaries. Keep the control API bound to localhost
and use restrictive policies first: --net deny, short timeouts, and decoys only
inside the work directory.
Goal: make a reproducible run configuration.
Copy contracts/examples/policy.example.yaml
and edit specimen.path, network, files.decoys, and trace.
For installed applications that need a dependency tree, add a Docker-only
read-only mount. If the launcher expects to run from its installed path, also
set specimen.container_path:
specimen:
path: /opt/vendor-suite/tool
container_path: /opt/vendor-suite/tool
files:
read_only_mounts:
- { source: /opt/vendor-suite, target: /opt/vendor-suite }Then run:
uv run containre run path/to/policy.yamlThe effective policy is persisted into the run directory as policy.yaml, so the
run can be reviewed or reproduced later.
Goal: make a completed run machine-checkable.
Add report assertions to a policy:
report:
assertions:
- id: no-real-egress
subject: network.allowed_remote_endpoint_event_count
op: eq
value: 0
severity: critical
- id: no-result-artifacts
subject: artifacts.names
op: none_match
value: ["*.csv", "*.zip", "*.json"]Then summarize and persist the report:
uv run containre summarize <run_id> --write-report --fail-on-assertionsUse this pattern for repeatable no-egress/no-output regression checks around suspicious or proprietary specimens.
Run unit tests only (the default):
./run_tests.shRun the specimen/docker integration suite as well (rebuilds specimens first):
./run_tests.sh --integration # unit + integration
./run_tests.sh --only-integration # integration onlyRun the full Python suite directly:
uv run pytestDocker integration tests auto-skip when Docker is unavailable.
