Implement jvazquez-r7 comments

bug/bundler_fix
Arnaud SOULLIE 2014-04-29 16:09:47 +02:00
parent a0add34a7d
commit 04f2632972
1 changed files with 38 additions and 43 deletions

View File

@ -8,47 +8,42 @@ require 'msf/core'
class Metasploit3 < Msf::Auxiliary class Metasploit3 < Msf::Auxiliary
include Msf::Exploit::Remote::Tcp include Msf::Exploit::Remote::Tcp
include Rex::Socket::Tcp
def initialize(info = {}) def initialize(info = {})
super(update_info(info, super(update_info(info,
'Name' => 'Modbus client, reloaded.', 'Name' => 'Modbus Client Utility',
'Description' => %q{ 'Description' => %q{
This module allows reading and writing data to a PLC using the Modbus protocol. This module allows reading and writing data to a PLC using the Modbus protocol.
This module is based on the 'modiconstop.rb' Basecamp module from This module is based on the 'modiconstop.rb' Basecamp module from
DigitalBond, as well as the mbtget perl script. DigitalBond, as well as the mbtget perl script.
}, },
'Author' => 'Author' =>
[ [
'EsMnemon <esm [at] mnemonic.no>', # original write-only module 'EsMnemon <esm[at]mnemonic.no>', # original write-only module
'Arnaud SOULLIE <arnaud.soullie[at]solucom.fr>', # new code that allows read/write 'Arnaud SOULLIE <arnaud.soullie[at]solucom.fr>' # new code that allows read/write
], ],
'License' => MSF_LICENSE, 'License' => MSF_LICENSE,
'Actions' => [AuxiliaryAction.new('READ_COIL', {}),
AuxiliaryAction.new('WRITE_COIL', {}),
AuxiliaryAction.new('READ_REGISTER', {}),
AuxiliaryAction.new('WRITE_REGISTER', {})
]
)) ))
register_options( register_options(
[ [
OptEnum.new("MODE", [true, 'Command', "READ_REGISTER",
[
"READ_REGISTER",
"READ_COIL",
"WRITE_REGISTER",
"WRITE_COIL"
]
]),
Opt::RPORT(502), Opt::RPORT(502),
OptInt.new('DATA', [false, "Data to write (WRITE_COIL and WRITE_REGISTER modes only)", 0xBEEF]), OptInt.new('DATA', [false, "Data to write (WRITE_COIL and WRITE_REGISTER modes only)"]),
OptInt.new('DATA_ADDRESS', [true, "Modbus data address", 0]), OptInt.new('DATA_ADDRESS', [true, "Modbus data address"]),
OptInt.new('UNIT_NUMBER', [false, "Modbus unit number", 1]), OptInt.new('UNIT_NUMBER', [false, "Modbus unit number", 1]),
], self.class) ], self.class)
end end
# a wrapper just to be sure we increment the counter # a wrapper just to be sure we increment the counter
def sendframe(payload) def send_frame(payload)
sock.put(payload) sock.put(payload)
@modbuscounter += 1 @modbus_counter += 1
r = sock.recv(65535, 0.1) r = sock.get
return r return r
end end
@ -59,13 +54,13 @@ class Metasploit3 < Msf::Auxiliary
payload += [datastore['DATA_ADDRESS']].pack("n") payload += [datastore['DATA_ADDRESS']].pack("n")
payload += [1].pack("n") payload += [1].pack("n")
packetdata = "" packet_data = ""
packetdata += [@modbuscounter].pack("n") packet_data += [@modbus_counter].pack("n")
packetdata += "\x00\x00\x00" #dunno what these are packet_data += "\x00\x00\x00" #dunno what these are
packetdata += [payload.size].pack("c") # size byte packet_data += [payload.size].pack("c") # size byte
packetdata += payload packet_data += payload
return packetdata return packet_data
end end
def make_write_coil_payload(data) def make_write_coil_payload(data)
@ -76,13 +71,13 @@ class Metasploit3 < Msf::Auxiliary
payload += [data].pack("c") payload += [data].pack("c")
payload += "\x00" payload += "\x00"
packetdata = "" packet_data = ""
packetdata += [@modbuscounter].pack("n") packet_data += [@modbus_counter].pack("n")
packetdata += "\x00\x00\x00" #dunno what these are packet_data += "\x00\x00\x00" #dunno what these are
packetdata += [payload.size].pack("c") # size byte packet_data += [payload.size].pack("c") # size byte
packetdata += payload packet_data += payload
return packetdata return packet_data
end end
def make_write_register_payload(data) def make_write_register_payload(data)
@ -92,27 +87,27 @@ class Metasploit3 < Msf::Auxiliary
payload += [datastore['DATA_ADDRESS']].pack("n") payload += [datastore['DATA_ADDRESS']].pack("n")
payload += [data].pack("n") payload += [data].pack("n")
packetdata = "" packet_data = ""
packetdata += [@modbuscounter].pack("n") packet_data += [@modbus_counter].pack("n")
packetdata += "\x00\x00\x00" #dunno what these are packet_data += "\x00\x00\x00" #dunno what these are
packetdata += [payload.size].pack("c") # size byte packet_data += [payload.size].pack("c") # size byte
packetdata += payload packet_data += payload
return packetdata return packet_data
end end
def run def run
@modbuscounter = 0x0000 # used for modbus frames @modbus_counter = 0x0000 # used for modbus frames
connect connect
case datastore['MODE'] case datastore['ACTION']
when "READ_COIL" when "READ_COIL"
@function_code = 1 @function_code = 1
response = sendframe(make_read_payload) response = send_frame(make_read_payload)
print_good("Coil value at address #{datastore['DATA_ADDRESS']} : " + response.reverse.unpack("c").to_s.gsub('[', '').gsub(']', '')) print_good("Coil value at address #{datastore['DATA_ADDRESS']} : " + response.reverse.unpack("c").to_s.gsub('[', '').gsub(']', ''))
when "READ_REGISTER" when "READ_REGISTER"
@function_code = 3 @function_code = 3
response = sendframe(make_read_payload) response = send_frame(make_read_payload)
value = response.split[0][9..10].to_s.unpack("n").to_s.gsub('[', '').gsub(']','') value = response.split[0][9..10].to_s.unpack("n").to_s.gsub('[', '').gsub(']','')
print_good("Register value at address #{datastore['DATA_ADDRESS']} : " + value) print_good("Register value at address #{datastore['DATA_ADDRESS']} : " + value)
@ -126,7 +121,7 @@ class Metasploit3 < Msf::Auxiliary
print_error("Data value must be 0 or 1 in WRITE_COIL mode") print_error("Data value must be 0 or 1 in WRITE_COIL mode")
exit exit
end end
response = sendframe(make_write_coil_payload(data)) response = send_frame(make_write_coil_payload(data))
print_good("Value #{datastore['DATA']} successfully written at coil address #{datastore['DATA_ADDRESS']}") print_good("Value #{datastore['DATA']} successfully written at coil address #{datastore['DATA_ADDRESS']}")
when "WRITE_REGISTER" when "WRITE_REGISTER"
@ -135,11 +130,11 @@ class Metasploit3 < Msf::Auxiliary
print_error("Data to write must be an integer between 0 and 65535 in WRITE_REGISTER mode") print_error("Data to write must be an integer between 0 and 65535 in WRITE_REGISTER mode")
exit exit
end end
response = sendframe(make_write_register_payload(datastore['DATA'])) response = send_frame(make_write_register_payload(datastore['DATA']))
print_good("Value #{datastore['DATA']} successfully written at registry address #{datastore['DATA_ADDRESS']}") print_good("Value #{datastore['DATA']} successfully written at registry address #{datastore['DATA_ADDRESS']}")
else else
print_error("Invalid MODE") print_error("Invalid ACTION")
return return
end end
end end