The words written earlier
Modbus is not secure. This is not a new discovery - when Modicon designed this protocol in 1979, it was not even popular on the Internet, let alone that one day the PLC would be directly exposed to the public network through the 4G module. The threat model at that time was' Will the cable be bitten by mice ', not' Is there anyone doing a man in the middle attack on port 502 '.
But this does not mean that Modbus cannot be used. The issue of a protocol and the problem on the construction site are two different things. In the cabinet, on the isolated control network, and on the one-to-one physical connection RS-485 bus, the drawbacks of Modbus plaintext pose almost no threat. When did the problem arise? You connected the RS-485 cable to a 4G DTU, and the DTU was configured with a public IP address, but the default password has not been changed yet.
This article does not talk about security theory, but about nine situations that you and I may encounter - not 'if' but 'already happened'. Then we will discuss how to reduce the risk to an acceptable level without changing the equipment or overturning the existing architecture.
What is missing from Modbus
First, clarify what exactly Modbus is missing. It cannot be summarized by the three words' unsafe '.
**There is no authentication mechanism. **The MBAP header of Modbus TCP contains a Unit ID field of 1 byte. This thing is a device address, not an identity credential. Anyone who can establish a TCP connection to port 502 can send function code 0x03 to read the hold register and function code 0x06 to write a single register. Try it out: Telnet sends' x00x00x00x00x06x01x03x00x00x00x00x001 '- as long as the device is online, it will return register data. No password, no token, no form of authentication required.
Take the function code 0x05 as an example of writing a single coil. This frame only has 12 bytes:
| TX ID | Proto | Len | UID | FC | Coil Addr | Value |
|---------|-------|------|-----|-----|-----------|----------|
| 00 01 | 00 00 | 00 06| 01 | 05 | 00 01 | FF 00 |The meaning of this frame is to set the coil address 0001 of device 01 to ON. If you are a legitimate SCADA client, this is not a problem. If you are a stranger connected to port 502, this is also valid. Devices will not be treated differently.
**No encryption. **Every byte in the TCP payload is plaintext. Wireshark can directly view transaction IDs, function codes, register addresses, and data values using the 'modbus' filter. Capturing a packet of Modbus TCP traffic is equivalent to obtaining the entire register mapping table. A thoughtful person can draw a register diagram of all devices by looking at the Modbus traffic in your factory for five minutes.
**CRC cannot verify tampering. **The CRC-16 of Modbus RTU and the TCP checksum dependent on Modbus TCP are designed to detect bit errors in the physical transport layer - data flipping caused by cable noise and electromagnetic interference. They are not cryptographic hashes and cannot be deliberately tampered with. The attacker intercepts a frame, changes the register value, recalculates the CRC, and forwards it, but the slave cannot distinguish whether the frame has been tampered with or not.
Take a look at the attack flow:
Original frame (Main Station)→From the station): 01 06 00 01 17 70 D8 0B (Write and hold register address 0001)=6000, Corresponding to 50Hz)
intercept→Tampered frame: 01 06 00 01 02 58 C9 C3 (Change to 600), Corresponding to 5Hz)The CRC has changed, but the attacker can also calculate it. Execute as usual after receiving from the station. The upper limit frequency of the frequency converter has changed from 50Hz to 5Hz - the motor is not burning, but the pump is not producing water.
**There is no anti replay feature. **Modbus does not have timestamps or serial number protection (transaction IDs in MBAP are only used to match requests and responses, not security numbers). The same frame can be replayed infinitely. Last month, you sent a shutdown command to the wind turbine, which was recorded by the attacker. Next month, you will send it again - the decoding is exactly the same, but the equipment still stops.
Nine real risk scenarios
It's not a theoretical loophole, it's that the following things have already happened in different scenarios. Some of them were encountered by myself, some were discussed among peers, and some were mentioned in public reports.
Scenario 1: Modbus TCP Direct Connection to Public Network - Port 502 Exposed on Shodan
Search for 'port: 502' on Shodan, and the number keeps increasing. Two or three years ago, there were about six or seven thousand publicly available data, but now it has already exceeded ten thousand. These devices include PLCs, RTUs, gateways, smart meters, some running in data centers, and some hanging on the backbone network of SCADA in water plants. Shodan will also capture the Modbus response returned by the device, directly displaying the device model and firmware version.
Nothing needs to be cracked. You set the device IP as a public network address, and there is no ACL on port 502- it's like leaving the workshop door open and the device operation panel facing the road.
Scan with nmap to make it more intuitive:
nmap -p 502 --script modbus-discover <target_ip>This NSE script will attempt to read device information. If the device responds with 0x11 (reporting slave ID) or 0x2B (device identification), it directly tells you the manufacturer, product code, and firmware version. Zero threshold.
Scenario 2: Modbus RTU for water plants/substations transmitted transparently to the cloud via 4G DTU
On site, RS-485 is used to run Modbus RTU, and dozens of instruments are hung on the bus. For remote monitoring, a 4G DTU was added and configured for transparent transmission mode - the DTU packages serial data into TCP packets and sends them to the cloud server. Public IP, port 8899 (not 502, but the difference is not significant).
The problem is that the link between DTU and cloud server is plaintext TCP. Anyone who can act as a MITM (man in the middle) on this link - not necessarily a national level attacker, but could be internal personnel of the operator, 4G signal hijacking devices, or other devices under the same base station exploiting LTE network vulnerabilities - can:
1. Monitor all Modbus RTU traffic to obtain complete register mapping and real-time data
Last year, there was a case of a water plant where an attacker connected to DTU's backend management port (default password admin/admin) through a publicly available cloud platform IP, and directly saw the control interface of the entire pump station. Fortunately, I just watched it and didn't operate it.
Scenario 3: Modbus to MQTT gateway - MQTT side naked running
This architecture is now very common: Modbus RTU devices → gateway for protocol conversion → MQTT Broker (cloud or local) → upper layer application consumption.
The gateway maps register data to MQTT topics, such as'/part1/pump1/pressure '->holding the value of register 40001. This design itself is not a problem - MQTT's publish/subscribe model is indeed more suitable for cloud scenarios than Modbus polling.
The problem lies on the MQTT side: many deployments do not have TLS enabled, brokers do not require client certificate authentication, and topics do not have ACLs. Attackers only need to know the Broker address and port (usually 1883, the default port for plaintext MQTT) to subscribe to all topics using 'mosquitto_stub':
mosquitto_sub -h <broker_ip> -p 1883 -t "#" -v`#`It is a multi-level wildcard of MQTT, subscribing to all topics. After a few seconds, the temperature, pressure, meter readings, and equipment status of the entire factory were all received. If the Broker still allows publishing (many gateways' bidirectional control functions rely on this), attackers can directly send instructions to the controlling Topic:
mosquitto_pub -h <broker_ip> -p 1883 -t "/plant1/pump1/control" -m "STOP"Scenario 4: Modbus TCP on Wi Fi in the factory intranet is sniffed
Many factories hang Modbus TCP devices and SCADA servers on the same Wi Fi network for the convenience of wiring. The Wi Fi password is written on the device label and posted on the outside of the cabinet - to prevent gentlemen but not villains.
After internal employees (or visitors, maintenance personnel, and devices left by departing employees) connect to this Wi Fi, all Modbus TCP traffic is plaintext within the broadcast domain. Wireshark packet capture:
filter: modbus && tcp.port == 502You can draw the register mapping of all devices in just ten minutes. If the attacker wants to go further, ARP spoofing directs the traffic from the SCADA server to their own machine and forwards it as a man in the middle - the Modbus communication on the device side will not be interrupted, the SCADA interface is normal, and the data in the background is already being stolen in real time.
Scenario 5: The BACnet Modbus gateway configuration page for building automation does not have a password set
In building automation systems, BACnet and Modbus are often mixed on the same gateway. For example, some gateway products from Delta Controls and Siemens Desigo have both Modbus RTU interfaces for instruments and BACnet/IP interfaces for BMS.
These gateways typically provide a web configuration page. By default, many integrators only change their IP address and configure register mapping when they go online, and their password is still the factory default - or not set at all. The web page exposes the complete register mapping table, device address, function code configuration, and even online debugging functions - Modbus read and write instructions can be directly sent inside.
Search for 'BACnet gateway' or product pages for specific gateway models on Shodan, and you will find many such entrances. Going in is not just about looking at data - you can directly change the opening of HVAC valves, set air conditioning temperature settings, and start/stop chiller units on the web interface.
Scenario 6: Modbus control commands of wind farm SCADA are replayed
Wind farm SCADA systems typically communicate with wind turbine PLCs using Modbus TCP. Control instructions include start stop, pitch angle adjustment, yaw control, power limitation, etc.
After the 2015 Ukrainian power grid attack, people finally began to pay attention to OT security. But the situation of wind farms is quite special - many wind farms are built in remote areas, and remote operation and maintenance rely on VPN or dedicated lines. The mobility of operation and maintenance personnel is high, and VPN account management often cannot keep up.
If an "emergency stop" Modbus command (function code 0x05, write a certain coil) is intercepted by a bad person during transmission - regardless of the means used, it may be the VPN client being controlled, the operation and maintenance laptop being implanted with a Trojan horse, or the internal network moving horizontally - this frame can be saved. The attacker does not need to understand the details of the Modbus protocol, does not need to know the register mapping, and only needs to replay this frame at night a few months later. After receiving it, the fan will shut down.
Replay without timing or targeting. Record once, send a hundred times. However, the Modbus protocol itself has no mechanism to prevent this from happening.
Scenario 7: OEM device default configuration is utilized
In order to improve shipping efficiency, OEM equipment manufacturers use a unified slave address (such as address 01), a unified function code support list, and even a unified register mapping for all PLCs/RTUs. Even worse, some manufacturers have written communication parameters in their firmware that cannot be changed.
This is very convenient during the device debugging phase. But after actual deployment, it turned into a security nightmare.
Assuming a distributed photovoltaic project uses the same batch of inverters, all devices have slave addresses of 01, and register mappings are exactly the same (40001=power, 40003=voltage, 40005=operating status, 40101=power on/off control). If an attacker breaks through one of the devices or intermediate network nodes, they are essentially obtaining the control blueprints of all the devices. Other devices do not need to be re detected - the register mapping is completely the same.
Scenario 8: Register Write Attack - Modifying Device Parameters
This scene is the most dangerous. The hold register of Modbus not only stores measurement data, but also device parameters. The upper limit frequency, PID parameters, alarm threshold, and calibration coefficient of the frequency converter are all stored in registers. People who can write registers can change the physical behavior of the device.
Specific examples:
| Device | register address | parameter | normal value | Malicious value | consequence |
|---|---|---|---|---|---|
| Variable Frequency Drive | 40018 | upper frequency limit | 5000 (=50Hz) | 500 (=5Hz) | Insufficient pump output, production line shutdown |
| thermostat | 40005 | Target temperature | 250 (=25.0℃) | 800 (=80.0℃) | Overtemperature protection tripping, or reversing to low causing freezing |
| electricity meter | 40045 | Current ratio | 100 | 1 | Deviation of electricity data by a hundred times, collapse of energy consumption accounting |
| PLC | 40001 | Operation Mode | 1 (Running) | 0 (Stop) | Directly stop the PLC from executing logic |
No need for complex attacks. Scan the modbus director script of nmap to obtain the register mapping, and then directly write it into modbus cli or pymodbus:
from pymodbus.client import ModbusTcpClient
client = ModbusTcpClient('192.168.1.100')
client.write_register(18, 500) # Change the upper limit frequency of the frequency converter to 5HzFour lines of code. No permission is required. Once the frequency converter receives it, execute it.
Scenario 9: RS-485 bus physical access - workshop door unlocked
The physical security of RS-485 bus is almost zero. All devices on the bus share a pair of differential signal lines (A+/B -), and anyone who connects a USB-RS485 converter at any position on the bus can:
1. * * Passive monitoring * *: Record all RS-485 traffic and analyze it offline
A USB-RS485 converter costs over ten yuan on Taobao. A clever attacker hid the converter in a slot during a night shift inspection and added a micro 4G module for remote access while people were not paying attention. Who can discover it? No one regularly checks the electrical characteristics of the RS-485 bus.
The key is that the design of RS-485 bus itself is a multi station shared medium, without the need for switches or port access permits. Physically, hanging it up is a member of the network. The slave addresses of Modbus RTU are only 1-247, and attackers can enumerate all addresses and detect device types one by one.
Layered defense: a complete solution from the physical layer to the monitoring layer
After discussing nine scenarios, a natural conclusion is that Modbus security issues cannot be solved by a single means. Its problems are distributed at every layer of the protocol stack, and protection also needs to be divided accordingly.
The following solutions are not theoretical - each one has a corresponding product, open source tool, or configuration method. Choose according to your own on-site conditions.
Network layer: putting Modbus in a cage
**The first iron rule: Never expose the Modbus 502 port directly to the public network. **This sentence cannot be emphasized too much. If your device supplier tells you to 'directly set the IP to the public network, it will be convenient for us to maintain remotely' - switch suppliers.
Specific operations:
**Firewall ACL whitelist. **It's not a blacklist, it's a whitelist. Port 502 only allows specified IP addresses (SCADA servers, data acquisition gateways) to access. Linux iptables can be done in two lines:
iptables -A INPUT -p tcp --dport 502 -s 192.168.10.0/24 -j ACCEPT
iptables -A INPUT -p tcp --dport 502 -j DROPIf your device's CPU cannot run the iptables, use a hardware firewall (a small industrial firewall costing a few hundred yuan is sufficient), or at least do an ACL on the router/layer 3 switch.
**VLAN isolation. **Place Modbus devices in separate VLANs, completely isolated from office networks, Wi Fi networks, and guest networks. VLAN routing only allows traffic from SCADA servers to port 502, and does not route anything else. Perform MAC binding on the switch port to prevent someone from unplugging the device and replacing it with their own laptop.
**VPN/IPsec tunnel. **For scenarios that require remote access, use VPN instead of opening the port to the public network. IPsec or WireGuard are both acceptable. The configuration of OpenVPN is not complicated:
# The server only allows 502 Port traffic passes through tunnels
push "route 192.168.10.0 255.255.255.0"This ensures that Modbus traffic is always transmitted within the encrypted tunnel. Even if the attacker intercepts the VPN link, TLS/AES encryption will prevent them from obtaining plaintext.
Transport Layer: Modbus+TLS Solution
When it comes to Modbus plus TLS, we must first talk about the current situation: * * The Modbus Organization released the Modbus/TCP Security specification * * in October 2018. Core changes: The default port has been changed from 502 to 802, TLS 1.2 is enforced, X.509v3 certificate is used for identity authentication, and Role Based Access Control (RBAC) is introduced.
The standard defines four roles:
| Role ID | Role Name | Permission |
|---|---|---|
| 0 | Administrator | Full function code, full register, device management |
| 1 | Operator | Read and write all registers, configuration cannot be changed |
| 2 | Engineer | Debugging and diagnostic permissions |
| 3 | Observer | Read only data, unable to write |
This completely solves the problem of Modbus unauthentication - clients must hold a valid certificate to establish TLS connections, and the role field in the certificate determines which function codes can be executed.
But the reality is that there are very few devices that support port 802. The vast majority of existing devices only support 502 plaintext. How to add TLS without changing the device?
**Stunnel Plan. **Stunnel is a lightweight TLS proxy that can encapsulate any TCP connection into a TLS tunnel. Deployment Architecture:
SCADA client → stunnel(Local 127).0.0.1:1502) → TLS → stunnel(Remote) → Device(502)Stunnel configuration is very short:
# 客户端 stunnel.conf
[modbus-client]
client = yes
accept = 127.0.0.1:1502
connect = 192.168.10.1:802
verifyChain = yes
CAfile = /etc/stunnel/ca.pem
cert = /etc/stunnel/client.pem
key = /etc/stunnel/client.key
# 服务端 stunnel.conf
[modbus-server]
client = no
accept = 802
connect = 127.0.0.1:502
cert = /etc/stunnel/server.pem
key = /etc/stunnel/server.key
CAfile = /etc/stunnel/ca.pem
verifyChain = yesThe client software is connected to '127.0.0.1:1502' instead of directly connecting to the device's 502. The TLS encryption in the middle is completely transparent to the upper layer. Stunnel itself only has a few hundred KB and can run on embedded Linux gateways, Raspberry Pi, and even OpenWrt routers.
**Note: Stunnel addresses transmission encryption issues, not application layer authentication issues. It ensures that the transmission link is not eavesdropped or tampered with, but once the TLS tunnel is built, the Modbus frame itself remains plaintext - only this plaintext is transmitted between the encrypted tunnel and the protected intranet. If an attacker can enter the internal network and directly connect to device 502, Stunnel cannot protect it.
Application Layer: Modbus Security Proxy/Gateway
If you cannot deploy stunnel on every device or require finer grained control, adding a secure proxy/gateway between the Modbus bus and upper layer applications is the most cost-effective solution.
The Moxa MGate series, Hilscher netTAP, and Advantech ADAM-4570 industrial gateways all support access control lists. You can configure on the gateway:
-Which IP can access which slave addresses
When selecting, it is important to note that not all Modbus gateways support security policies. Many cheap gateways only do transparent transmission, and the ACL function needs to look for the 'Access Control' or 'Security Policy' fields in the selection table.
There are also open-source solutions available. Writing a proxy using Pymodbus only takes a few hundred lines of code:
# 简化版 Modbus 安全代理逻辑
ALLOWED_FUNCTION_CODES = {0x03, 0x04, 0x06, 0x10} # 只允许这些功能码
READ_ONLY_REGISTERS = range(40001, 40051) # 这个地址段只读
def proxy_handler(request):
if request.function_code not in ALLOWED_FUNCTION_CODES:
return exception_response(request.function_code, 0x01) # 非法功能码
if request.function_code in {0x06, 0x10}:
for addr in request.addresses:
if addr in READ_ONLY_REGISTERS:
return exception_response(request.function_code, 0x02) # 非法数据地址
# 转发到实际设备
return forward_to_device(request)These lines block most of the register write attacks in scenario 8.
Physical layer: Physical security of RS-485 bus
Physical security may sound 'low-level', but at least three out of the nine scenarios are related to physical access.
A few things that can be done at the lowest cost:
1. * * The cabinet is locked. **Not just a simple key lock - use electronic access control to record who opened which cabinet when. The cabinet opening at an abnormal time (two or three in the morning) is a physical security event.
It doesn't cost much, but blocking 90% of physical access attacks is enough.
Monitoring layer: Modbus traffic anomaly detection
All the previous measures were to 'not let him in'. But for situations where "they have already entered" or "legitimate users have done illegal things", you still need to have the ability to detect.
The anomalous characteristics of Modbus traffic are very clear - precisely because the protocol is simple, anomalies are easier to identify:
**Sudden change in polling cycle. **SCADA systems typically poll devices at fixed intervals (such as once per second). If the request frequency of a slave suddenly changes from 1 time/second to 100 times/second, it is likely not the behavior of SCADA. Perhaps someone is violently scanning the register.
**Non standard function codes appear. **A system that only uses 0x03 (read hold register) and 0x06 (write single register) suddenly experiences 0x08 (diagnostic) or 0x2B (device recognition) requests - this is a typical characteristic of reconnaissance behavior.
**Non working time traffic. **During the factory shutdown period (such as 11pm to 6am), there should not be a large number of read and write instructions on the Modbus bus. If there is, call the police.
**Combination of abnormal function codes. **A dense combination of 0x05 (writing a single coil), 0x06 (writing a single register), and 0x10 (writing multiple registers) appears in a short period of time, and the target address spans multiple non adjacent regions - it is almost certain to be a malicious operation.
In terms of open source tools:
# Zeek (Original)Bro) have Modbus Protocol parser
# Write a detection script and place it in Zeek The strategy directoryWireshark+Modbus plugin can be used for offline traffic auditing. Capture the daily bus traffic and use Wireshark's' Statistics' → 'Protocol Hierarchy' → 'Modbus' to see the distribution of function codes. The appearance of function codes 0x08 and 0x2B is a red flag.
The 'modbus director' NSE script of nmap should be periodically run from your own SCADA server to check for any new Modbus devices appearing on the network:
nmap -p 502 --script modbus-discover 192.168.10.0/24If you discover a device that doesn't belong to you, the situation becomes serious.
Compliance reference
Without delving into regulatory provisions, only a few that directly impact Modbus deployment will be discussed.
**IEC 62443-3-3 * * defines seven basic requirements for industrial automation and control systems (FR1-FR7). FR2 (Usage Control) requires authentication and authorization for industrial communication, while FR3 (System Integrity) requires integrity verification of communication data. The plaintext Modbus directly does not comply with FR2 and FR3. Adding stunnel/VPN can meet the requirements of cryptography.
**The CIP-005 of NERC CIP (North American Electric Reliability Standard) requires access control to the Electronic Security Boundary (ESP) of the power system. This means that if you use Modbus to transmit control commands in the US power industry, port 502 must be inside ESP or through ESP's encrypted tunnel and cannot run naked. CIP-007 also requires system patching and minimizing ports, which are directly related to firmware management of Modbus devices.
**China's equivalent insurance 2.0 (GB/T 22239-2019) * * has specific expansion requirements for industrial control systems. Mainly including: implementing boundary protection and technical isolation between control networks and non control networks; When using a wide area network for control instruction transmission, encrypted authentication is used; The industrial control system divides security domains based on business and implements isolation. Basic network isolation, communication encryption, and access control are mandatory requirements for devices using Modbus in systems with protection level three or above, and there is no room for choice.
These compliance requirements are not just decorations - during the audit, network architecture diagrams, firewall rules, and packet capture verification will be checked. Using Modbus TCP plaintext to access public networks is not subject to any compliance audit.
Minimum Cost Protection List
If you are in a small or medium-sized factory with limited budget, outdated equipment that cannot be replaced, and no dedicated safety engineer, the following 5 things you can do now. **These 5 blocks 90% of attacks without the need for additional equipment procurement:**
1. * * Check if all 502 ports can be accessed from the public network. **Go to https://www.shodan.io Search for your public IP address range, or scan it with 'nmap-p 502<public IP>' on an external network. If exposed, immediately turn off port mapping or add AC.
After implementing the above 5 points, we can discuss whether to use a dedicated OT security platform and whether to do SIEM integration. Most small factories haven't even done the first one.
Comparison with the security model of OPC UA
Talking about Modbus security cannot bypass OPC UA. It's not about who replaces whom, it's about understanding the gap between the two security models and avoiding making outrageous decisions when selecting.
| Dimension | Modbus TCP (native) | OPC UA |
|---|---|---|
| Certification | 无 | X. 509 certificate, username/password Kerberos |
| Transmission Encryption | 无 | TLS 1.2/1.3 (UA-TCP) or HTTPS (UA-HTTPS) |
| Data Signature | 无 | Each message can be individually signed (UA SecureConversation) |
| access control | 无 | Session level+Node level ACL |
| audit log | Dependent application layer | Built in audit event types |
| Protocol complexity | Minimalist, 12 byte frame | Binary encoding, complete OO object model |
OPC UA incorporates security into the protocol stack, with corresponding security mechanisms from the transport layer to the application layer. Modbus left everything to the implementer. This is not OPC UA being 'better' than Modbus - these are two completely different design philosophies. The security complexity of OPC UA also comes at a cost: TLS handshake, certificate management, trust chain, CRL/OCSP revocation checks - all of which are unrealistic on embedded Modbus devices. STM32 only requires one UART and two to three hundred lines of C code to run Modbus RTU, while running OPC UA requires TLS library, XML parser, and at least tens of KB of RAM.
So the conclusion is not 'everyone uses OPC UA'. Yes: If you are already using Modbus, don't overturn the entire system and switch to OPC UA just because it is not secure - the cost of adding stunnel, firewall ACL, and security agents is much lower than switching protocols. If you are in the process of building a new system, selecting equipment resources, and need to integrate IT/OT architecture, the natural security capabilities of OPC UA will save you a lot of trouble in compliance and operation in the later stage.
Afterword
The security issue of Modbus is not a technical problem, but an engineering management issue. The protocol itself does not have security capabilities, but you can place it in a protected environment through deployment architecture. Just as you wouldn't hang a server without a firewall directly on the public network, you shouldn't let Modbus devices face untrusted networks directly.
Ultimately, the most dangerous thing is never protocol vulnerabilities, but rather the feeling that 'no one attacks our small factory'. Attackers don't pick big or small factories - automated scanning tools treat everyone equally and come in with port 502 open.
If you have any questions, talk to me again, or you can use Wireshark to grab a packet and have a look yourself - you are likely to be surprised.
Leave a Reply