Coordinating ICS/SCADA module contributions - is there a direction for the scada/tree? #21830
Replies: 4 comments
|
Hi there, @ethan-thomason- I'm sorry to say it, but I don't believe anyone currently working on Metasploit is doing ICS work. The closest I get to that space is I do a bit of IoT/embedded hardware work on the Mettle/Linux Meterpreter POSIX payloads side (https://github.com/rapid7/mettle) , but nothing on the SCADA protocol side like what you've submitted so far. For the questions:
Not that I am aware of. There are several modules under
We have found sequential works best for the most part, though if you are planning on multiple submissions that use the same target that is hard to configure, let us know so we can make sure to keep the target after landing the PR. Anything with docker containers is wonderfully easy to work with, though we understand that's not always feasible. We also have had decent luck lately with pointing an AI at difficult and/or expensive hardware and asking it to create a protocol emulator in Python, since lots of IoT systems have limited interactions.
For ICS exploits, I think we just need to make sure we adhere to the same guidance as any exploit- document any risks, document the side effects, ensure we return the software to the original configuration or document the process for doing it manually, and if there's a legitimate chance of doing damage, use the |
|
Thanks - that's very useful information. On reusable targets: yes, and it's Docker. The work is all against Inductive Automation Ignition, which publishes an official image that commissions unattended: One wrinkle: the OPC-UA server is enabled by default but binds to loopback only, so it needs a bind address change in the gateway web UI before it's reachable off-host. That's documented in the For pure OPC-UA protocol testing I've also been using node-opcua and the Milo demo server in containers - Ignition only ever advertises secured endpoints, so I needed something offering an unsecured one to exercise the weak-endpoint path in #21829. The node-opcua recipe is a four-line Dockerfile plus a short server script, happy to share if it's useful for regression testing later. On emulators: that matches where I've ended up. I maintain a Python research toolkit for this ecosystem and several pieces of it are effectively protocol implementations already, so if something proves awkward to containerize I can probably produce an emulator rather than asking anyone to source hardware. On The complication is that restoring a gateway backup replaces the gateway's configuration - projects, tag providers, device connections, user sources. Against a production gateway that's destructive in a way you can't undo from inside the module, and unusually for an RCE the damage is to configuration rather than availability. I've read how One design question I'd like a steer on, since I couldn't find an analogue in tree: I'm considering having the module download the gateway's existing backup before restoring the malicious one, so the operator has a documented path back rather than just a warning. That's a read-only operation, so my instinct is to do it before the DefangedMode guard - meaning even a defanged run leaves the user holding a recovery copy. That seems more useful than failing with nothing, but it's unusual and I'd rather ask than surprise a reviewer. Does that sound reasonable, or would you rather the guard come first and the module do nothing at all in defanged mode? On evidence: noted on videos and scrubbed PCAPs. My lab is isolated and entirely mine, so I can supply full captures of the exchange for anything hard to reproduce. I did look through the older |
|
Great that docker is available for this, and honestly, kudos to Inductive Automation Ignition for letting the public help verify the security of their software!
I wonder if we could figure out a cURL command that does this programmatically?
Yes absolutely. Right now, the best place for this is within the module documentation; submissions of docker files are somewhat new- we have only started seeing them within the last year or so, but the python emulation scripts are something that has only really cropped up in the last few months. We have had a few discussions internally on where we should be putting docker files, setup scripts, and emulation scripts, but for now, we are just saying that all dockerfiles, commands, or setup scripts should be quoted within the module documentation. Personally, I'd like to see us figure out a place to put the scripts, but we have not yet reached a consensus on where that is, or what that means for maintainability and expectations.
100% agree. Defang is only there as a gate to drive home the user is purposefully and knowingly doing something that we thing is dangerous- absolutely agree downloading the backup is not only not dangerous, but highly encouraged. One thing to note- I noticed that your most recent PR #21829 has a lot in common with a previous PR- I saw your note on why, but if you are going to do a couple modules (and we hope you do!) you may want to think about offloading a lot of the commonality to a library so it is deduplicated and we can wire it up with easier rspec testing. |
Worked it out, and it's in the #21829 docs now. On 8.3.x the bind address is a gateway config resource reachable over the REST API, so it's a pure curl sequence - IdP auth chain, CSRF token, read the singleton config and PUT it back with bindAddresses set to 0.0.0.0. No browser, and the OPC-UA module rebinds immediately with no gateway restart. Verified against inductiveautomation/ignition:8.3 at build 8.3.9. One trap worth knowing about if your harness tries to confirm it: check the gateway log line The node-opcua target is in those docs too - Dockerfile plus server.js, quoted, package version pinned so the default endpoint set doesn't drift out from under it. That's the one that serves an unsecured endpoint, so it exercises the weak-endpoint path that Ignition can't reach. Both recipes are in the module documentation per your guidance, so the skill should have what it needs.
Agreed, and I'd rather do it before the next module than after. My inclination is to let #21829 land as-is and then open a separate PR that extracts the parsing layer - bounded binary reader, NodeId and ExtensionObject decoding, message framing and chunk assembly, EndpointDescription parsing, the policy and status tables - with rspec covering it, and ports both modules onto it. Socket handling and reporting would stay in the modules. That means modifying The testing half is the part I actually want. Two paths in the current module have never executed: chunk reassembly, because every response my lab produces fits in one chunk, and the ERR status decode. That second one is where you caught the bad status codes - they were wrong precisely because nothing ever triggered an ERR response to check them against. Fixture bytes test both directly, which a well-behaved server can't. On the third OPC-UA module (authentication testing) - I'll hold it until the library lands, so it arrives on top of something already reviewed and covered rather than adding a credential module and a library in one review. |
Uh oh!
There was an error while loading. Please reload this page.
I've contributed a few ICS-focused modules recently and would like to coordinate future work rather than guess at what's useful.
Background: I do ICS/SCADA integration as well as security research professionally, mostly around the Inductive Automation Ignition ecosystem and the MES/middleware that sits alongside it. Three modules so far:
auxiliary/scanner/scada/ignition_statusping(Add Ignition gateway fingerprint scanner (auxiliary/scanner/scada/ignition_statusping) #21603, merged)auxiliary/scanner/scada/opcua_enum(Add OPC-UA server detection auxiliary scanner module #21612, merged) - first OPC-UA coverage in the frameworkauxiliary/scanner/scada/opcua_endpoint_enum(Add OPC-UA protocol library and endpoint enumeration module #21829, open)The OPC-UA work started because
grep -ril "opc" modules/returned nothing. OPC-UA (IEC 62541) is the dominant interoperability standard in industrial automation and it had zero representation. More broadly thescada/tree has Modbus, BACnet, Profinet, Digi, Moxa and Koyo, which is a fairly thin slice of what's actually deployed on plant floors.What I have queued, roughly by readiness:
Questions:
scada/tree, or anything already in flight internally that I'd be duplicating?Also genuinely interested to hear from anyone else contributing in this space. ICS coverage seems to grow in bursts when someone with access to the gear shows up, and it would be good to know who else is around.
Thanks to @bwatters-r7 and @jheysel-r7 for the reviews on the first two - fast, thorough, and the feedback generalized well to everything I've written since.
All reactions