The Factory Floor That Wasn't: The ICS Census That Turned Into a Decoy Signal
Dressing an ordinary cloud server up as a power plant costs about four dollars and twenty minutes of an evening. Behind most of the industrial badges in this story there is no controller at all, just a rented Linux box wearing them. So the usual headline, that there is a scary amount of industrial gear exposed on the internet, is half right. There is a scary amount of something, and I wanted to map that something cleanly.
The plan was a census. Take the exposed population across three vendors on Censys, Schneider, Siemens and Rockwell, and sort it into three honest buckets. What Censys already flags as a honeypot. What it has not flagged but that looks like a decoy anyway. And what is a real device answering for itself. Count each bucket its own way, never mix them, and you have an honest picture of how much of the exposed factory floor is actually a factory floor.
The middle bucket is where the study went sideways in a useful direction. When I went to confirm the unlabeled likely decoys, most of them turned out not to be ICS at all. They were ordinary web hosts, cameras and VPN portals and dashboards, that happened to be fronting as several competing vendors at once. That was not what I went looking for, and it turned out to be the interesting part, because the thing that gave them away, one key signing certificates for competing vendors, is a clean and reusable way to surface likely decoys the honeypot label does not yet reach. The census I planned became the setup for a detection signal I did not, and the rest of this post is mostly that signal, checked by hand and with a script you can rerun.
The short version
- I set out to census exposed ICS across Schneider, Siemens and Rockwell and split it into three buckets, counted three separate ways and never summed: labeled honeypots, unlabeled likely decoys, and real devices.
- The middle bucket is where it got interesting. At least 146 hosts outside the current honeypot label were wearing ICS vendor certificates over ordinary web services, cameras, VPN portals, routers and dashboards. The certificates themselves were fabricated, one key signing for competing vendors, so the industrial identity was a costume. The web service underneath was usually real. The badge on top was not.
- That accident became the finding, a reusable signal. One key signing certificates for competing vendors flags these decoys cleanly, fired on 146 of 146 of them, and runs entirely off certificate fields Censys already publishes. All 146 sit on AWS.
- Real ICS lives on carrier lines. A read only protocol probe confirmed at least 79 genuine devices, 78 Allen-Bradley over EtherNet/IP and one Schneider Modicon over Modbus. Every one sat on a telecom or utility network. None were in the cloud.
- Proven. The certificates on the 146 are fabricated and each host is a decoy by construction. One machine minted certs for companies that do not share a signing key. That is certificate math, not opinion.
- Associated, not proven. Single origin certs per host and an identical build template across the set are consistent with one operation or one toolkit. That is a strong association. It is not proof that one key ties every host to one hand, and I will not claim it.
- Inference, not finding. That these decoys are honeypots specifically. The shared key proves fabrication and decoy by construction. Intent is a strong hunch I keep labeled as a hunch.
Why I bothered
A costume matters because people count the costumes. Reports that tally exposed industrial systems by scanning for vendor banners and vendor certificates will happily fold these 146 into a number that then gets read as real risk to real plants. If a large slice of the exposed factory floor is scenery, the honest thing is to tell the scenery from the buildings before anyone budgets around the count. The good news is that the difference is cheap to see, and it never requires kicking a door.
How I got here
The finder is a single Censys query, and I am going to describe it rather than print it. In plain terms it asks for hosts whose certificate issuers name two of the big three competitors at once, the Schneider, Siemens and Rockwell issuer strings, and it drops anything Censys already flags a honeypot so I am only ever looking at the unlabeled pile. I am keeping the exact field and string form out of the post on purpose. A copy ready finder is also a copy ready evasion recipe, and the point of this piece is the method, not a signature for operators to design around. Anyone on a scanner or research team who wants the literal query can reach me.
Two things about that finder, so nobody thinks it does more than it does. It is a candidate selector, not the proof. All it returns is a list of hosts whose certificate issuers name two competitors at once. The proof comes in the next step, when I pull each candidate and check whether one key actually signed those competitors' certificates. I key Rockwell on the certificate organization field rather than a single product string, so it catches both the plain company name and the variant with a corporate suffix that some of these certs carry. Widen or narrow those vendor strings and the count moves, which is the honest way to say the 146 is a floor tied to one specific finder, not a universal total.
This snapshot returned 146 hosts. Every one of them lives on AWS, 139 on AMAZON-02 and 7 on AMAZON-AES. Hold that in your head, because it is half the whole story before we even open a host.
One host, opened all the way up
The fastest way to feel why these are costumes is to sit with one. Meet 15.165.xxx.xxx, an AMAZON-02 box in Incheon. Censys reads its operating system as Axis Camera Firmware and hangs seven everyday labels on it, camera, IoT, login page, remote access, VPN, web server. It runs nine services, all of them plain HTTP over TLS, and not one speaks an industrial protocol. What it does carry is eight certificates that read like a trade show badge rack.
15.165.xxx.xxx AMAZON-02 Incheon, KR OS read as "Axis Camera Firmware"
port the real service behind it the certificate it wears
1234 Dask dashboard (Tornado) CN=Experion, O=Honeywell
1963 Cambium router login (Boa) CN=Rockwell Automation Certificate Authority
4839 "system-admin-agent" at /a2a CN=Unity Pro, O=Schneider Electric
4840 FortiManager login (miniupnpd) CN=Honeywell PKI Certificate, O=Honeywell
6003 Axis camera page (Apache) CN=SCADA-Server
8088 "mcp-server" at /mcp (plain HTTP, no cert)
11101 GlobalProtect VPN portal CN=SIMATIC WinCC, O=Siemens
11885 GlobalProtect VPN portal CN=OPC-Server
39075 Axis camera page (Apache) C=US, O=Tridium, CN=Niagara4
Read the two columns against each other. Taken one at a time, most of these pairings could almost pass. Real vendors do ship web logins, VPN portals and dashboards, so a single service sitting under a single vendor badge is nothing unusual on its own. What does not add up is all of it at once. This one host is fronting as Honeywell, Siemens, Schneider, Rockwell and Tridium across its ports at the same time, and no single real device belongs to five competing vendors at once. It is also a rented AWS box, not a piece of gear in a plant. Either fact on its own might have an innocent story. Both together do not, and the certificate math below settles it.
system-admin-agent at /a2a that advertises system administration style skills, and an mcp-server at /mcp. Treat those as bait. Never point automated agent tooling at a stranger's /a2a or /mcp. My probes never touched either one. I read the service banners the scanner already had and left them alone.
The tell that unmasks the costume
A rack of mismatched badges is suggestive. It is not proof, because a determined defender could argue that some odd honeynet legitimately presents many vendor names. So I stopped trusting the words printed on the badges and went to the one thing on a certificate that cannot be forced into agreement.
I lined up the stamps on the exemplar host by hand, one row per port, and watched two of them do all the signing.
# host 15.165.xxx.xxx, per port: the cert issuer, and the SPKI key that stamped it
port issuer CN / O SPKI key
1234 Experion / Honeywell KEY_A
4840 Honeywell PKI Certificate / Honeywell KEY_A
6003 SCADA-Server KEY_A
11101 SIMATIC WinCC / Siemens KEY_A
1963 Rockwell Automation Certificate Authority KEY_B
4839 Unity Pro / Schneider Electric KEY_B
11885 OPC-Server KEY_B
39075 Niagara4 / Tridium KEY_B
# KEY_A stamped both a Siemens cert and a Honeywell cert
# KEY_B stamped Schneider, Rockwell and Tridium certs
# competing vendors never share a signing key, so one machine minted both
A signal that extends the honeypot label
Censys labels honeypots by pattern matching against its scan data, and it does that carefully and on purpose. It even separates true honeypots from tarpits and scanner bait in its own writing. That precision is exactly right, a label you can trust is worth far more than one that fires on everything. What it leaves is room for a complementary signal, and the useful part of this whole study is that there is a clean, cheap one available, computed entirely from data Censys already publishes.
I did not take my own eyeballs on one host as proof of a pattern. I wrote a small script that groups every certificate on a host by its actual public key, maps each issuer to a vendor family, and flags any key that signed for two or more competing families. Then I ran it across all 146.
python3 spki_audit.py hosts --full
hosts analysed: 146
hosts with a key crossing 2+ competing vendors: 146 of 146
51.49.xxx.xxx <key> -> GE, Rockwell, Schneider, Tridium
15.222.xxx.xxx <key> -> GE, Honeywell, Rockwell, Schneider
18.61.xxx.xxx <key> -> Emerson, Honeywell, Schneider, Siemens, Yokogawa
15.165.xxx.xxx KEY_A -> Honeywell, Siemens
15.165.xxx.xxx KEY_B -> Rockwell, Schneider, Tridium
99.79.xxx.xxx <key> -> ABB, Emerson, GE, Honeywell, Mitsubishi, Rockwell,
Schneider, Siemens, Tridium, Yokogawa
... (146 of 146 carried it)
Every host in the set had at least one key that signed for competing vendors. Plenty of them go further than the exemplar. On the busiest, a single key had signed certificates for ten competing vendors at the same time, from ABB to Yokogawa, the whole industry stamped by one machine.
The signal is strong, so let me fence in exactly what it proves. It proves the certificates are fabricated, one machine minted certs for companies that do not share a secret, which is a fact and not an opinion. That makes each of the 146 a decoy by construction, again a fact. What it does not prove is why. I cannot tell you from a certificate whether a given box is a classic honeypot, a scanner trap, or somebody's research rig, so I stop at decoy and treat the honeypot read as a strong hunch rather than a finding. For a scanner like Censys the appeal is the precision. This is a cheap query over fields it already publishes, it surfaces at least 146 unlabeled likely decoys, and it did not misfire once in the batch I checked by hand.
What Censys already calls them
It is only fair to show what Censys does tag these hosts as, because the labels it already applies are accurate and genuinely useful. So I extended the same pull to grab every label on all 146 and tally them, which is a small script anyone can rerun against the same query to confirm what follows.
| Censys label carried by the 146 | Hosts of 146 |
|---|---|
| LOGIN_PAGE | 145 |
| VPN | 95 |
| REMOTE_ACCESS | 93 |
| WEB_SERVER | 90 |
| CAMERA | 87 |
| IOT | 87 |
| ROUTER | 86 |
| ELECTRICAL | 13 |
| POWER_METER | 11 |
| MEDICAL | 10 |
| BUILDING_AUTOMATION | 9 |
| HONEYPOT | 0 |
Two things jump out. Nearly every host, 145 of 146, is a login page of some kind, and most are cameras, VPN portals, routers or plain web servers, the everyday furniture of the internet. A handful also pick up heavier labels, 13 ELECTRICAL, 11 POWER_METER, 10 MEDICAL and 9 BUILDING_AUTOMATION, all accurate descriptions of what the boxes present on the wire. Those surface labels do their job well. The shared key signal simply works one layer down, on how the certificates were built, so it layers on top of what Censys already reads rather than competing with it. A box can be a genuine looking login page on the surface and a decoy underneath, and both readings are true at once.
The software underneath tells the same story from another angle. The same small handful of internet facing login pages repeats across the whole set, Apache on 104 of the 146, a Palo Alto GlobalProtect portal on 93, the Boa web server that ships on real cameras and routers on 90, Atlassian Confluence on 86. Real vendor gear runs web front ends too, so none of these is damning on its own. What stands out is that the same wardrobe of common login pages, the kind attackers probe all day, turns up host after host, which reads like one shared kit rather than 146 independent devices each dressed by hand.
What the decoys are dressed up as
Bucket the 146 by the vendor strings in their certificates and the wardrobe is enormous. These are distinct host counts, so no host appears twice in a row, but a single host wears many rows at once.
| Badge in the certificates | Hosts of 146 |
|---|---|
| Generic ICS strings like SCADA-Server, OPC-Server, HMI and PLC | 118 |
| Rockwell | 114 |
| Siemens | 104 |
| Schneider | 103 |
| Emerson | 49 |
| ABB | 49 |
| GE | 48 |
| Yokogawa | 48 |
| Tridium | 39 |
| Honeywell | 35 |
| Mitsubishi | 12 |
The top three, Rockwell, Siemens and Schneider, are no surprise, because the query itself demanded two of those three. The tell is everything stacked below them. The ABB, Emerson, GE, Yokogawa and Honeywell badges were never asked for, and a single real device would never present them all at once. The most common badge of all is not even a brand, it is a generic SCADA-Server or OPC-Server string riding on well over a hundred of the hosts. No box sticks to one costume, which is why these add up to far past 146 even though only 146 hosts are in the set.
The real devices, and where they live
A census needs the other end too, the genuine article. So I ran a read only identity probe against the Rockwell EtherNet/IP candidates, the kind of query a real controller answers by stating its own vendor and product code. Here is one run, redacted.
# read only CIP List Identity against the carrier EtherNet/IP candidates. no session, nothing written.
$ python3 enip_identity_probe.py --targets carrier_eip.txt --read-only
# IPs and serials redacted. one line per host that answered.
<REDACTED> -> vendor='Rockwell Automation/Allen-Bradley' PLC product='1766-L32AWA C/21.07' rev 2.21 serial <REDACTED>
<REDACTED> -> vendor='Rockwell Automation/Allen-Bradley' PLC product='1769-L33ER/A LOGIX5333ER' rev 36.12 serial <REDACTED>
<REDACTED> -> vendor='Rockwell Automation/Allen-Bradley' PLC product='ControlLogix 5580 Controller' rev 33.17 serial <REDACTED>
<REDACTED> -> vendor='Rockwell Automation/Allen-Bradley' PLC product='Emulate 5580 Controller' rev 38.11 serial <REDACTED>
------------------------------------------------------------------------
Done. 87 carrier EtherNet/IP candidates probed.
78 Allen-Bradley identities (77 physical PLCs, 1 software emulator)
1 other vendor identity
8 unreachable
That is 78 genuine Allen-Bradley identities coming back over EtherNet/IP, real MicroLogix, CompactLogix and ControlLogix controllers, plus one that openly labels itself a software emulator. On Modbus, one more host returned a real Schneider Modicon identity. That is at least 79 confirmed real, and every one of them sat on a carrier, telecom or utility network. None were in the cloud. I say at least 79, not only 79, because a probe confirms what answers and stays silent about what did not.
Zoom out from my confirmed 79 to the whole population Censys already sees answering EtherNet/IP on 44818, more than seven thousand hosts, and the same shape holds. Group them by network and the carriers run the table.
| Network answering EtherNet/IP on 44818 | Hosts | Share |
|---|---|---|
| Verizon | 2,295 | 30% |
| AT&T Mobility | 650 | 8% |
| TELUS | 304 | 4% |
| Telefónica de España | 298 | 4% |
| Korea Telecom | 194 | 3% |
| Orange | 157 | 2% |
| Bell Canada | 155 | 2% |
| Deutsche Telekom, Telecom Italia, Comcast, Vodafone, T-Mobile, Telstra, Rogers and a long carrier tail | more | |
| Akamai and Alibaba, the cloud entries, and mostly Conpot honeypots | ~1,000 | 13% |
| Amazon, home of all 146 cert decoys | 24 | <1% |
That is the exact opposite of the decoy crowd, and it is the cleanest signal in the study. Genuine gear that speaks EtherNet/IP sits out where factories actually connect from, on telecom and utility lines, with Verizon alone carrying nearly a third of it. The cloud does turn up, but look at who. The Akamai and Alibaba boxes are largely emulators and Conpot style honeypots rather than real controllers. And Amazon, the home of every one of the 146 cert decoys, sits at the bottom with two dozen, because the decoys answer HTTP on this port rather than the protocol they dress up as.
What is proven, what is associated, what is not
Here is the whole thing sorted into tiers, so nobody has to guess which brick carries which load.
Proven
The 146 hosts carry fabricated certificates and each is a decoy by construction. On every one, at least one signing key stamped certificates for two or more competing vendors, which no honest device or vendor does. The audit fired on 146 of 146, and I confirmed the exemplar host by hand. Separately, at least 79 genuine devices answered a read only protocol probe with coherent vendor identities, and every one lived on a carrier, telecom or utility network. All 146 decoys sit on AWS. All 79 real devices do not.
Associated, not proven
The 146 look like one operation or one toolkit. Each host's certificates trace back to a single origin on that host, and the build template repeats across the set, the same fabricated wardrobe stapled to the same kind of ordinary web box. That is a strong association, consistent with a single operator or a single kit spun up wherever there was cloud capacity. It stops short of proof, because I recovered no one key that ties all 146 hosts to one hand, and I will not narrate one into existence.
Inference, and I keep it labeled as one
That these decoys are honeypots specifically. The certificate math proves the badges are fabricated and the hosts are decoys by construction. Whether any given one is a classic honeypot, a scanner trap, or a research rig is an intent question a certificate cannot answer. I read the wardrobe of attacker bait login pages as leaning honeypot, and I keep that a strong hunch rather than dressing it up as a finding.
The ceiling I will not publish as a number
The tight finder returned 146, and I stand behind every one of them cert by cert. A looser search for any single ICS vendor certificate sitting over ordinary AWS web services returns a much larger pile, on the order of hundreds more, that looks like the same cert theater. I am not putting that bigger number in the headline, because I only ran the shared key test to completion on the 146. Treat the 146 as a confirmed floor and the wider pile as a ceiling that fits the pattern but stays unverified. The number I can defend cert by cert beats the bigger number I cannot.
The signal, as a tripwire
Throwaway infrastructure gets rebuilt the moment it burns, so the durable value is in the check that survives a redeploy. The certificates rotate, the labels drift, the hosts get wiped. The one thing that stays true is the arithmetic: a single key signing for competing vendors is fabrication, full stop. That makes it a clean tripwire. Group certificates by public key, map issuers to vendor families, and flag any key that crosses two or more competitors. It runs off fields Censys already records, it surfaced at least 146 likely decoys the honeypot label does not yet reach, and it did not misfire once in the batch I checked by hand. That is the kind of cheap, reproducible signal worth feeding a label.
Most of this is reproducible from the description alone. The candidate finder is the certificate search I
described above, held back only in its exact string form. The label tally and the shared key audit are two
small scripts that read the pulled host JSON and print the same numbers you just read. The real device side is
a read only identity probe and a public facet on host.services: (port=44818 and protocol="EIP"),
which finds genuine gear rather than decoys, so it stays in the open. Rerun any of it and diff against my
counts.
The honest wrap up
I set out to count a census and walked out holding a detection signal, which turned out to be the better souvenir. The plan was three clean buckets, labeled honeypots, unlabeled likely decoys, and real devices. The middle bucket refused to be ICS, and that refusal was the gift. Most of those hosts were ordinary cloud boxes in factory costumes, and the thread that unmasked them, one key signing for competitors that would never share a key, is a cheap and reusable way to spot the next batch of decoys before anyone counts them as real risk.
The pieces that will still be true after these exact boxes are gone are the certificate math and the geography. A costume can change its badges, its labels, and its address overnight. It cannot make a real key sign for two competitors, and it cannot move a rented cloud box onto a carrier's factory lines. So if you count exposed ICS, stop trusting the costume. Ask a box to say its own name in its own protocol, and read how its certificate was built rather than what it says on the front. When I did that, the real factory floor turned out to be a lot smaller, and a lot further from the cloud, than the badges wanted me to believe.
Indicators and reproduction
The candidate finder (returns 146; all on AWS)
method Censys certificate search: issuer names two competing ICS vendors on one host
(Schneider + Siemens + Rockwell issuer strings), excluding HONEYPOT-labeled
Rockwell keyed on the issuer organization field to catch name variants
exact query withheld on purpose (a copy-ready finder is a copy-ready evasion recipe);
available to scanner / research teams on request
result 146 hosts 139 AMAZON-02 + 7 AMAZON-AES 22 countries
Exemplar decoy host
15.165.xxx.xxx AMAZON-02 Incheon, KR OS read as "Axis Camera Firmware"
labels CAMERA IOT LOGIN_PAGE REMOTE_ACCESS VPN WEB_SERVER (no HONEYPOT, no ICS)
9 services all HTTP over TLS; none speak an industrial protocol
2 SPKI keys KEY_A -> Honeywell + Siemens certs
KEY_B -> Schneider + Rockwell + Tridium certs
bait /a2a "system-admin-agent" (port 4839), /mcp "mcp-server" (port 8088) -- do not touch
The shared key signal (proven; 146 of 146)
test group each host's certs by public key (SPKI / RSA modulus),
map issuer -> vendor family, flag any key crossing 2+ competing families
result 146 of 146 hosts carry a crossing key
extreme case one key on one host signed for ABB, Emerson, GE, Honeywell, Mitsubishi,
Rockwell, Schneider, Siemens, Tridium and Yokogawa at once (ten competitors)
not explained by CVE-2022-38465 (Siemens hardcoded key) -- that is WITHIN-vendor reuse only
scripts pull_labels.py (label + software + network + country rollups)
spki_audit.py (the crossing audit; run: python3 spki_audit.py hosts --full)
Real devices (at least 79; all carrier / utility)
probe read only CIP List Identity (EtherNet/IP) and Modbus identity
confirmed 78 Allen-Bradley over EtherNet/IP (77 physical PLCs + 1 software emulator)
1 Schneider Modicon over Modbus
= at least 79 real, every one on a telecom or utility network, none in cloud
real EtherNet/IP population facet host.services: (port=44818 and protocol="EIP")
~7,696 hosts; Verizon 2,295 (30%), AT&T 650, TELUS 304, Telefonica 298, ...
Amazon 24 (<1%) <- decoys answer HTTP on 44818, not EIP
cloud EIP Akamai/Linode and Alibaba entries are largely Conpot honeypots (already flagged)
Durable tells (survive a rebuild)
certificate math one signing key across 2+ competing vendor certs on one host = fabricated
geography real ICS answers its own protocol on carrier/utility ASNs;
AWS "ICS" answers HTTP and is costume
label gap seed ICS vendor certs over ordinary web software, on AWS, with no HONEYPOT label
scope note 146 = confirmed floor (this query); wider "cert theater" pile = unverified ceiling