Projects

OT Triage

Now / Next / Never triage for OT/ICS vulnerabilities

Most vulnerability scores come from IT thinking: a high CVSS number means “patch it”. In an OT environment the better question is what do I do about this one, on this asset, given what protects it. I built OT Triage to answer that question and to show its work.

You give it a CVSS score or a full CVSS vector, optionally a CVE, and what you know about the asset: how critical it is, how exposed, whether a patch exists and what controls protect it. It answers NOW, NEXT or NEVER, and lists the reasons in plain language. It also shows the single change that would move the answer, so the logic is easy to explain to someone else.

The Assess view: a crown-jewel asset with an actively exploited vulnerability is NOW, with the reasons, CISA's required action and its reference links

An actively exploited CVE on an exposed crown-jewel asset: NOW, with the reasons and CISA's own guidance.

What it does

The Batch view ranking fifteen findings, with the selected row's reasons, CISA references and the ICS advisories that name its CVE
Batch: rank a whole spreadsheet and see the references behind each row.
The Batch view grouped by asset: the worst bucket on each asset and what could be handled on one outage window
By asset: the worst thing on each asset, and what to handle on one visit.
The Assess view for an actively exploited firewall flaw on a crown-jewel asset, with the CISA ICS advisory that names it and the vendor's own mitigations and fix
CISA's advisory for the CVE, with what the vendor says to do about it.
The Assess view in the light theme
A light theme, adjustable text size and keyboard shortcuts.

Built to be trusted

It is a security tool, so it is tested like one. The project has a written security test plan with archived reports, tests that feed it hostile files and hostile network responses, property-based fuzzing, and automated checks on every change (Linux and Windows, static analysis and a secret scan). It is pure Python with no third-party dependencies, so there is no dependency tree to audit.

The Now / Next / Never categories come from the framing Dragos has used in its annual ICS/OT Year in Review. The definitions and scoring rules here are my own and are documented in the repository.

View on GitHub Read the README

Get it

The current version is 0.10.0. Each release has a portable bundle (ot-triage-0.10.0.zip) with a checksum file next to it. Unzip it anywhere and, on Windows, double-click OT Triage.pyw; everywhere else run python3 ot_triage_gui.py. It needs Python 3.12 or newer with Tkinter, and nothing else: no third-party packages and no .exe. The bundle is reproducible, so anyone can rebuild it from the tag and compare the checksum, and from 0.9.0 on it carries a signed build attestation that gh attestation verify can check.

If you are looking for places to learn more about OT security, there is also a curated list of free OT/ICS resources.

MIT licensed code. The OkieOTSec name and logo are not part of that license.