A Routine Pen Test Found a Zero-Day. The Vendor Response Was the Real Lesson.
This was supposed to be a routine external penetration test. Within minutes, it was not.
A colleague on our pen test team was running asset discovery when he flagged an internet-facing HMI tied to industrial control systems. At first, it looked like one more exposed web interface on a non-standard high port. He brought it to me to take a closer look. A few HTTP headers, a favicon hash check, and a handful of targeted requests later, it was clear this was a commercial off-the-shelf HMI product.
That changed the engagement. A vulnerable customer system is one thing. A vulnerable product deployed across hundreds of environments is something else entirely.
What started as a routine engagement turned into 14 critical and 14 high findings, including one critical issue that only surfaced after I figured out how the product handled stored passwords.
This post walks through what we found, how we confirmed the vendor and product, why the vulnerability mattered, how disclosure went, and why the real lesson was not just the bug. It was the gap between a vendor saying “patched” and operators actually being protected.
The engagement
The scope looked familiar, and the first pass looked like many external tests we run every year. Then asset discovery surfaced that one host. The web interface served on a non-standard high port with no authentication prompt at the landing page. The HTTP response headers, favicon hash, and JavaScript bundle paths all gave away that this was a commercial off-the-shelf HMI product rather than something custom-built. Service fingerprinting through Nmap and a few targeted requests against well-known vendor-specific paths confirmed the product family within minutes.
Vendor attribution in OT engagements is rarely the hard part. Vendors leave fingerprints everywhere: in HTML comments, in JavaScript namespaces, in default endpoints, in the structure of error responses, in the X-Powered-By and Server headers that vendors rarely strip from their builds. The harder part is what happens after attribution. To understand the risk, I needed the same thing an attacker would want: a working copy of the product.
Acquiring the product
For most commercial software, acquisition is straightforward. Vendor trial downloads, public documentation, archived installers on third-party repositories, and shipped firmware images recovered from physical devices all give you what you need to start static analysis. In this case, the installer was publicly available, registration-gated but not meaningfully access-controlled. Within an hour I had the product running in an isolated VM, with full filesystem access to its install directory and the ability to instrument every API call it made.
Two notes for OT defenders reading along. First, “obscure” does not mean “secure.” Any product deployed in hundreds of environments has been reverse-engineered by someone, and you should assume the same is true for the vendor products in your stack. Second, the gap between vendor trial download and full local instrumentation is short enough that the only thing standing between a curious attacker and your product internals is the attacker’s willingness to spend a Saturday afternoon on it.
The vulnerability
The flaw was straightforward once the product was running locally. An undocumented HTTP endpoint, exposed by default on the same web server that hosted the legitimate operator UI, accepted commands that the documented interface required authentication to issue. It trusted the request simply because the request existed. Send the right POST body to the right path and the backend control system executed the instruction.
For an OT audience: the commands available through this endpoint included the ones you would expect a vendor to gate carefully. Register reads and writes against the underlying PLCs. Configuration modifications. In some deployments, the ability to push parameter changes that would meaningfully alter the physical process being controlled. The endpoint existed in every deployment of the product I tested against, including the customer environment that started the engagement.
The scope
This is the moment in a finding when the calculus changes. A vulnerability in one customer’s environment is a finding. A vulnerability in a product deployed across hundreds of customer environments is an industry problem.
Shodan and Censys both index the product’s distinctive HTTP signature. The internet-facing population alone was in the high hundreds. That undercounts the real exposure substantially, because most deployments of this product class sit behind firewalls or VPN concentrators that obscure them from internet-wide scans. The customers who run them include water utilities, manufacturing plants, energy distribution operators, and the kind of mid-tier critical infrastructure that does not always carry a CISA designation but absolutely matters when it fails.
The disclosure
We followed the process the security community has spent two decades building. The vendor was notified through their published security contact. We provided a technical writeup, proof-of-concept code, and a remediation recommendation. We agreed on a disclosure timeline that gave the vendor time to develop and ship a patch.
The vendor acknowledged the finding. They committed to a fix. A patch was released within the agreed timeline.
The patch was partial.
The remediation gap
The vendor did release a patch within the agreed timeline. That part is good.
The problem was that the fix was incomplete. It addressed the endpoint we reported, but not an adjacent endpoint in the same web service that followed the same unauthenticated pattern. For existing customers, the protection also depended on a configuration change they had to know to enable. The release notes did not make the security impact clear enough for the average operator to understand what was at stake.
That is the remediation gap.
From the vendor’s perspective, a patch shipped. From the operator’s perspective, exposed systems were still exposed. From an attacker’s perspective, the window was still open.
This is the part I wish more OT defenders saw up close. Finding the bug was not the hard part. Getting from “the vendor shipped a patch” to “customers are actually protected” was the hard part. When a vendor’s incentive structure rewards minimum-viable patching over complete remediation, when the cost of an incomplete fix is borne by the vendor’s customers rather than by the vendor, partial remediation is the predictable outcome.
The AI acceleration context
I mentioned Project Glasswing in the SecDSM talk because it is one of several public efforts demonstrating that LLM-driven tooling can now find and weaponize this class of vulnerability faster than the manual workflow we followed.
The uncomfortable part is that the manual work we did here is exactly the kind of workflow AI-assisted vulnerability research is getting better at: fingerprint the product, acquire a copy, map the endpoints, compare documented and undocumented functionality, and test for missing authorization. None of those steps require human intuition that a sufficiently capable model cannot approximate.
The compression of the discovery-to-exploit window changes the math on vendor accountability. A vendor that ships a partial fix today is making a bet that no one else will find the rest before they get around to it. That bet was already aging poorly. It is going to age faster.
Three things to do this week
If you operate or defend OT environments running commercial HMI or SCADA products:
First, inventory your internet-facing OT assets honestly. Pull the data from Shodan, Censys, your own external scanners, and your egress logs. You need to know what is reachable from outside your perimeter before someone else tells you.
Second, ask every vendor whose product you run two specific questions in writing. What is your patch cadence for security findings, and what does your responsible disclosure process look like in practice? The answers you get will tell you which vendors take their part of the responsible disclosure contract seriously and which ones do not.
Third, build a detection and response plan that assumes the next zero-day in a vendor product you depend on will be partially fixed at best. Network segmentation, behavioral monitoring on industrial protocols, and clear escalation paths to your vendor’s PSIRT and to CISA’s ICS-CERT are the controls that buy you time when the patch arrives late or incomplete.
Closing
Finding the vulnerability was not the hardest part of this story. The harder part was watching how much risk remained after the patch existed.
OT operators depend on vendors for products they cannot always inspect, patch, or replace quickly. That means vendor accountability is not an abstract policy issue. It is part of the security boundary.
The full SecDSM presentation goes deeper into the technical path, and a Cyberside Chats episode focused on the disclosure timeline and vendor accountability lessons is coming soon. I will share both as they go live.
If your organization operates HMI, SCADA, or other OT systems and wants to understand where internet exposure, vendor risk, and incomplete patching intersect, LMG can help.