module Msf
module Ui
module Console
module CommandDispatcher

###
#
# Exploit module command dispatcher.
#
###
class Exploit

	include Msf::Ui::Console::ModuleCommandDispatcher

	@@exploit_opts = Rex::Parser::Arguments.new(
		"-e" => [ true,  "The payload encoder to use.  If none is specified, ENCODER is used." ],
		"-h" => [ false, "Help banner."                                                        ],
		"-j" => [ false, "Run in the context of a job."                                        ],
		"-n" => [ true,  "The NOP generator to use.  If none is specified, NOP is used."       ],
		"-o" => [ true,  "A comma separated list of options in VAR=VAL format."                ],
		"-p" => [ true,  "The payload to use.  If none is specified, PAYLOAD is used."         ],
		"-t" => [ true,  "The target index to use.  If none is specified, TARGET is used."     ],
		"-z" => [ false, "Do not interact with the session after successful exploitation."     ])

	#
	# Returns the hash of exploit module specific commands.
	#
	def commands
		{
			"check"    => "Check to see if a target is vulnerable",
			"exploit"  => "Launch an exploit attempt",
			"rcheck"   => "Reloads the module and checks if the target is vulnerable",
			"rexploit" => "Reloads the module and launches an exploit attempt",
		}
	end

	#
	# Returns the name of the command dispatcher.
	#
	def name
		"Exploit"
	end

	#
	# Checks to see if a target is vulnerable.
	#
	def cmd_check(*args)
		defanged?

		begin

			code = mod.check_simple(
				'LocalInput'  => driver.input,
				'LocalOutput' => driver.output)

			if (code)
				stat = '[*]'

				if (code == Msf::Exploit::CheckCode::Vulnerable)
					stat = '[+]'
				end
					
				print_line(stat + ' ' + code[1])
			else
				print_error(
					"Check failed: The state could not be determined.")
			end
		rescue
			log_error("Check failed: #{$!}")
		ensure
			mod.reset_ui
		end
	end

	#
	# Launches an exploitation attempt.
	#
	def cmd_exploit(*args)
		defanged?

		opt_str = nil
		payload = mod.datastore['PAYLOAD']
		encoder = mod.datastore['ENCODER']
		target  = mod.datastore['TARGET']
		nop     = mod.datastore['NOP']
		bg      = false
		jobify  = false

		# Always run passive exploits in the background
		if (mod.passive?)
			jobify = true
		end

		@@exploit_opts.parse(args) { |opt, idx, val|
			case opt
				when '-e'
					encoder = val
				when '-j'
					jobify = true
				when '-n'
					nop = val
				when '-o'
					opt_str = val
				when '-p'
					payload = val
				when '-t'
					target = val.to_i
				when '-z'
					bg = true
				when '-h'
					print(
						"Usage: exploit [options]\n\n" +
						"Launches an exploitation attempt.\n" +
						@@exploit_opts.usage)
					return false
			end
		}

		begin
			session = mod.exploit_simple(
				'Encoder'        => encoder,
				'Payload'        => payload,
				'Target'         => target,
				'Nop'            => nop,
				'OptionStr'      => opt_str,
				'LocalInput'     => driver.input,
				'LocalOutput'    => driver.output,
				'RunAsJob'       => jobify)
		rescue EOFError
			print_error("Exploit failed: The remote connection closed.")
		rescue
			log_error("Exploit failed: #{$!}")
			return false
		end

		# If we were given a session, let's see what we can do with it
		if (session)
			# If we aren't told to run in the background and the session can be
			# interacted with, start interacting with it by issuing the session
			# interaction command.
			if (bg == false and session.interactive?)
				print_line

				driver.run_single("sessions -q -i #{session.sid}")
			# Otherwise, log that we created a session
			else
				print_status("Session #{session.sid} created in the background.")
			end
		# If we ran the exploit as a job, indicate such so the user doesn't
		# wonder what's up.
		elsif (jobify)
			print_status("Exploit running as background job.")

			mod.reset_ui
		# Worst case, the exploit ran but we got no session, bummer.
		else
			print_status("Exploit completed, but no session was created.")
		end
	end

	#
	# Reloads an exploit module and checks the target to see if it's
	# vulnerable.
	#
	def cmd_rcheck(*args)
		begin
			self.mod = framework.modules.reload_module(mod)

			cmd_check(*args)
		rescue
			log_error("Failed to rcheck: #{$!}")
		end
	end

	#
	# Reloads an exploit module and launches an exploit.
	#
	def cmd_rexploit(*args)
		begin
			self.mod = framework.modules.reload_module(mod)

			cmd_exploit(*args)
		rescue
			log_error("Failed to rexploit: #{$!}")
		end
	end

end

end end end end
