module Msf module Ui module Gtk2 ## # This class perform an assistant to configure module ## class MsfAssistant class Auxiliary < Msf::Ui::Gtk2::Assistant # to stock our values WIZARD2 = {} WizardStruct2 = Struct.new('Wizard2', :description, :page, :options_state, :review_state) ARRAY2 = [ ['Options', ["Select your options", "option", true, true, true, false], ], ['Review', ["Check your review", "end", true, true, true, true], ], ].collect do |item, state| WIZARD2[item] = WizardStruct2.new( state[0], state[1], state[2], state[3] ) end include Msf::Ui::Gtk2::MyControls # # Init # def initialize(active_module) @active_module = active_module @job_tree = $gtk2driver.job_tree @hash = {} # Call the parent super(@active_module.refname) # Initialize exploit driver's exploit instance #@mydriver = Msf::ExploitDriver.new(framework) #@mydriver.exploit = framework.auxiliary.create(@active_module.refname) @mydriver = $gtk2driver @mydriver.exploit = framework.auxiliary.create(@active_module.refname) @mydriver.active_module = @active_module # Populate the datastore if possible #@mydriver.exploit.load_config # Main interface @frame_advanced = Gtk::Expander.new("Advanced") @frame_evasion = Gtk::Expander.new("Evasion") @options_required = Gtk::VBox.new(false, 0) @options_advanced = Gtk::VBox.new(false, 0) @options_evasion = Gtk::VBox.new(false, 0) # Begin the wizard options_completion() # Build the left frame populate_frame( [ @label_options = create_label( WIZARD2['Options'].options_state, WIZARD2['Options'].description ), @label_review = create_label( WIZARD2['Review'].review_state, WIZARD2['Review'].description ) ] ) self.show_all end # # Save configuration for MsfAssistant # def save dump_to_hash() @mydriver.exploit.datastore.import_options_from_hash(@hash, imported = false) # TODO: choose the $gtk2driver or @mydriver.exploit ? $gtk2driver.active_module = @mydriver.exploit $gtk2driver.save_config # Save the framework's datastore framework.save_config @mydriver.exploit.datastore.to_file(Msf::Config.config_file, @mydriver.exploit.refname) $gtk2driver.append_log_view("Saved configuration to: #{Msf::Config.config_file}\n") end # # Action when Forward button was clicked # def next_page if (self.page == "options") if not validate() self.page = "options" refresh_label( nil, # historic [@label_options], # actual [@label_review] # next ) #button_forward.set_sensitive(false) display() options_completion() else self.page = "end" refresh_label( [@label_options], [@label_review], nil ) display() review_completion() end end end # # Action when Back button was clicked # def back_page if (self.page == "end") self.page = "options" refresh_label( nil, [@label_options], [@label_review] ) display() options_completion() end end # # Display options view # def options_completion self.page = "options" # Expanded frame @frame_advanced.each do |widget| @frame_advanced.remove(widget) end @frame_evasion.each do |widget| @frame_evasion.remove(widget) end # Required @options_required.each do |widget| @options_required.remove(widget) end # Advanced @options_advanced.each do |widget| @options_advanced.remove(widget) end # Evasion @options_evasion.each do |widget| @options_evasion.remove(widget) end # Pack self.main.pack_start(@options_required, false, false, 10) self.main.pack_start(@frame_advanced, false, false, 10) self.main.pack_start(@frame_evasion, false, false, 10) # Standards options @mydriver.exploit.options.sorted.each do |key, opt| next if (opt.evasion?) next if (opt.advanced?) @options_required.pack_start(add_option(key, opt, @mydriver.exploit.datastore[key]), false, false, 10) end # Advanced options @mydriver.exploit.options.sorted.each do |key, opt| next if (!opt.advanced?) @options_advanced.pack_start(add_option(key, opt, @mydriver.exploit.datastore[key]), false, false, 10) end # Evasion options @mydriver.exploit.options.sorted.each do |key, opt| next if (!opt.evasion?) @options_evasion.pack_start(add_option(key, opt, @mydriver.exploit.datastore[key]), false, false, 10) end # Display @frame_advanced.set_label("Advanced") @frame_advanced.add(@options_advanced) @frame_evasion.set_label("Evasion") @frame_evasion.add(@options_evasion) self.main.show_all end # # Put all values in a hash # def dump_to_hash @options_required.each do |widget| name, value = widget.get_pair begin if (@mydriver.exploit.options[name].default.to_s == value) nil else @hash[name] = value end rescue nil end end @options_advanced.each do |widget| name, value = widget.get_pair begin if (@mydriver.exploit.options[name].default.to_s == value) nil else @hash[name] = value end rescue nil end end @options_evasion.each do |widget| name, value = widget.get_pair begin if (@mydriver.exploit.options[name].default.to_s == value) nil else @hash[name] = value end rescue nil end end end # # Validate options in datastore # def validate dump_to_hash() errors = [] @mydriver.exploit.datastore.import_options_from_hash(@hash) @mydriver.exploit.options.each_pair do |name, option| if (!option.valid?(@mydriver.exploit.datastore[name])) errors << name # If the option is valid, normalize its format to the correct type. elsif ((val = option.normalize(@mydriver.exploit.datastore[name])) != nil) @mydriver.exploit.datastore.update_value(name, val) end end if (errors.empty? == false) MsfDialog::Error.new(self, "Failed to validate : #{errors.join(', ')}") false else true end end # # Display the review page # def review_completion warning = Gtk::Label.new warning.set_markup("Review your configuration before clicking the apply button") self.main.pack_start(warning, false, false, 0) label = Gtk::Label.new review = "\n\n" @hash.each do |key, value| review << "#{key} : #{value}\n" end label.set_markup(review) self.main.pack_start(label, false, false, 0) self.main.show_all end # # Fire !! # def apply # Import options from the supplied assistant @mydriver.exploit.datastore.import_options_from_hash(@hash) result = MsfWindow::Auxiliary.new(@mydriver.active_module.refname, @hash) action = @mydriver.exploit.datastore['ACTION'] jobify = false @pipe = Msf::Ui::Gtk2::GtkConsolePipe.new @pipe.create_subscriber_proc() do |msg| $gtk2driver.append_log_view(msg) result.append_log_view(msg) end @pipe.print_status("Launching auxiliary #{@mydriver.exploit.refname}...") # Always run passive modules in the background if (@mydriver.exploit.passive? or @mydriver.exploit.passive_action?(action)) jobify = true end begin Thread.new do @mydriver.exploit.run_simple( 'Action' => action, 'Options' => @hash, 'LocalInput' => @pipe, 'LocalOutput' => @pipe, 'RunAsJob' => jobify ) end result.show_all rescue ::Exception => e MsfDialog::Error.new(self, "Auxiliary failed", e.to_s) return false end end end end end end end