Unified ICS red team multi-tool - Rust edition.
Discovers, enumerates, and exploits devices across twelve industrial control protocols. Single binary with a terminal UI, bloodyAD-style CLI, and REST web interface.
- Active fingerprint and passive scan across 12 ICS protocols
- TUI, CLI, and REST web interface in one binary
- Authenticated and unauthenticated exploitation paths
- Protocol fingerprint randomisation - always-on, no flags needed
- Ephemeral-token web API - no credential file, no config
- ~300-entry ICS CVE reference database built in
- Local simulator suite (
sim/) for safe offline testing - Usable as a Rust library (
scadavercrate)
git clone https://github.com/Whispergate/scadaver
cd scadaver
cargo build --release
# binary: target/release/scadaverscadaver scan # sweep local network, all protocols
scadaver scan --protocol siemens -i 10.0.0.50 # targeted S7 fingerprint
scadaver get io -i 10.0.0.50 --protocol siemens # read digital I/O state
scadaver run fc90-stop -i 192.168.1.10 # unauthenticated Schneider stop
scadaver tui # interactive terminal UI
scadaver web --host 0.0.0.0 --port 8080 # REST API + browser UI| Protocol | Vendor | Port(s) | Discovery | Exploitation | Auth |
|---|---|---|---|---|---|
| S7Comm / ISO-TCP | Siemens | TCP 102 | COTP fingerprint, PDU info | I/O and DB r/w, CPU start/stop, password spray | optional password |
| ADS/AMS | Beckhoff TwinCAT | UDP 48899, TCP 48898 | broadcast NetID | run/config state, symbol r/w, add route | none (pre-4024) |
| Modbus TCP | Schneider / generic | TCP 502 | FC43 Device ID, UDP 1740 | FC1/3/4/5/6/16, false-data injection, rogue server | none |
| FC90 | Schneider M340/TM221 | TCP 502 | function-code probe | stop, start, force output bit | none |
| EtherNet/IP + CIP | Rockwell Allen-Bradley | TCP/UDP 44818 | ListIdentity broadcast | tag enumeration, tag r/w | none |
| SLMP / MC 3E | Mitsubishi MELSEC | UDP 5561, TCP 5007 | UDP broadcast | D/M register r/w | none |
| FINS | Omron SYSMAC | TCP/UDP 9600 | UDP broadcast | DM area r/w, CPU state | none |
| HTTP + IPCONF | HMS eWON Flexy | TCP 80, UDP 1507 | IPCONF UDP broadcast | auth-bypass credential extract (CVE-2019-9015) | HTTP Basic |
| ProConOS + WebVisit | Phoenix Contact | TCP 1962, 80/8080 | HTTP probe | password retrieval (CVE-2016-8366), tag r/w | HTTP Basic |
| SNMPv2c | generic | UDP 161 | community scan | GET, GETNEXT, walk, SET | community string |
| IEC 60870-5-104 | generic RTU/relay | TCP 2404 | TESTFR probe | GI dump, single command, double command | none |
| HTTP Basic | generic | TCP 80/443/8080 | TCP connect | default-cred spray, Shellshock (CVE-2014-6271) | configurable |
Six fields that previously fingerprinted the tool are randomised per-connection: Modbus MBAP
transaction ID, two Siemens S7Comm PDU references, Omron FINS SA1 source node, Beckhoff ADS
route hostname (OS hostname, never the tool name), and IEC 104 teardown (graceful FIN instead
of RST). These are always-on. Stealth mode (-z) adds probe-order shuffle and 100-400 ms
inter-probe jitter on top.
scadaver tui| Key | Action |
|---|---|
A |
Add IP |
S |
Scan menu |
E |
Exploit menu |
W |
References overlay |
R |
Rescan selected device |
D |
Delete selected device |
V |
VendorPicker (for multi-protocol devices) |
/ |
Search / filter device list |
O |
Zoom output panel |
C |
Clear output |
Z |
Toggle stealth mode |
? |
Help overlay |
Q |
Quit |
Sensitive and write actions require typing YES before execution. When multiple protocols
respond for the same IP, the device is stored as multi and V switches which protocol's
exploit list is active.
scadaver [OPTIONS] <COMMAND>Global flags:
| Flag | Short | Default | Description |
|---|---|---|---|
--ip <IP> |
-i |
Target host IP | |
--port <N> |
-p |
0 |
Override port (0 = protocol default) |
--timeout <N> |
-t |
5 |
Timeout in seconds |
--protocol <P> |
Protocol hint (siemens, rockwell, beckhoff, ...) |
||
--stealth |
-z |
off | Randomised probe order + inter-probe jitter |
scan - probe for ICS devices on the local segment or a single IP
get nouns:
| Noun | Description |
|---|---|
info |
Device identity and firmware (--protocol required) |
state |
CPU run/stop/monitor state |
io |
Siemens S7 digital inputs, outputs, merkers |
tags |
Tag or symbol list |
tag <name> |
Read one named tag |
register [start] [count] |
Modbus holding registers (FC3) |
input-register [start] [count] |
Modbus input registers (FC4) |
coil [start] [count] |
Modbus coils (FC1) |
dm [start] [count] |
Omron FINS DM area words |
db <db> [offset] [len] |
Siemens S7 data block bytes |
d [start] [count] |
Mitsubishi SLMP D word registers |
m [start] [count] |
Mitsubishi SLMP M bit devices |
community |
SNMP community string probe |
oid <oid> [-c community] |
SNMP GET single OID |
walk <oid> [-c community] |
SNMP GETNEXT walk |
enum |
SNMP system info, interfaces, topology |
gi |
IEC 104 General Interrogation |
creds |
eWON auth-bypass credential extract |
session |
Schneider legacy web-session compatibility check |
set nouns:
| Noun | Description |
|---|---|
state <state> |
CPU state: run/stop/monitor/config/flip (--protocol required) |
tag <NAME=HEXBYTES> |
Write one tag |
register <address> <value> |
Modbus holding register (FC6) |
registers <start> <values> |
Multiple Modbus holding registers (FC16) |
coil <address> <on|off> |
Modbus coil (FC5) |
output <bits> |
Siemens S7 digital outputs (binary string) |
merkers <bits> <offset> |
Siemens S7 merkers |
dm <start> <values> |
Omron FINS DM area words |
db <db> [offset] <data> |
Siemens S7 data block bytes |
d <start> <values> |
Mitsubishi SLMP D word registers |
m <start> <bits> |
Mitsubishi SLMP M bit devices |
oid <oid> <value> --community --type |
SNMP SET (--confirm required) |
sc <ioa> <on|off> |
IEC 104 Single Command |
dc <ioa> [state] |
IEC 104 Double Command |
run exploits:
| Command | Description |
|---|---|
reboot |
Beckhoff CX9020 reboot via UPnP/SOAP (CVE-2015-4051) |
add-user <credentials> |
Add admin user to CX9020 via UPnP/SOAP |
write-symbol <NAME=hexbytes> |
Write raw bytes to ADS symbol |
flash-led |
Schneider identification LED flash |
session-stop |
Schneider PLC stop via recovered legacy web session |
session-run |
Schneider PLC start via recovered legacy web session |
fc90-stop [--model m340|tm221] |
Unauthenticated Schneider FC90 stop |
fc90-start [--model m340|tm221] |
Unauthenticated Schneider FC90 start |
fc90-force [--output] [--state] |
Force physical output bit on M340 |
passwords |
Retrieve Phoenix Contact WebVisit passwords (CVE-2016-8366) |
ewon-creds |
eWON auth-bypass credential extract |
portscan [--ports] |
TCP connect scan for common ICS ports |
shellshock [--http-port] |
Shellshock scanner on PLC/HMI web CGI (CVE-2014-6271) |
default-creds [--path] |
HTTP Basic Auth default-credential spray |
fdi |
False Data Injection - continuous Modbus write loop |
modbus-server |
Rogue Modbus TCP server (no -i needed) |
db commands:
| Command | Description |
|---|---|
db add --ip <IP> [--vendor] |
Add a device to the database |
db remove --id <id> |
Remove a device by ID |
db refs [--vendor <slug>] |
List embedded ICS research references |
scadaver web # 127.0.0.1:8888
scadaver web --host 0.0.0.0 --port 9000A 32-character hex token is generated at startup and printed to the terminal. The browser
opens automatically at http://host:port/?key=<token>. REST clients send X-API-Key: <token>
on protected endpoints (scan, device tags, tag write, all exploit routes). The token is
ephemeral - a new one is generated each run.
Endpoints that do not require authentication: GET /health, GET /api/devices,
GET /api/devices/:ip/history.
~300 publicly disclosed ICS vulnerability writeups embedded in the binary, sourced from awesome-ics-writeups. Entries from Claroty, ZDI, Nozomi Networks, Microsoft, Dragos, and others.
TUI: press W. CLI: scadaver db refs [--vendor <slug>]
| Slug | Covers |
|---|---|
beckhoff |
Beckhoff, TwinCAT, ADS |
siemens |
Siemens, SIMATIC, S7, SCALANCE, SINEC, TIA Portal, PROFINET |
schneider |
Schneider Electric, Modicon, M340/M580/M221, EcoStruxure, UMAS |
rockwell |
Rockwell, Allen-Bradley, FactoryTalk, RSLogix, ControlLogix |
mitsubishi |
Mitsubishi, MELSEC, SLMP, GX Works |
omron |
Omron, SYSMAC, CX-Programmer, FINS |
phoenix |
Phoenix Contact, ProConOS, PLCnext |
ewon |
eWON, HMS Networks |
modbus |
Modbus protocol |
iec104 |
IEC 60870-5-104, IEC 62351 |
enip |
EtherNet/IP, CIP |
snmp |
SNMP |
malware |
ICS malware: Triton/TRISIS, Industroyer, PIPEDREAM, Havoc |
ics-general |
General OT/SCADA security research |
Refresh from upstream:
python scripts/fetch_refs.py- PyScada - Django-based SCADA with Modbus, OPC-UA, historian, and HMI: https://pyscada.readthedocs.io/en/main/
- Pump Station Simulator - live Modbus TCP registers from a pump-station ladder logic sim: https://github.com/dscioli/pump-station-simulator
Local protocol stubs for offline regression testing (sim/ directory):
python sim/run_all.py --profile high # start all simulators on unprivileged ports
python sim/smoke.py # smoke test against themUse --profile canonical for standard protocol ports (requires Administrator/root for ports 80, 102, 502).
[dependencies]
scadaver_rs = { git = "https://github.com/Whispergate/scadaver" }Scan a Rockwell device and read tags:
use scadaver_rs::vendors::rockwell::driver;
let device = driver::get_device_info("192.168.1.50", 44818)?;
println!("{}: {}", device.product_name, device.revision);
let tags = driver::enumerate_tags("192.168.1.50", 44818)?;
for tag in &tags {
let value = driver::read_tag("192.168.1.50", 44818, &tag.name)?;
println!("{} = {}", tag.name, driver::decode_value(tag.tag_type, &value, None));
}Query the embedded ICS reference database:
use scadaver_rs::references;
for r in references::for_vendor("siemens") {
println!("[{}] {} | {}", r.source, r.title, r.url);
}Enable stealth mode before sweeping:
use scadaver_rs::core::autodetect;
autodetect::set_stealth(true);
let results = autodetect::sweep("192.168.1.100", 8);Public namespaces:
| Namespace | Protocols |
|---|---|
scadaver_rs::vendors::schneider |
Modbus TCP, FC90, UDP discovery |
scadaver_rs::vendors::siemens |
S7Comm / ISO-on-TCP |
scadaver_rs::vendors::beckhoff |
ADS/AMS, TwinCAT, CX webcontrol |
scadaver_rs::vendors::mitsubishi |
SLMP / MC Protocol 3E |
scadaver_rs::vendors::omron |
FINS TCP/UDP |
scadaver_rs::vendors::rockwell |
EtherNet/IP + CIP |
scadaver_rs::vendors::enip |
EtherNet/IP enumerations |
scadaver_rs::vendors::ewon |
eWON HTTP exploit + IPCONF scan |
scadaver_rs::vendors::phoenix |
ProConOS binary, WebVisit HMI |
scadaver_rs::vendors::snmp |
SNMPv1/v2c client, OID constants |
scadaver_rs::vendors::iec104 |
IEC 60870-5-104 client session |
scadaver_rs::core::modbus |
Raw Modbus TCP client primitives |
scadaver_rs::core::autodetect |
Multi-protocol sweep, stealth mode |
scadaver_rs::core::network |
Interface enumeration, broadcast sockets |
scadaver_rs::core::bytes |
Hex/IP utility functions |
scadaver_rs::references |
Embedded ICS vulnerability reference database |
This tool is for authorized penetration testing, red team exercises, ICS security research, and CTF competitions only. Unauthorized use against systems you do not own or have explicit written permission to test is illegal in most jurisdictions.
The authors assume no liability for misuse.