beautify code
git-svn-id: file:///home/svn/framework3/trunk@4903 4d416f70-5f16-0410-b530-b9f4589650daunstable
parent
018f069b0a
commit
244abb6ae0
|
@ -1,30 +1,30 @@
|
|||
module Msf
|
||||
module Ui
|
||||
module Gtk2
|
||||
module Ui
|
||||
module Gtk2
|
||||
|
||||
class MyAbout
|
||||
include Msf::Ui::Gtk2::MyControls
|
||||
Gtk::AboutDialog.set_email_hook {|about, link|
|
||||
puts "Mail to #{link}"
|
||||
}
|
||||
Gtk::AboutDialog.set_url_hook {|about, link|
|
||||
puts "Launch a browser to url #{link}"
|
||||
}
|
||||
|
||||
def initialize
|
||||
@about = Gtk::AboutDialog.new
|
||||
@about.set_name('MsfGUI')
|
||||
@about.set_website('http://www.metasploit.org')
|
||||
@about.set_authors(['Fabrice MOURRON <fab@metasploit.com>', 'Metasploit LLC'])
|
||||
@about.set_license(File.read(File.join(Msf::Config.install_root, 'documentation', 'LICENSE')))
|
||||
#@about.set_wrap_license('True')
|
||||
@about.set_logo(driver.get_icon('msfwx.xpm'))
|
||||
@about.set_version("\nMetasploit Framework v#{Msf::Framework::Version}")
|
||||
@about.run
|
||||
@about.destroy
|
||||
end
|
||||
end
|
||||
|
||||
class MyAbout
|
||||
include Msf::Ui::Gtk2::MyControls
|
||||
Gtk::AboutDialog.set_email_hook {|about, link|
|
||||
puts "Mail to #{link}"
|
||||
}
|
||||
Gtk::AboutDialog.set_url_hook {|about, link|
|
||||
puts "Launch a browser to url #{link}"
|
||||
}
|
||||
|
||||
def initialize
|
||||
@about = Gtk::AboutDialog.new
|
||||
@about.set_name('MsfGUI')
|
||||
@about.set_website('http://www.metasploit.org')
|
||||
@about.set_authors(['Fabrice MOURRON <fab@metasploit.com>', 'Metasploit LLC'])
|
||||
@about.set_license(File.read(File.join(Msf::Config.install_root, 'documentation', 'LICENSE')))
|
||||
#@about.set_wrap_license('True')
|
||||
@about.set_logo(driver.get_icon('msfwx.xpm'))
|
||||
@about.set_version("\nMetasploit Framework v#{Msf::Framework::Version}")
|
||||
@about.run
|
||||
@about.destroy
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,269 +1,269 @@
|
|||
module Msf
|
||||
module Ui
|
||||
module Gtk2
|
||||
module Ui
|
||||
module Gtk2
|
||||
|
||||
##
|
||||
# This class help us to wait the next release of ruby-libglade2 package
|
||||
##
|
||||
class GladeXML < GladeXML
|
||||
def connect(source, target, signal, handler, data, after = false)
|
||||
@handler_proc ||= Proc.new{}
|
||||
handler = canonical_handler(handler)
|
||||
if target
|
||||
signal_proc = target.method(handler)
|
||||
else
|
||||
signal_proc = @handler_proc.call(handler)
|
||||
end
|
||||
|
||||
if after
|
||||
sig_conn_proc = source.method(:signal_connect_after)
|
||||
else
|
||||
sig_conn_proc = source.method(:signal_connect)
|
||||
end
|
||||
|
||||
if signal_proc
|
||||
guard_source_from_gc(source)
|
||||
case signal_proc.arity
|
||||
when 0
|
||||
sig_conn_proc.call(signal) {signal_proc.call}
|
||||
else
|
||||
sig_conn_proc.call(signal, &signal_proc)
|
||||
end
|
||||
elsif $DEBUG
|
||||
puts "Undefined handler: #{handler}"
|
||||
end
|
||||
end
|
||||
|
||||
def guard_source_from_gc(source)
|
||||
return if source.nil?
|
||||
@sources ||= {}
|
||||
@sources[source.object_id] = source
|
||||
|
||||
source.signal_connect("destroy") do |object|
|
||||
@sources.delete(object.object_id)
|
||||
end
|
||||
|
||||
# To get the parent window of the source as a ruby object.
|
||||
# Ruby/GTK keeps the Window objects on the memory to prevend from GC.
|
||||
parent = source.parent
|
||||
while parent
|
||||
parent = parent.parent
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# This class help us to retreive all glade widgets and place them in your user instance
|
||||
# like @windows, @widget, ...
|
||||
##
|
||||
|
||||
class MyGlade
|
||||
include Msf::Ui::Gtk2::MyControls
|
||||
|
||||
def initialize(root)
|
||||
# Give the glade file and instance the glade object
|
||||
file_glade = File.join(driver.resource_directory, 'msfgui.glade')
|
||||
glade = GladeXML.new(file_glade, root) { |handler|method(handler) }
|
||||
|
||||
# For all widget names, instance a variable
|
||||
glade.widget_names.each do |name|
|
||||
begin
|
||||
instance_variable_set("@#{name}".intern, glade[name])
|
||||
rescue
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# This is the main class
|
||||
##
|
||||
class MyApp < MyGlade
|
||||
|
||||
include Msf::Ui::Gtk2::MyControls
|
||||
|
||||
def initialize
|
||||
super('window')
|
||||
|
||||
# Set a default icon for all widgets
|
||||
Gtk::Window.set_default_icon(driver.get_icon('msfwx.xpm'))
|
||||
@window.set_icon(driver.get_icon('msfwx.xpm'))
|
||||
|
||||
# Set a title with the version
|
||||
@window.set_title("MSF Gui v#{Msf::Framework::Version}")
|
||||
|
||||
# Destroy
|
||||
@window.signal_connect('destroy') { Gtk.main_quit }
|
||||
|
||||
# Default size
|
||||
# @window.set_default_size(1024, 768)
|
||||
|
||||
# Defaults policies for Gtk::ScrolledWindow
|
||||
@scrolledwindow1.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC)
|
||||
@scrolledwindow2.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC)
|
||||
@scrolledwindow3.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC)
|
||||
# @scrolledwindow4.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC)
|
||||
@scrolledwindow16.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC)
|
||||
|
||||
# Logs Buffer
|
||||
@buffer = Gtk::TextBuffer.new
|
||||
@viewlogs.set_buffer(@buffer_logs)
|
||||
@viewlogs.set_editable(false)
|
||||
@viewlogs.set_cursor_visible(false)
|
||||
|
||||
# Sessions Tree
|
||||
@session_tree = MySessionTree.new(@treeview_session)
|
||||
|
||||
# Target Tree
|
||||
@job_tree = MyJobTree.new(@treeview2)
|
||||
|
||||
# Module Tree
|
||||
@module_tree = MyModuleTree.new(@treeview1, @viewmodule)
|
||||
|
||||
# Tooltips
|
||||
tooltips = Gtk::Tooltips.new
|
||||
|
||||
# Configure the window handles for easy reference
|
||||
$gtk2driver.main = @window
|
||||
$gtk2driver.session_tree = @session_tree
|
||||
$gtk2driver.job_tree = @job_tree
|
||||
$gtk2driver.module_tree = @module_tree
|
||||
$gtk2driver.log_text = @viewlogs
|
||||
$gtk2driver.tips = tooltips
|
||||
|
||||
# Initialize the search class
|
||||
ModuleSearch.new(@search_entry, @search_button, @search_cancel_button)
|
||||
|
||||
# Focus on the search widget
|
||||
@search_entry.can_focus = true
|
||||
@search_entry.grab_focus
|
||||
|
||||
# Update the StatusBar with all framework modules
|
||||
refresh()
|
||||
|
||||
# TODO: Add an hook for binding all links with browser preference
|
||||
# Gtk::AboutDialog.set_url_hook do |about, link|
|
||||
# puts link
|
||||
# end
|
||||
end
|
||||
|
||||
#
|
||||
# Signal to refresh the treeview module
|
||||
#
|
||||
def on_refresh_activate
|
||||
refresh()
|
||||
end
|
||||
|
||||
#
|
||||
# Bye bye
|
||||
#
|
||||
def on_leave_activate
|
||||
Gtk.main_quit
|
||||
end
|
||||
|
||||
#
|
||||
# Actions for OpCodes/Stats
|
||||
#
|
||||
def on_stats_activate
|
||||
t_run = Thread.new do
|
||||
MsfOpcode::Stats.new()
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Actions for OpCodes/Locales
|
||||
#
|
||||
def on_locales_activate
|
||||
MsfOpcode::Locales.new()
|
||||
end
|
||||
|
||||
#
|
||||
# Actions for OpCodes/Metatypes
|
||||
#
|
||||
def on_metatypes_activate
|
||||
MsfOpcode::Metatypes.new()
|
||||
end
|
||||
|
||||
#
|
||||
# Actions for OpCodes/Groups
|
||||
#
|
||||
def on_groups_activate
|
||||
MsfOpcode::Groups.new()
|
||||
end
|
||||
|
||||
#
|
||||
# Actions for OpCodes/Types
|
||||
#
|
||||
def on_types_activate
|
||||
MsfOpcode::Types.new()
|
||||
end
|
||||
|
||||
#
|
||||
# Actions for OpCodes/Platforms
|
||||
#
|
||||
def on_platforms_activate
|
||||
MsfOpcode::Platforms.new()
|
||||
end
|
||||
|
||||
#
|
||||
# Actions for OpCodes/Modules
|
||||
#
|
||||
def on_modules_activate
|
||||
MsfOpcode::Modules.new()
|
||||
end
|
||||
|
||||
#
|
||||
# Actions for OpCodes/Search
|
||||
#
|
||||
def on_search_activate
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Action for "Parameters/Preferences"
|
||||
#
|
||||
def on_preferences_activate
|
||||
MsfParameters::Preferences.new()
|
||||
end
|
||||
|
||||
#
|
||||
# Action for "Parameters"/"Databases" menu
|
||||
#
|
||||
def on_databases_activate
|
||||
MsfParameters::Databases.new()
|
||||
end
|
||||
|
||||
#
|
||||
# Action for "Parameters"/"Options" menu
|
||||
#
|
||||
def on_options_activate
|
||||
MsfParameters::Options.new()
|
||||
end
|
||||
#
|
||||
# The About Dialog
|
||||
#
|
||||
def on_about_activate
|
||||
MyAbout.new
|
||||
end
|
||||
|
||||
#
|
||||
# Call the refresh method to reload all module
|
||||
#
|
||||
def refresh
|
||||
@module_tree.refresh
|
||||
context_id = @statusbar.get_context_id("update")
|
||||
@statusbar.push(
|
||||
context_id,
|
||||
"Loaded " +
|
||||
framework.stats.num_exploits.to_s + " exploits, " +
|
||||
framework.stats.num_payloads.to_s + " payloads, " +
|
||||
framework.stats.num_encoders.to_s + " encoders, " +
|
||||
framework.stats.num_nops.to_s + " nops, and " +
|
||||
framework.stats.num_auxiliary.to_s + " auxiliary"
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
##
|
||||
# This class help us to wait the next release of ruby-libglade2 package
|
||||
##
|
||||
class GladeXML < GladeXML
|
||||
def connect(source, target, signal, handler, data, after = false)
|
||||
@handler_proc ||= Proc.new{}
|
||||
handler = canonical_handler(handler)
|
||||
if target
|
||||
signal_proc = target.method(handler)
|
||||
else
|
||||
signal_proc = @handler_proc.call(handler)
|
||||
end
|
||||
|
||||
if after
|
||||
sig_conn_proc = source.method(:signal_connect_after)
|
||||
else
|
||||
sig_conn_proc = source.method(:signal_connect)
|
||||
end
|
||||
|
||||
if signal_proc
|
||||
guard_source_from_gc(source)
|
||||
case signal_proc.arity
|
||||
when 0
|
||||
sig_conn_proc.call(signal) {signal_proc.call}
|
||||
else
|
||||
sig_conn_proc.call(signal, &signal_proc)
|
||||
end
|
||||
elsif $DEBUG
|
||||
puts "Undefined handler: #{handler}"
|
||||
end
|
||||
end
|
||||
|
||||
def guard_source_from_gc(source)
|
||||
return if source.nil?
|
||||
@sources ||= {}
|
||||
@sources[source.object_id] = source
|
||||
|
||||
source.signal_connect("destroy") do |object|
|
||||
@sources.delete(object.object_id)
|
||||
end
|
||||
|
||||
# To get the parent window of the source as a ruby object.
|
||||
# Ruby/GTK keeps the Window objects on the memory to prevend from GC.
|
||||
parent = source.parent
|
||||
while parent
|
||||
parent = parent.parent
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# This class help us to retreive all glade widgets and place them in your user instance
|
||||
# like @windows, @widget, ...
|
||||
##
|
||||
|
||||
class MyGlade
|
||||
include Msf::Ui::Gtk2::MyControls
|
||||
|
||||
def initialize(root)
|
||||
# Give the glade file and instance the glade object
|
||||
file_glade = File.join(driver.resource_directory, 'msfgui.glade')
|
||||
glade = GladeXML.new(file_glade, root) { |handler|method(handler) }
|
||||
|
||||
# For all widget names, instance a variable
|
||||
glade.widget_names.each do |name|
|
||||
begin
|
||||
instance_variable_set("@#{name}".intern, glade[name])
|
||||
rescue
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# This is the main class
|
||||
##
|
||||
class MyApp < MyGlade
|
||||
|
||||
include Msf::Ui::Gtk2::MyControls
|
||||
|
||||
def initialize
|
||||
super('window')
|
||||
|
||||
# Set a default icon for all widgets
|
||||
Gtk::Window.set_default_icon(driver.get_icon('msfwx.xpm'))
|
||||
@window.set_icon(driver.get_icon('msfwx.xpm'))
|
||||
|
||||
# Set a title with the version
|
||||
@window.set_title("MSF Gui v#{Msf::Framework::Version}")
|
||||
|
||||
# Destroy
|
||||
@window.signal_connect('destroy') { Gtk.main_quit }
|
||||
|
||||
# Default size
|
||||
# @window.set_default_size(1024, 768)
|
||||
|
||||
# Defaults policies for Gtk::ScrolledWindow
|
||||
@scrolledwindow1.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC)
|
||||
@scrolledwindow2.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC)
|
||||
@scrolledwindow3.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC)
|
||||
# @scrolledwindow4.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC)
|
||||
@scrolledwindow16.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC)
|
||||
|
||||
# Logs Buffer
|
||||
@buffer = Gtk::TextBuffer.new
|
||||
@viewlogs.set_buffer(@buffer_logs)
|
||||
@viewlogs.set_editable(false)
|
||||
@viewlogs.set_cursor_visible(false)
|
||||
|
||||
# Sessions Tree
|
||||
@session_tree = MySessionTree.new(@treeview_session)
|
||||
|
||||
# Target Tree
|
||||
@job_tree = MyJobTree.new(@treeview2)
|
||||
|
||||
# Module Tree
|
||||
@module_tree = MyModuleTree.new(@treeview1, @viewmodule)
|
||||
|
||||
# Tooltips
|
||||
tooltips = Gtk::Tooltips.new
|
||||
|
||||
# Configure the window handles for easy reference
|
||||
$gtk2driver.main = @window
|
||||
$gtk2driver.session_tree = @session_tree
|
||||
$gtk2driver.job_tree = @job_tree
|
||||
$gtk2driver.module_tree = @module_tree
|
||||
$gtk2driver.log_text = @viewlogs
|
||||
$gtk2driver.tips = tooltips
|
||||
|
||||
# Initialize the search class
|
||||
ModuleSearch.new(@search_entry, @search_button, @search_cancel_button)
|
||||
|
||||
# Focus on the search widget
|
||||
@search_entry.can_focus = true
|
||||
@search_entry.grab_focus
|
||||
|
||||
# Update the StatusBar with all framework modules
|
||||
refresh()
|
||||
|
||||
# TODO: Add an hook for binding all links with browser preference
|
||||
# Gtk::AboutDialog.set_url_hook do |about, link|
|
||||
# puts link
|
||||
# end
|
||||
end
|
||||
|
||||
#
|
||||
# Signal to refresh the treeview module
|
||||
#
|
||||
def on_refresh_activate
|
||||
refresh()
|
||||
end
|
||||
|
||||
#
|
||||
# Bye bye
|
||||
#
|
||||
def on_leave_activate
|
||||
Gtk.main_quit
|
||||
end
|
||||
|
||||
#
|
||||
# Actions for OpCodes/Stats
|
||||
#
|
||||
def on_stats_activate
|
||||
t_run = Thread.new do
|
||||
MsfOpcode::Stats.new()
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Actions for OpCodes/Locales
|
||||
#
|
||||
def on_locales_activate
|
||||
MsfOpcode::Locales.new()
|
||||
end
|
||||
|
||||
#
|
||||
# Actions for OpCodes/Metatypes
|
||||
#
|
||||
def on_metatypes_activate
|
||||
MsfOpcode::Metatypes.new()
|
||||
end
|
||||
|
||||
#
|
||||
# Actions for OpCodes/Groups
|
||||
#
|
||||
def on_groups_activate
|
||||
MsfOpcode::Groups.new()
|
||||
end
|
||||
|
||||
#
|
||||
# Actions for OpCodes/Types
|
||||
#
|
||||
def on_types_activate
|
||||
MsfOpcode::Types.new()
|
||||
end
|
||||
|
||||
#
|
||||
# Actions for OpCodes/Platforms
|
||||
#
|
||||
def on_platforms_activate
|
||||
MsfOpcode::Platforms.new()
|
||||
end
|
||||
|
||||
#
|
||||
# Actions for OpCodes/Modules
|
||||
#
|
||||
def on_modules_activate
|
||||
MsfOpcode::Modules.new()
|
||||
end
|
||||
|
||||
#
|
||||
# Actions for OpCodes/Search
|
||||
#
|
||||
def on_search_activate
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Action for "Parameters/Preferences"
|
||||
#
|
||||
def on_preferences_activate
|
||||
MsfParameters::Preferences.new()
|
||||
end
|
||||
|
||||
#
|
||||
# Action for "Parameters"/"Databases" menu
|
||||
#
|
||||
def on_databases_activate
|
||||
MsfParameters::Databases.new()
|
||||
end
|
||||
|
||||
#
|
||||
# Action for "Parameters"/"Options" menu
|
||||
#
|
||||
def on_options_activate
|
||||
MsfParameters::Options.new()
|
||||
end
|
||||
#
|
||||
# The About Dialog
|
||||
#
|
||||
def on_about_activate
|
||||
MyAbout.new
|
||||
end
|
||||
|
||||
#
|
||||
# Call the refresh method to reload all module
|
||||
#
|
||||
def refresh
|
||||
@module_tree.refresh
|
||||
context_id = @statusbar.get_context_id("update")
|
||||
@statusbar.push(
|
||||
context_id,
|
||||
"Loaded " +
|
||||
framework.stats.num_exploits.to_s + " exploits, " +
|
||||
framework.stats.num_payloads.to_s + " payloads, " +
|
||||
framework.stats.num_encoders.to_s + " encoders, " +
|
||||
framework.stats.num_nops.to_s + " nops, and " +
|
||||
framework.stats.num_auxiliary.to_s + " auxiliary"
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,258 +1,258 @@
|
|||
module Msf
|
||||
module Ui
|
||||
module Gtk2
|
||||
module Ui
|
||||
module Gtk2
|
||||
|
||||
|
||||
##
|
||||
# This class perform a wizard
|
||||
##
|
||||
class Assistant < Gtk::Window
|
||||
|
||||
include Msf::Ui::Gtk2::MyControls
|
||||
|
||||
attr_accessor :vbox, :hbox, :main, :page, :bbox, :vbox_left, :vbox_label, :save_button
|
||||
attr_accessor :button_forward
|
||||
|
||||
def initialize(title)
|
||||
super
|
||||
self.resizable = false
|
||||
self.set_default_size(600, 400)
|
||||
self.title = title
|
||||
|
||||
# First page
|
||||
@page = "intro"
|
||||
|
||||
# VBox
|
||||
@vbox = Gtk::VBox.new(false, 10)
|
||||
self.add(@vbox)
|
||||
|
||||
# MSF Banner
|
||||
@vbox.pack_start(create_banner(), false, false, 0)
|
||||
|
||||
# HBox
|
||||
@hbox = Gtk::HBox.new(false, 10)
|
||||
@vbox.pack_start(@hbox, true, false, 0)
|
||||
|
||||
# Left frame
|
||||
@vbox_left = Gtk::VBox.new(false, 5)
|
||||
@hbox.pack_start(@vbox_left, false, false, 10)
|
||||
@vbox_left.pack_start(create_frame(), false, false, 10)
|
||||
@vbox_left.pack_start(create_save(), false, false, 5)
|
||||
|
||||
# Main frame
|
||||
@main = Gtk::VBox.new(false, 5)
|
||||
@hbox.pack_start(@main, true, true, 5)
|
||||
|
||||
# Separator
|
||||
separator = Gtk::HSeparator.new
|
||||
@vbox.pack_start(separator, false, false, 0)
|
||||
##
|
||||
# This class perform a wizard
|
||||
##
|
||||
class Assistant < Gtk::Window
|
||||
|
||||
# Buttons
|
||||
@bbox = Gtk::HButtonBox.new
|
||||
@bbox.set_border_width(5)
|
||||
@bbox.layout_style = Gtk::ButtonBox::END
|
||||
@bbox.set_spacing(10)
|
||||
create_buttons()
|
||||
@vbox.pack_end(@bbox, false, false, 0)
|
||||
|
||||
# Signals
|
||||
self.signal_connect('destroy') do
|
||||
self.destroy
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Display the left frame
|
||||
#
|
||||
def populate_frame(array)
|
||||
array.each do |item|
|
||||
@vbox_label.pack_start(item, false, false, 0)
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Save configuration for MsfAssistant
|
||||
#
|
||||
def create_save
|
||||
@save_button = Gtk::Button.new(Gtk::Stock::SAVE)
|
||||
$gtk2driver.tips.set_tip(@save_button, "Save your configuration", nil)
|
||||
@save_button.signal_connect('clicked') do
|
||||
save()
|
||||
end
|
||||
return @save_button
|
||||
end
|
||||
|
||||
#
|
||||
# Dummy function
|
||||
#
|
||||
def save
|
||||
raise NotImplementedError, "Subclass must implement save_config()"
|
||||
end
|
||||
|
||||
#
|
||||
# next_page signal function
|
||||
#
|
||||
def next_page
|
||||
raise NotImplementedError, "Subclass must implement next_page()"
|
||||
end
|
||||
include Msf::Ui::Gtk2::MyControls
|
||||
|
||||
#
|
||||
# back_page signal function
|
||||
#
|
||||
def back_page
|
||||
raise NotImplementedError, "Subclass must implement back_page()"
|
||||
end
|
||||
attr_accessor :vbox, :hbox, :main, :page, :bbox, :vbox_left, :vbox_label, :save_button
|
||||
attr_accessor :button_forward
|
||||
|
||||
#
|
||||
# apply signal function
|
||||
#
|
||||
def apply
|
||||
raise NotImplementedError, "Subclass must implement apply()"
|
||||
end
|
||||
|
||||
#
|
||||
# Create Label, the foreground color was determining by the state
|
||||
# state = (true or false)
|
||||
#
|
||||
def create_label(state, text)
|
||||
label = Gtk::Label.new
|
||||
label.set_alignment(0, 0)
|
||||
if state
|
||||
label.set_markup("<span foreground=\"black\"><b>#{text}</b></span>")
|
||||
else
|
||||
label.set_markup("<span foreground=\"#C0C0C0\">#{text}</span>")
|
||||
end
|
||||
return label
|
||||
end
|
||||
|
||||
#
|
||||
# Create dynamics buttons
|
||||
#
|
||||
def create_buttons
|
||||
@button_cancel = Gtk::Button.new(Gtk::Stock::CANCEL)
|
||||
@button_cancel.signal_connect('clicked') do
|
||||
self.destroy
|
||||
end
|
||||
|
||||
@button_back = Gtk::Button.new(Gtk::Stock::GO_BACK)
|
||||
@button_back.signal_connect('clicked') do
|
||||
back_page()
|
||||
end
|
||||
def initialize(title)
|
||||
super
|
||||
self.resizable = false
|
||||
self.set_default_size(600, 400)
|
||||
self.title = title
|
||||
|
||||
@button_apply = Gtk::Button.new(Gtk::Stock::APPLY)
|
||||
@button_apply.signal_connect('clicked') do
|
||||
apply()
|
||||
self.destroy
|
||||
end
|
||||
|
||||
@button_forward = Gtk::Button.new(Gtk::Stock::GO_FORWARD)
|
||||
@button_forward.signal_connect('clicked') do
|
||||
next_page
|
||||
end
|
||||
|
||||
# Display buttons
|
||||
display()
|
||||
end
|
||||
|
||||
#
|
||||
# Init and refresh the backend buttons
|
||||
# Refresh the main view
|
||||
#
|
||||
def display
|
||||
|
||||
# Remove all buttons on the bbox
|
||||
@bbox.each do |widget|
|
||||
@bbox.remove(widget)
|
||||
end
|
||||
|
||||
# Remove all widgets and the main view
|
||||
@main.each do |widget|
|
||||
@main.remove(widget)
|
||||
end
|
||||
|
||||
# Add buttons
|
||||
@bbox.add(@button_cancel)
|
||||
if (not @page == "intro")
|
||||
@bbox.add(@button_back)
|
||||
end
|
||||
|
||||
if (@page == "end")
|
||||
@bbox.add(@button_apply)
|
||||
else
|
||||
@bbox.add(@button_forward)
|
||||
end
|
||||
|
||||
@bbox.show_all
|
||||
end
|
||||
|
||||
#
|
||||
# Refresh the left frame
|
||||
#
|
||||
def refresh_label(hist, actual , nex)
|
||||
if not (hist == nil)
|
||||
hist.each do |label|
|
||||
label.set_markup("<span foreground=\"white\"><i>#{label.text}</i></span>")
|
||||
end
|
||||
end
|
||||
|
||||
actual.each do |label|
|
||||
label.set_markup("<span foreground=\"black\"><b>#{label.text}</b></span>")
|
||||
end
|
||||
|
||||
if not (nex == nil)
|
||||
nex.each do |label|
|
||||
label.set_markup("<span foreground=\"#C0C0C0\"><b>#{label.text}</b></span>")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#########
|
||||
private #
|
||||
#########
|
||||
|
||||
#
|
||||
# Create and return a DrawingArea object
|
||||
#
|
||||
def create_banner
|
||||
|
||||
#
|
||||
# Not use for this moment ...
|
||||
#
|
||||
# da = Gtk::DrawingArea.new
|
||||
# da.set_size_request(600, 60)
|
||||
#
|
||||
# # Signal
|
||||
# da.signal_connect('expose-event') do |widget, event|
|
||||
# cr = widget.window.create_cairo_context
|
||||
# cr.scale(*widget.window.size)
|
||||
# cr.set_line_width(0.04)
|
||||
#
|
||||
# cr.new_path
|
||||
# image = Cairo::ImageSurface.from_png(driver.get_image("banner_assistant.png"))
|
||||
# cr.scale(1.0 / image.width, 1.0 / image.height)
|
||||
# cr.set_source(image, 0, 0)
|
||||
#
|
||||
# cr.paint
|
||||
# end
|
||||
|
||||
da = Gtk::Image.new(driver.get_image("banner_assistant.png"))
|
||||
|
||||
return da
|
||||
end
|
||||
|
||||
#
|
||||
# Create and return the left frame
|
||||
#
|
||||
def create_frame
|
||||
frame_label = Gtk::Frame.new
|
||||
frame_label.set_shadow_type(Gtk::SHADOW_ETCHED_IN)
|
||||
@vbox_label = Gtk::VBox.new(false, 20)
|
||||
frame_label.add(@vbox_label)
|
||||
|
||||
return frame_label
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
# First page
|
||||
@page = "intro"
|
||||
|
||||
# VBox
|
||||
@vbox = Gtk::VBox.new(false, 10)
|
||||
self.add(@vbox)
|
||||
|
||||
# MSF Banner
|
||||
@vbox.pack_start(create_banner(), false, false, 0)
|
||||
|
||||
# HBox
|
||||
@hbox = Gtk::HBox.new(false, 10)
|
||||
@vbox.pack_start(@hbox, true, false, 0)
|
||||
|
||||
# Left frame
|
||||
@vbox_left = Gtk::VBox.new(false, 5)
|
||||
@hbox.pack_start(@vbox_left, false, false, 10)
|
||||
@vbox_left.pack_start(create_frame(), false, false, 10)
|
||||
@vbox_left.pack_start(create_save(), false, false, 5)
|
||||
|
||||
# Main frame
|
||||
@main = Gtk::VBox.new(false, 5)
|
||||
@hbox.pack_start(@main, true, true, 5)
|
||||
|
||||
# Separator
|
||||
separator = Gtk::HSeparator.new
|
||||
@vbox.pack_start(separator, false, false, 0)
|
||||
|
||||
# Buttons
|
||||
@bbox = Gtk::HButtonBox.new
|
||||
@bbox.set_border_width(5)
|
||||
@bbox.layout_style = Gtk::ButtonBox::END
|
||||
@bbox.set_spacing(10)
|
||||
create_buttons()
|
||||
@vbox.pack_end(@bbox, false, false, 0)
|
||||
|
||||
# Signals
|
||||
self.signal_connect('destroy') do
|
||||
self.destroy
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Display the left frame
|
||||
#
|
||||
def populate_frame(array)
|
||||
array.each do |item|
|
||||
@vbox_label.pack_start(item, false, false, 0)
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Save configuration for MsfAssistant
|
||||
#
|
||||
def create_save
|
||||
@save_button = Gtk::Button.new(Gtk::Stock::SAVE)
|
||||
$gtk2driver.tips.set_tip(@save_button, "Save your configuration", nil)
|
||||
@save_button.signal_connect('clicked') do
|
||||
save()
|
||||
end
|
||||
return @save_button
|
||||
end
|
||||
|
||||
#
|
||||
# Dummy function
|
||||
#
|
||||
def save
|
||||
raise NotImplementedError, "Subclass must implement save_config()"
|
||||
end
|
||||
|
||||
#
|
||||
# next_page signal function
|
||||
#
|
||||
def next_page
|
||||
raise NotImplementedError, "Subclass must implement next_page()"
|
||||
end
|
||||
|
||||
#
|
||||
# back_page signal function
|
||||
#
|
||||
def back_page
|
||||
raise NotImplementedError, "Subclass must implement back_page()"
|
||||
end
|
||||
|
||||
#
|
||||
# apply signal function
|
||||
#
|
||||
def apply
|
||||
raise NotImplementedError, "Subclass must implement apply()"
|
||||
end
|
||||
|
||||
#
|
||||
# Create Label, the foreground color was determining by the state
|
||||
# state = (true or false)
|
||||
#
|
||||
def create_label(state, text)
|
||||
label = Gtk::Label.new
|
||||
label.set_alignment(0, 0)
|
||||
if state
|
||||
label.set_markup("<span foreground=\"black\"><b>#{text}</b></span>")
|
||||
else
|
||||
label.set_markup("<span foreground=\"#C0C0C0\">#{text}</span>")
|
||||
end
|
||||
return label
|
||||
end
|
||||
|
||||
#
|
||||
# Create dynamics buttons
|
||||
#
|
||||
def create_buttons
|
||||
@button_cancel = Gtk::Button.new(Gtk::Stock::CANCEL)
|
||||
@button_cancel.signal_connect('clicked') do
|
||||
self.destroy
|
||||
end
|
||||
|
||||
@button_back = Gtk::Button.new(Gtk::Stock::GO_BACK)
|
||||
@button_back.signal_connect('clicked') do
|
||||
back_page()
|
||||
end
|
||||
|
||||
@button_apply = Gtk::Button.new(Gtk::Stock::APPLY)
|
||||
@button_apply.signal_connect('clicked') do
|
||||
apply()
|
||||
self.destroy
|
||||
end
|
||||
|
||||
@button_forward = Gtk::Button.new(Gtk::Stock::GO_FORWARD)
|
||||
@button_forward.signal_connect('clicked') do
|
||||
next_page
|
||||
end
|
||||
|
||||
# Display buttons
|
||||
display()
|
||||
end
|
||||
|
||||
#
|
||||
# Init and refresh the backend buttons
|
||||
# Refresh the main view
|
||||
#
|
||||
def display
|
||||
|
||||
# Remove all buttons on the bbox
|
||||
@bbox.each do |widget|
|
||||
@bbox.remove(widget)
|
||||
end
|
||||
|
||||
# Remove all widgets and the main view
|
||||
@main.each do |widget|
|
||||
@main.remove(widget)
|
||||
end
|
||||
|
||||
# Add buttons
|
||||
@bbox.add(@button_cancel)
|
||||
if (not @page == "intro")
|
||||
@bbox.add(@button_back)
|
||||
end
|
||||
|
||||
if (@page == "end")
|
||||
@bbox.add(@button_apply)
|
||||
else
|
||||
@bbox.add(@button_forward)
|
||||
end
|
||||
|
||||
@bbox.show_all
|
||||
end
|
||||
|
||||
#
|
||||
# Refresh the left frame
|
||||
#
|
||||
def refresh_label(hist, actual , nex)
|
||||
if not (hist == nil)
|
||||
hist.each do |label|
|
||||
label.set_markup("<span foreground=\"white\"><i>#{label.text}</i></span>")
|
||||
end
|
||||
end
|
||||
|
||||
actual.each do |label|
|
||||
label.set_markup("<span foreground=\"black\"><b>#{label.text}</b></span>")
|
||||
end
|
||||
|
||||
if not (nex == nil)
|
||||
nex.each do |label|
|
||||
label.set_markup("<span foreground=\"#C0C0C0\"><b>#{label.text}</b></span>")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#########
|
||||
private #
|
||||
#########
|
||||
|
||||
#
|
||||
# Create and return a DrawingArea object
|
||||
#
|
||||
def create_banner
|
||||
|
||||
#
|
||||
# Not use for this moment ...
|
||||
#
|
||||
# da = Gtk::DrawingArea.new
|
||||
# da.set_size_request(600, 60)
|
||||
#
|
||||
# # Signal
|
||||
# da.signal_connect('expose-event') do |widget, event|
|
||||
# cr = widget.window.create_cairo_context
|
||||
# cr.scale(*widget.window.size)
|
||||
# cr.set_line_width(0.04)
|
||||
#
|
||||
# cr.new_path
|
||||
# image = Cairo::ImageSurface.from_png(driver.get_image("banner_assistant.png"))
|
||||
# cr.scale(1.0 / image.width, 1.0 / image.height)
|
||||
# cr.set_source(image, 0, 0)
|
||||
#
|
||||
# cr.paint
|
||||
# end
|
||||
|
||||
da = Gtk::Image.new(driver.get_image("banner_assistant.png"))
|
||||
|
||||
return da
|
||||
end
|
||||
|
||||
#
|
||||
# Create and return the left frame
|
||||
#
|
||||
def create_frame
|
||||
frame_label = Gtk::Frame.new
|
||||
frame_label.set_shadow_type(Gtk::SHADOW_ETCHED_IN)
|
||||
@vbox_label = Gtk::VBox.new(false, 20)
|
||||
frame_label.add(@vbox_label)
|
||||
|
||||
return frame_label
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,157 +1,156 @@
|
|||
module Msf
|
||||
module Ui
|
||||
module Gtk2
|
||||
module Ui
|
||||
module Gtk2
|
||||
|
||||
class Console
|
||||
require 'rex/io/bidirectional_pipe'
|
||||
|
||||
ID_SESSION, PEER, PAYLOAD, O_SESSION, O_BUFFER = *(0..5).to_a
|
||||
|
||||
#
|
||||
# Classic console herited from Gtk::Window
|
||||
#
|
||||
class Basic < Gtk::Window
|
||||
include Msf::Ui::Gtk2::MyControls
|
||||
|
||||
def initialize(iter)
|
||||
|
||||
# Style
|
||||
console_style = File.join(driver.resource_directory, 'style', 'console.rc')
|
||||
Gtk::RC.parse(console_style)
|
||||
|
||||
super(Gtk::Window::TOPLEVEL)
|
||||
|
||||
@session = iter[O_SESSION]
|
||||
@buffer = iter[O_BUFFER]
|
||||
|
||||
# Layout stuff
|
||||
self.set_default_size(500, 400)
|
||||
self.set_border_width(10)
|
||||
|
||||
# Set title with the tunnel peer
|
||||
self.set_title(@session.tunnel_peer)
|
||||
|
||||
# Skeleton ;-)
|
||||
vbox = Gtk::VBox.new(false, 5)
|
||||
self.add(vbox)
|
||||
|
||||
@textview = Gtk::TextView.new
|
||||
scrolled_window = Gtk::ScrolledWindow.new
|
||||
scrolled_window.add(@textview)
|
||||
vbox.pack_start(scrolled_window, true, true, 5)
|
||||
scrolled_window.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC)
|
||||
|
||||
@cmd_entry = Gtk::Entry.new
|
||||
vbox.pack_start(@cmd_entry, false, false, 0)
|
||||
|
||||
hbox = Gtk::HButtonBox.new
|
||||
hbox.layout_style = Gtk::ButtonBox::END
|
||||
button = Gtk::Button.new(Gtk::Stock::CLOSE)
|
||||
button.signal_connect("clicked") do
|
||||
close_console
|
||||
end
|
||||
hbox.pack_end(button, false, false, 5)
|
||||
vbox.pack_start(hbox, false, false, 0)
|
||||
|
||||
@textview.set_buffer(@buffer)
|
||||
@textview.editable = false
|
||||
@textview.set_cursor_visible(false)
|
||||
@buffer.create_mark('end_mark', @buffer.end_iter, false)
|
||||
|
||||
# Give focus to Gtk::Entry
|
||||
@cmd_entry.can_focus = true
|
||||
@cmd_entry.grab_focus()
|
||||
|
||||
# Signal
|
||||
@cmd_entry.signal_connect('activate') do
|
||||
on_cmd_entry_activate
|
||||
end
|
||||
|
||||
# Create the pipe interface
|
||||
@pipe = Rex::IO::BidirectionalPipe.new
|
||||
|
||||
# Start the session interaction
|
||||
@t_run = Thread.new do
|
||||
@session.interact(@pipe, @pipe)
|
||||
end
|
||||
|
||||
# Create a subscriber with a callback for the UI
|
||||
@sid = @pipe.create_subscriber_proc() do |data|
|
||||
@buffer.insert(@buffer.end_iter, Rex::Text.to_utf8(data))
|
||||
@buffer.move_mark('end_mark', @buffer.end_iter)
|
||||
@textview.scroll_mark_onscreen(@buffer.get_mark('end_mark'))
|
||||
end
|
||||
|
||||
#Gtk::RC.parse(console_style)
|
||||
|
||||
self.show_all
|
||||
|
||||
# Kill the interaction thread
|
||||
#@t_run.kill
|
||||
|
||||
# Close the pipes
|
||||
#@pipe.close
|
||||
|
||||
end
|
||||
|
||||
#
|
||||
# update access
|
||||
#
|
||||
def update_access
|
||||
last_access = Time.now
|
||||
end
|
||||
|
||||
#
|
||||
# Signal for user entry
|
||||
#
|
||||
def on_cmd_entry_activate
|
||||
send_cmd(@cmd_entry.text)
|
||||
end
|
||||
|
||||
#
|
||||
# Send command to bidirectionnal_pipe
|
||||
#
|
||||
def send_cmd(cmd)
|
||||
|
||||
update_access
|
||||
|
||||
# Write the command plus a newline to the input
|
||||
@pipe.write_input(cmd + "\n")
|
||||
|
||||
# Clear the text entry
|
||||
@cmd_entry.set_text("")
|
||||
end
|
||||
|
||||
#
|
||||
# Just close the console, not kill !
|
||||
#
|
||||
def close_console
|
||||
self.destroy
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Meterpreter Console
|
||||
#
|
||||
class Meterpreter < Msf::Ui::Gtk2::Console::Basic
|
||||
|
||||
def inititialize(iter)
|
||||
print "On the meterpreter console place"
|
||||
super(iter)
|
||||
print @session.run_cmd("help")
|
||||
end
|
||||
end
|
||||
end
|
||||
class Console
|
||||
require 'rex/io/bidirectional_pipe'
|
||||
|
||||
ID_SESSION, PEER, PAYLOAD, O_SESSION, O_BUFFER = *(0..5).to_a
|
||||
|
||||
#
|
||||
# Classic console herited from Gtk::Window
|
||||
#
|
||||
class Basic < Gtk::Window
|
||||
include Msf::Ui::Gtk2::MyControls
|
||||
|
||||
def initialize(iter)
|
||||
|
||||
# Style
|
||||
console_style = File.join(driver.resource_directory, 'style', 'console.rc')
|
||||
Gtk::RC.parse(console_style)
|
||||
|
||||
super(Gtk::Window::TOPLEVEL)
|
||||
|
||||
@session = iter[O_SESSION]
|
||||
@buffer = iter[O_BUFFER]
|
||||
|
||||
# Layout stuff
|
||||
self.set_default_size(500, 400)
|
||||
self.set_border_width(10)
|
||||
|
||||
# Set title with the tunnel peer
|
||||
self.set_title(@session.tunnel_peer)
|
||||
|
||||
# Skeleton ;-)
|
||||
vbox = Gtk::VBox.new(false, 5)
|
||||
self.add(vbox)
|
||||
|
||||
@textview = Gtk::TextView.new
|
||||
scrolled_window = Gtk::ScrolledWindow.new
|
||||
scrolled_window.add(@textview)
|
||||
vbox.pack_start(scrolled_window, true, true, 5)
|
||||
scrolled_window.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC)
|
||||
|
||||
@cmd_entry = Gtk::Entry.new
|
||||
vbox.pack_start(@cmd_entry, false, false, 0)
|
||||
|
||||
hbox = Gtk::HButtonBox.new
|
||||
hbox.layout_style = Gtk::ButtonBox::END
|
||||
button = Gtk::Button.new(Gtk::Stock::CLOSE)
|
||||
button.signal_connect("clicked") do
|
||||
close_console
|
||||
end
|
||||
hbox.pack_end(button, false, false, 5)
|
||||
vbox.pack_start(hbox, false, false, 0)
|
||||
|
||||
@textview.set_buffer(@buffer)
|
||||
@textview.editable = false
|
||||
@textview.set_cursor_visible(false)
|
||||
@buffer.create_mark('end_mark', @buffer.end_iter, false)
|
||||
|
||||
# Give focus to Gtk::Entry
|
||||
@cmd_entry.can_focus = true
|
||||
@cmd_entry.grab_focus()
|
||||
|
||||
# Signal
|
||||
@cmd_entry.signal_connect('activate') do
|
||||
on_cmd_entry_activate
|
||||
end
|
||||
|
||||
# Create the pipe interface
|
||||
@pipe = Rex::IO::BidirectionalPipe.new
|
||||
|
||||
# Start the session interaction
|
||||
@t_run = Thread.new do
|
||||
@session.interact(@pipe, @pipe)
|
||||
end
|
||||
|
||||
# Create a subscriber with a callback for the UI
|
||||
@sid = @pipe.create_subscriber_proc() do |data|
|
||||
@buffer.insert(@buffer.end_iter, Rex::Text.to_utf8(data))
|
||||
@buffer.move_mark('end_mark', @buffer.end_iter)
|
||||
@textview.scroll_mark_onscreen(@buffer.get_mark('end_mark'))
|
||||
end
|
||||
|
||||
#Gtk::RC.parse(console_style)
|
||||
|
||||
self.show_all
|
||||
|
||||
# Kill the interaction thread
|
||||
#@t_run.kill
|
||||
|
||||
# Close the pipes
|
||||
#@pipe.close
|
||||
|
||||
end
|
||||
|
||||
#
|
||||
# update access
|
||||
#
|
||||
def update_access
|
||||
last_access = Time.now
|
||||
end
|
||||
|
||||
#
|
||||
# Signal for user entry
|
||||
#
|
||||
def on_cmd_entry_activate
|
||||
send_cmd(@cmd_entry.text)
|
||||
end
|
||||
|
||||
#
|
||||
# Send command to bidirectionnal_pipe
|
||||
#
|
||||
def send_cmd(cmd)
|
||||
|
||||
update_access
|
||||
|
||||
# Write the command plus a newline to the input
|
||||
@pipe.write_input(cmd + "\n")
|
||||
|
||||
# Clear the text entry
|
||||
@cmd_entry.set_text("")
|
||||
end
|
||||
|
||||
#
|
||||
# Just close the console, not kill !
|
||||
#
|
||||
def close_console
|
||||
self.destroy
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Meterpreter Console
|
||||
#
|
||||
class Meterpreter < Msf::Ui::Gtk2::Console::Basic
|
||||
|
||||
def inititialize(iter)
|
||||
print "On the meterpreter console place"
|
||||
super(iter)
|
||||
print @session.run_cmd("help")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
class GtkConsolePipe < Rex::IO::BidirectionalPipe
|
||||
def prompting?
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
class GtkConsolePipe < Rex::IO::BidirectionalPipe
|
||||
def prompting?
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,39 +1,39 @@
|
|||
module Msf
|
||||
module Ui
|
||||
module Gtk2
|
||||
module Ui
|
||||
module Gtk2
|
||||
|
||||
module MyControls
|
||||
module MyControls
|
||||
|
||||
#
|
||||
# Included class methods
|
||||
#
|
||||
#
|
||||
# Included class methods
|
||||
#
|
||||
|
||||
# Get the global driver handle
|
||||
def driver
|
||||
$gtk2driver
|
||||
end
|
||||
|
||||
# Return the framework instance from the driver handler
|
||||
def framework
|
||||
driver.framework
|
||||
end
|
||||
# Get the global driver handle
|
||||
def driver
|
||||
$gtk2driver
|
||||
end
|
||||
|
||||
def log(msg)
|
||||
if ($gtk2logger)
|
||||
$gtk2logger.append_text(msg + "\n")
|
||||
else
|
||||
$stderr.puts Time.now.to_s + " " + msg
|
||||
end
|
||||
end
|
||||
# Return the framework instance from the driver handler
|
||||
def framework
|
||||
driver.framework
|
||||
end
|
||||
|
||||
#
|
||||
# Controls
|
||||
#
|
||||
|
||||
# TODO: Add control here
|
||||
def log(msg)
|
||||
if ($gtk2logger)
|
||||
$gtk2logger.append_text(msg + "\n")
|
||||
else
|
||||
$stderr.puts Time.now.to_s + " " + msg
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
#
|
||||
# Controls
|
||||
#
|
||||
|
||||
# TODO: Add control here
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,134 +1,134 @@
|
|||
module Msf
|
||||
module Ui
|
||||
module Gtk2
|
||||
module Ui
|
||||
module Gtk2
|
||||
|
||||
class SkeletonAlert < Gtk::Dialog
|
||||
def initialize(parent, title, stock_icon, buttons, message=nil)
|
||||
super("", parent, Gtk::Dialog::DESTROY_WITH_PARENT, *buttons)
|
||||
|
||||
self.border_width = 6
|
||||
self.resizable = false
|
||||
self.has_separator = false
|
||||
self.vbox.spacing = 12
|
||||
|
||||
hbox = Gtk::HBox.new(false, 12)
|
||||
hbox.border_width = 6
|
||||
self.vbox.pack_start(hbox)
|
||||
|
||||
image = Gtk::Image.new(stock_icon,
|
||||
Gtk::IconSize::DIALOG)
|
||||
image.set_alignment(0.5, 0)
|
||||
hbox.pack_start(image)
|
||||
|
||||
vbox = Gtk::VBox.new(false, 6)
|
||||
hbox.pack_start(vbox)
|
||||
|
||||
label = Gtk::Label.new
|
||||
label.set_alignment(0, 0)
|
||||
label.wrap = true
|
||||
label.markup = "<b><big>#{title}</big></b>"
|
||||
vbox.pack_start(label)
|
||||
|
||||
if message
|
||||
label = Gtk::Label.new
|
||||
label.markup = message.strip
|
||||
label.set_alignment(0, 0)
|
||||
label.wrap = true
|
||||
vbox.pack_start(label)
|
||||
end
|
||||
end
|
||||
end
|
||||
class SkeletonAlert < Gtk::Dialog
|
||||
def initialize(parent, title, stock_icon, buttons, message=nil)
|
||||
super("", parent, Gtk::Dialog::DESTROY_WITH_PARENT, *buttons)
|
||||
|
||||
class SkeletonView < Gtk::Dialog
|
||||
def initialize(title, buffer)
|
||||
super(title, $gtk2driver.main, Gtk::Dialog::Flags::MODAL,
|
||||
[ Gtk::Stock::CLOSE, Gtk::Dialog::RESPONSE_NONE ])
|
||||
|
||||
self.border_width = 10
|
||||
self.vbox.spacing = 10
|
||||
self.set_default_size(400, 350)
|
||||
|
||||
view = Gtk::TextView.new(buffer)
|
||||
scrolled_window = Gtk::ScrolledWindow.new
|
||||
scrolled_window.add(view)
|
||||
self.vbox.pack_start(scrolled_window, true, true, 5)
|
||||
scrolled_window.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC)
|
||||
end
|
||||
end
|
||||
self.border_width = 6
|
||||
self.resizable = false
|
||||
self.has_separator = false
|
||||
self.vbox.spacing = 12
|
||||
|
||||
##
|
||||
# Class and subclass for all MsfDialog
|
||||
##
|
||||
class MsfDialog
|
||||
|
||||
##
|
||||
# Class for the payload rendering
|
||||
# title: the payload refname
|
||||
# payload: the generated payload
|
||||
##
|
||||
class Payload < Msf::Ui::Gtk2::SkeletonView
|
||||
def initialize(title, payload)
|
||||
@buffer = Gtk::TextBuffer.new
|
||||
super(title, @buffer)
|
||||
|
||||
colorize()
|
||||
display(payload)
|
||||
|
||||
self.default_response = Gtk::Dialog::RESPONSE_NONE
|
||||
show_all and run
|
||||
destroy
|
||||
end
|
||||
|
||||
#
|
||||
# Display the generated payload with color
|
||||
#
|
||||
def display(payload)
|
||||
filter = /^\#/
|
||||
@buffer.delete(*@buffer.bounds)
|
||||
start = @buffer.get_iter_at_offset(0)
|
||||
|
||||
payload.each do |line|
|
||||
if ( line.match(filter) )
|
||||
@buffer.insert_with_tags(start, line, 'comments')
|
||||
else
|
||||
@buffer.insert_with_tags(start, line, '_')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Create tags for the syntax color
|
||||
#
|
||||
def colorize
|
||||
@buffer.create_tag("comments",
|
||||
:'foreground' => 'RosyBrown',
|
||||
:'weight' => Pango::FontDescription::WEIGHT_BOLD
|
||||
)
|
||||
|
||||
@buffer.create_tag("_",
|
||||
:'weight' => Pango::FontDescription::WEIGHT_BOLD
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Display an error Gtk style
|
||||
# parent: the Gtk parent widget
|
||||
# title: the error title
|
||||
# message: the error
|
||||
##
|
||||
class Error < Msf::Ui::Gtk2::SkeletonAlert
|
||||
def initialize(parent, title, message=nil)
|
||||
super(parent, title, Gtk::Stock::DIALOG_ERROR,
|
||||
[[Gtk::Stock::OK, Gtk::Dialog::RESPONSE_OK]],
|
||||
message)
|
||||
self.default_response = Gtk::Dialog::RESPONSE_OK
|
||||
show_all and run
|
||||
destroy
|
||||
end
|
||||
end
|
||||
end
|
||||
hbox = Gtk::HBox.new(false, 12)
|
||||
hbox.border_width = 6
|
||||
self.vbox.pack_start(hbox)
|
||||
|
||||
end
|
||||
end
|
||||
image = Gtk::Image.new(stock_icon,
|
||||
Gtk::IconSize::DIALOG)
|
||||
image.set_alignment(0.5, 0)
|
||||
hbox.pack_start(image)
|
||||
|
||||
vbox = Gtk::VBox.new(false, 6)
|
||||
hbox.pack_start(vbox)
|
||||
|
||||
label = Gtk::Label.new
|
||||
label.set_alignment(0, 0)
|
||||
label.wrap = true
|
||||
label.markup = "<b><big>#{title}</big></b>"
|
||||
vbox.pack_start(label)
|
||||
|
||||
if message
|
||||
label = Gtk::Label.new
|
||||
label.markup = message.strip
|
||||
label.set_alignment(0, 0)
|
||||
label.wrap = true
|
||||
vbox.pack_start(label)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class SkeletonView < Gtk::Dialog
|
||||
def initialize(title, buffer)
|
||||
super(title, $gtk2driver.main, Gtk::Dialog::Flags::MODAL,
|
||||
[ Gtk::Stock::CLOSE, Gtk::Dialog::RESPONSE_NONE ])
|
||||
|
||||
self.border_width = 10
|
||||
self.vbox.spacing = 10
|
||||
self.set_default_size(400, 350)
|
||||
|
||||
view = Gtk::TextView.new(buffer)
|
||||
scrolled_window = Gtk::ScrolledWindow.new
|
||||
scrolled_window.add(view)
|
||||
self.vbox.pack_start(scrolled_window, true, true, 5)
|
||||
scrolled_window.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC)
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Class and subclass for all MsfDialog
|
||||
##
|
||||
class MsfDialog
|
||||
|
||||
##
|
||||
# Class for the payload rendering
|
||||
# title: the payload refname
|
||||
# payload: the generated payload
|
||||
##
|
||||
class Payload < Msf::Ui::Gtk2::SkeletonView
|
||||
def initialize(title, payload)
|
||||
@buffer = Gtk::TextBuffer.new
|
||||
super(title, @buffer)
|
||||
|
||||
colorize()
|
||||
display(payload)
|
||||
|
||||
self.default_response = Gtk::Dialog::RESPONSE_NONE
|
||||
show_all and run
|
||||
destroy
|
||||
end
|
||||
|
||||
#
|
||||
# Display the generated payload with color
|
||||
#
|
||||
def display(payload)
|
||||
filter = /^\#/
|
||||
@buffer.delete(*@buffer.bounds)
|
||||
start = @buffer.get_iter_at_offset(0)
|
||||
|
||||
payload.each do |line|
|
||||
if ( line.match(filter) )
|
||||
@buffer.insert_with_tags(start, line, 'comments')
|
||||
else
|
||||
@buffer.insert_with_tags(start, line, '_')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Create tags for the syntax color
|
||||
#
|
||||
def colorize
|
||||
@buffer.create_tag("comments",
|
||||
:'foreground' => 'RosyBrown',
|
||||
:'weight' => Pango::FontDescription::WEIGHT_BOLD
|
||||
)
|
||||
|
||||
@buffer.create_tag("_",
|
||||
:'weight' => Pango::FontDescription::WEIGHT_BOLD
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Display an error Gtk style
|
||||
# parent: the Gtk parent widget
|
||||
# title: the error title
|
||||
# message: the error
|
||||
##
|
||||
class Error < Msf::Ui::Gtk2::SkeletonAlert
|
||||
def initialize(parent, title, message=nil)
|
||||
super(parent, title, Gtk::Stock::DIALOG_ERROR,
|
||||
[[Gtk::Stock::OK, Gtk::Dialog::RESPONSE_OK]],
|
||||
message)
|
||||
self.default_response = Gtk::Dialog::RESPONSE_OK
|
||||
show_all and run
|
||||
destroy
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -19,155 +19,155 @@ require 'msf/ui/gtk2/opcode'
|
|||
require 'msf/ui/gtk2/framework_event_manager'
|
||||
|
||||
module Msf
|
||||
module Ui
|
||||
module Gtk2
|
||||
module Ui
|
||||
module Gtk2
|
||||
|
||||
###
|
||||
#
|
||||
# This class implements a user interface driver on a gtk2 interface.
|
||||
#
|
||||
###
|
||||
class Driver < Msf::Ui::Driver
|
||||
|
||||
attr_accessor :session_tree, :module_tree, :job_tree, :log_text, :module_model
|
||||
attr_accessor :module_completion, :main, :tips
|
||||
|
||||
include Msf::Ui::Gtk2::FrameworkEventManager
|
||||
|
||||
ConfigCore = "framework/core"
|
||||
ConfigGroup = "framework/ui/gtk2"
|
||||
|
||||
#
|
||||
# The default resource directory for msfgui
|
||||
#
|
||||
DefaultResourceDirectory = Msf::Config.data_directory + File::SEPARATOR + "msfgui"
|
||||
|
||||
#
|
||||
# Initializes a gtk2 driver instance
|
||||
#
|
||||
def initialize(opts = {})
|
||||
# Call the parent
|
||||
super()
|
||||
###
|
||||
#
|
||||
# This class implements a user interface driver on a gtk2 interface.
|
||||
#
|
||||
###
|
||||
class Driver < Msf::Ui::Driver
|
||||
|
||||
# Set the passed options hash for referencing later on.
|
||||
self.opts = opts
|
||||
attr_accessor :session_tree, :module_tree, :job_tree, :log_text, :module_model
|
||||
attr_accessor :module_completion, :main, :tips
|
||||
|
||||
# Initialize configuration
|
||||
Msf::Config.init
|
||||
|
||||
# Initialize logging
|
||||
initialize_logging
|
||||
include Msf::Ui::Gtk2::FrameworkEventManager
|
||||
|
||||
# Initialize attributes
|
||||
self.framework = Msf::Simple::Framework.create
|
||||
|
||||
# Create the gtk2driver global
|
||||
$gtk2driver = self
|
||||
|
||||
# Init GTK2
|
||||
Gtk.init
|
||||
|
||||
# Initialize the Gtk2 application object
|
||||
@gtk2app = Msf::Ui::Gtk2::MyApp.new()
|
||||
|
||||
# Register event handlers
|
||||
register_event_handlers
|
||||
end
|
||||
ConfigCore = "framework/core"
|
||||
ConfigGroup = "framework/ui/gtk2"
|
||||
|
||||
#
|
||||
# Starts the main gtk2 loop
|
||||
#
|
||||
def run
|
||||
ilog("msfgui has been started", LogSource)
|
||||
Gtk.main
|
||||
true
|
||||
end
|
||||
#
|
||||
# The default resource directory for msfgui
|
||||
#
|
||||
DefaultResourceDirectory = Msf::Config.data_directory + File::SEPARATOR + "msfgui"
|
||||
|
||||
#
|
||||
# Returns the local directory that will hold the files to be serviced.
|
||||
#
|
||||
def resource_directory
|
||||
opts['ResourceDirectory'] || DefaultResourceDirectory
|
||||
end
|
||||
|
||||
#
|
||||
# Saves configuration for MsfAssistant.
|
||||
#
|
||||
def save_config(active_module)
|
||||
# Build out the assistant config group
|
||||
group = {}
|
||||
#
|
||||
# Initializes a gtk2 driver instance
|
||||
#
|
||||
def initialize(opts = {})
|
||||
# Call the parent
|
||||
super()
|
||||
|
||||
if (active_module)
|
||||
group['ActiveModule'] = active_module.fullname
|
||||
end
|
||||
# Set the passed options hash for referencing later on.
|
||||
self.opts = opts
|
||||
|
||||
# Save it
|
||||
begin
|
||||
Msf::Config.save(
|
||||
ConfigGroup => group)
|
||||
rescue
|
||||
MsfDialog::Error.new(self, "Failed to save config file : #{$!}")
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Returns a new Gdk::Pixbuf object
|
||||
#
|
||||
def get_icon(name)
|
||||
Gdk::Pixbuf.new(File.join(resource_directory, 'pix', name))
|
||||
end
|
||||
|
||||
#
|
||||
# Returns only pics
|
||||
#
|
||||
def get_image(name)
|
||||
return File.join(resource_directory, 'pix', name)
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Adds text to the main logging screen
|
||||
#
|
||||
def append_log_view(data)
|
||||
|
||||
data = Time.now.strftime("%H:%m:%S") + " " + data
|
||||
|
||||
return if not self.log_text
|
||||
|
||||
view = self.log_text
|
||||
buff = view.buffer
|
||||
|
||||
if (not buff.get_mark('end_mark'))
|
||||
buff.create_mark('end_mark', buff.end_iter, false)
|
||||
end
|
||||
|
||||
buff.insert(buff.end_iter, Rex::Text.to_utf8(data))
|
||||
buff.move_mark('end_mark', buff.end_iter)
|
||||
view.scroll_mark_onscreen(buff.get_mark('end_mark'))
|
||||
end
|
||||
|
||||
# Initialize configuration
|
||||
Msf::Config.init
|
||||
|
||||
#
|
||||
# The framework instance associated with this driver.
|
||||
#
|
||||
attr_reader :framework
|
||||
# Initialize logging
|
||||
initialize_logging
|
||||
|
||||
protected
|
||||
# Initialize attributes
|
||||
self.framework = Msf::Simple::Framework.create
|
||||
|
||||
attr_writer :framework # :nodoc:
|
||||
attr_accessor :opts # :nodoc:
|
||||
# Create the gtk2driver global
|
||||
$gtk2driver = self
|
||||
|
||||
#
|
||||
# Initializes logging for the Gtk2 driver.
|
||||
#
|
||||
def initialize_logging
|
||||
level = (opts['LogLevel'] || 0).to_i
|
||||
# Init GTK2
|
||||
Gtk.init
|
||||
|
||||
Msf::Logging.enable_log_source(LogSource, level)
|
||||
end
|
||||
# Initialize the Gtk2 application object
|
||||
@gtk2app = Msf::Ui::Gtk2::MyApp.new()
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
# Register event handlers
|
||||
register_event_handlers
|
||||
end
|
||||
|
||||
#
|
||||
# Starts the main gtk2 loop
|
||||
#
|
||||
def run
|
||||
ilog("msfgui has been started", LogSource)
|
||||
Gtk.main
|
||||
true
|
||||
end
|
||||
|
||||
#
|
||||
# Returns the local directory that will hold the files to be serviced.
|
||||
#
|
||||
def resource_directory
|
||||
opts['ResourceDirectory'] || DefaultResourceDirectory
|
||||
end
|
||||
|
||||
#
|
||||
# Saves configuration for MsfAssistant.
|
||||
#
|
||||
def save_config(active_module)
|
||||
# Build out the assistant config group
|
||||
group = {}
|
||||
|
||||
if (active_module)
|
||||
group['ActiveModule'] = active_module.fullname
|
||||
end
|
||||
|
||||
# Save it
|
||||
begin
|
||||
Msf::Config.save(
|
||||
ConfigGroup => group)
|
||||
rescue
|
||||
MsfDialog::Error.new(self, "Failed to save config file : #{$!}")
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Returns a new Gdk::Pixbuf object
|
||||
#
|
||||
def get_icon(name)
|
||||
Gdk::Pixbuf.new(File.join(resource_directory, 'pix', name))
|
||||
end
|
||||
|
||||
#
|
||||
# Returns only pics
|
||||
#
|
||||
def get_image(name)
|
||||
return File.join(resource_directory, 'pix', name)
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Adds text to the main logging screen
|
||||
#
|
||||
def append_log_view(data)
|
||||
|
||||
data = Time.now.strftime("%H:%m:%S") + " " + data
|
||||
|
||||
return if not self.log_text
|
||||
|
||||
view = self.log_text
|
||||
buff = view.buffer
|
||||
|
||||
if (not buff.get_mark('end_mark'))
|
||||
buff.create_mark('end_mark', buff.end_iter, false)
|
||||
end
|
||||
|
||||
buff.insert(buff.end_iter, Rex::Text.to_utf8(data))
|
||||
buff.move_mark('end_mark', buff.end_iter)
|
||||
view.scroll_mark_onscreen(buff.get_mark('end_mark'))
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# The framework instance associated with this driver.
|
||||
#
|
||||
attr_reader :framework
|
||||
|
||||
protected
|
||||
|
||||
attr_writer :framework # :nodoc:
|
||||
attr_accessor :opts # :nodoc:
|
||||
|
||||
#
|
||||
# Initializes logging for the Gtk2 driver.
|
||||
#
|
||||
def initialize_logging
|
||||
level = (opts['LogLevel'] || 0).to_i
|
||||
|
||||
Msf::Logging.enable_log_source(LogSource, level)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
require 'msf/ui/gtk2/frame/modules_tree'
|
||||
require 'msf/ui/gtk2/frame/sessions_tree'
|
||||
require 'msf/ui/gtk2/frame/jobs_tree'
|
||||
require 'msf/ui/gtk2/frame/jobs_tree'
|
||||
|
|
|
@ -1,181 +1,181 @@
|
|||
module Msf
|
||||
module Ui
|
||||
module Gtk2
|
||||
module Ui
|
||||
module Gtk2
|
||||
|
||||
class MyJobTree < MyGlade
|
||||
PIX, TIME, NAME, OBJECT, RHOST, REFNAME = *(0..6).to_a
|
||||
|
||||
include Msf::Ui::Gtk2::MyControls
|
||||
class MyJobTree < MyGlade
|
||||
PIX, TIME, NAME, OBJECT, RHOST, REFNAME = *(0..6).to_a
|
||||
|
||||
def initialize(treeview)
|
||||
@treeview2 = treeview
|
||||
|
||||
@model = Gtk::TreeStore.new(Gdk::Pixbuf, # Pix rhost
|
||||
String, # process TIME
|
||||
String, # exploit shortname
|
||||
Object, # Exploit Object
|
||||
String, # Remote host
|
||||
String # exploit refname
|
||||
)
|
||||
|
||||
# Renderer
|
||||
renderer_pix = Gtk::CellRendererPixbuf.new
|
||||
renderer_time = Gtk::CellRendererText.new
|
||||
renderer_name = Gtk::CellRendererText.new
|
||||
|
||||
# Time Gtk::TreeViewColumn
|
||||
column_time = Gtk::TreeViewColumn.new
|
||||
#column_time.set_title("rhost")
|
||||
column_time.pack_start(renderer_pix, false)
|
||||
column_time.set_cell_data_func(renderer_pix) do |column, cell, model, iter|
|
||||
cell.pixbuf = iter[PIX]
|
||||
end
|
||||
column_time.pack_start(renderer_time, true)
|
||||
column_time.set_cell_data_func(renderer_time) do |column, cell, model, iter|
|
||||
cell.text = iter[TIME]
|
||||
end
|
||||
column_time.sort_column_id = TIME
|
||||
|
||||
# Name Gtk::TreeViewColumn
|
||||
column_name = Gtk::TreeViewColumn.new
|
||||
column_name.set_title("Module")
|
||||
column_name.pack_start(renderer_name, true)
|
||||
column_name.set_cell_data_func(renderer_name) do |column, cell, model, iter|
|
||||
cell.text = iter[NAME]
|
||||
end
|
||||
|
||||
#set model to treeview
|
||||
@treeview2.set_model(@model)
|
||||
|
||||
@selection = @treeview2.selection
|
||||
@treeview2.selection.mode = Gtk::SELECTION_BROWSE
|
||||
@treeview2.rules_hint = true
|
||||
|
||||
# Add Gtk::TreeViewColumn
|
||||
@treeview2.append_column(column_time)
|
||||
@treeview2.append_column(column_name)
|
||||
|
||||
# Add AutoPWN
|
||||
@autopwn_iter = @model.append(nil)
|
||||
@autopwn_iter.set_value(PIX, driver.get_icon("menu_autopwn.png"))
|
||||
@autopwn_iter.set_value(TIME, "AutoPWN")
|
||||
|
||||
# Add Parent "One shot"
|
||||
@oneshot_iter = @model.append(nil)
|
||||
@oneshot_iter.set_value(PIX, driver.get_icon("menu_oneshot.png"))
|
||||
@oneshot_iter.set_value(TIME, "One shot")
|
||||
|
||||
# Job Gtk::Menu
|
||||
@menu_job = Gtk::Menu.new
|
||||
|
||||
# Stop job
|
||||
kill_job_item_shell = Gtk::ImageMenuItem.new("Kill Job")
|
||||
kill_job_image_shell = Gtk::Image.new
|
||||
kill_job_image_shell.set(Gtk::Stock::CLOSE, Gtk::IconSize::MENU)
|
||||
kill_job_item_shell.set_image(kill_job_image_shell)
|
||||
@menu_job.append(kill_job_item_shell)
|
||||
|
||||
# Refresh
|
||||
refresh_job_item_shell = Gtk::ImageMenuItem.new("Refresh")
|
||||
refresh_job_image_shell = Gtk::Image.new
|
||||
refresh_job_image_shell.set(Gtk::Stock::REFRESH, Gtk::IconSize::MENU)
|
||||
refresh_job_item_shell.set_image(refresh_job_image_shell)
|
||||
@menu_job.append(refresh_job_item_shell)
|
||||
include Msf::Ui::Gtk2::MyControls
|
||||
|
||||
@menu_job.show_all
|
||||
|
||||
# TreeView Signals
|
||||
@treeview2.signal_connect('button_press_event') do |treeview, event|
|
||||
if event.kind_of? Gdk::EventButton
|
||||
if (event.button == 3)
|
||||
path, column, x, y = treeview.get_path_at_pos(event.x, event.y)
|
||||
|
||||
begin
|
||||
iter = @treeview2.model.get_iter(path)
|
||||
treeview.selection.select_path(path)
|
||||
@menu_job.popup(nil, nil, event.button, event.time)
|
||||
rescue
|
||||
nil
|
||||
#@menu_job.popup(nil, nil, event.button, event.time)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Menu Signals
|
||||
kill_job_item_shell.signal_connect('activate') do |item|
|
||||
if current = @selection.selected
|
||||
stop_job(current)
|
||||
end
|
||||
end
|
||||
def initialize(treeview)
|
||||
@treeview2 = treeview
|
||||
|
||||
refresh_job_item_shell.signal_connect('activate') do |item|
|
||||
refresh_job()
|
||||
end
|
||||
|
||||
end # def initialize
|
||||
|
||||
#
|
||||
# Add One Shot
|
||||
#
|
||||
def add_oneshot(exploit, rhost)
|
||||
time = Time.now
|
||||
oneshot_childiter = @model.append(@oneshot_iter)
|
||||
#oneshot_childiter.set_value(PIX, nil)
|
||||
oneshot_childiter.set_value(TIME, Time.now.strftime("%H:%m:%S"))
|
||||
oneshot_childiter.set_value(NAME, exploit.shortname)
|
||||
oneshot_childiter.set_value(OBJECT, exploit)
|
||||
oneshot_childiter.set_value(RHOST, rhost)
|
||||
oneshot_childiter.set_value(REFNAME, exploit.refname)
|
||||
@treeview2.expand_all()
|
||||
end
|
||||
|
||||
#
|
||||
# Stop job and remove it from the job tree
|
||||
#
|
||||
def stop_job(iter)
|
||||
framework.jobs.each_key do |i|
|
||||
if (framework.jobs[i].name.split(": ")[1] == iter[REFNAME])
|
||||
|
||||
# Stopping job
|
||||
framework.jobs.stop_job(i)
|
||||
|
||||
# Informing the user
|
||||
$gtk2driver.append_log_view("[*] Stopping exploit: #{iter[REFNAME]}")
|
||||
|
||||
# Removing the job from the job tree
|
||||
@model.remove(iter)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Refresh job
|
||||
#
|
||||
def refresh_job
|
||||
puts "TODO: refresh the job tree =>"
|
||||
framework.jobs.keys.sort.each do |k|
|
||||
puts framework.jobs[k].name
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Remove Target if not a passive exploit
|
||||
#
|
||||
def remove_job(rhost, name)
|
||||
found = nil
|
||||
@model.each do |model,path,iter|
|
||||
if (iter[RHOST] == rhost and iter[REFNAME] == name and iter[OBJECT].passive? == false)
|
||||
found = iter
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
@model.remove(found) if found
|
||||
end
|
||||
|
||||
@model = Gtk::TreeStore.new(Gdk::Pixbuf, # Pix rhost
|
||||
String, # process TIME
|
||||
String, # exploit shortname
|
||||
Object, # Exploit Object
|
||||
String, # Remote host
|
||||
String # exploit refname
|
||||
)
|
||||
|
||||
# Renderer
|
||||
renderer_pix = Gtk::CellRendererPixbuf.new
|
||||
renderer_time = Gtk::CellRendererText.new
|
||||
renderer_name = Gtk::CellRendererText.new
|
||||
|
||||
# Time Gtk::TreeViewColumn
|
||||
column_time = Gtk::TreeViewColumn.new
|
||||
#column_time.set_title("rhost")
|
||||
column_time.pack_start(renderer_pix, false)
|
||||
column_time.set_cell_data_func(renderer_pix) do |column, cell, model, iter|
|
||||
cell.pixbuf = iter[PIX]
|
||||
end
|
||||
column_time.pack_start(renderer_time, true)
|
||||
column_time.set_cell_data_func(renderer_time) do |column, cell, model, iter|
|
||||
cell.text = iter[TIME]
|
||||
end
|
||||
column_time.sort_column_id = TIME
|
||||
|
||||
# Name Gtk::TreeViewColumn
|
||||
column_name = Gtk::TreeViewColumn.new
|
||||
column_name.set_title("Module")
|
||||
column_name.pack_start(renderer_name, true)
|
||||
column_name.set_cell_data_func(renderer_name) do |column, cell, model, iter|
|
||||
cell.text = iter[NAME]
|
||||
end
|
||||
|
||||
#set model to treeview
|
||||
@treeview2.set_model(@model)
|
||||
|
||||
@selection = @treeview2.selection
|
||||
@treeview2.selection.mode = Gtk::SELECTION_BROWSE
|
||||
@treeview2.rules_hint = true
|
||||
|
||||
# Add Gtk::TreeViewColumn
|
||||
@treeview2.append_column(column_time)
|
||||
@treeview2.append_column(column_name)
|
||||
|
||||
# Add AutoPWN
|
||||
@autopwn_iter = @model.append(nil)
|
||||
@autopwn_iter.set_value(PIX, driver.get_icon("menu_autopwn.png"))
|
||||
@autopwn_iter.set_value(TIME, "AutoPWN")
|
||||
|
||||
# Add Parent "One shot"
|
||||
@oneshot_iter = @model.append(nil)
|
||||
@oneshot_iter.set_value(PIX, driver.get_icon("menu_oneshot.png"))
|
||||
@oneshot_iter.set_value(TIME, "One shot")
|
||||
|
||||
# Job Gtk::Menu
|
||||
@menu_job = Gtk::Menu.new
|
||||
|
||||
# Stop job
|
||||
kill_job_item_shell = Gtk::ImageMenuItem.new("Kill Job")
|
||||
kill_job_image_shell = Gtk::Image.new
|
||||
kill_job_image_shell.set(Gtk::Stock::CLOSE, Gtk::IconSize::MENU)
|
||||
kill_job_item_shell.set_image(kill_job_image_shell)
|
||||
@menu_job.append(kill_job_item_shell)
|
||||
|
||||
# Refresh
|
||||
refresh_job_item_shell = Gtk::ImageMenuItem.new("Refresh")
|
||||
refresh_job_image_shell = Gtk::Image.new
|
||||
refresh_job_image_shell.set(Gtk::Stock::REFRESH, Gtk::IconSize::MENU)
|
||||
refresh_job_item_shell.set_image(refresh_job_image_shell)
|
||||
@menu_job.append(refresh_job_item_shell)
|
||||
|
||||
@menu_job.show_all
|
||||
|
||||
# TreeView Signals
|
||||
@treeview2.signal_connect('button_press_event') do |treeview, event|
|
||||
if event.kind_of? Gdk::EventButton
|
||||
if (event.button == 3)
|
||||
path, column, x, y = treeview.get_path_at_pos(event.x, event.y)
|
||||
|
||||
begin
|
||||
iter = @treeview2.model.get_iter(path)
|
||||
treeview.selection.select_path(path)
|
||||
@menu_job.popup(nil, nil, event.button, event.time)
|
||||
rescue
|
||||
nil
|
||||
#@menu_job.popup(nil, nil, event.button, event.time)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Menu Signals
|
||||
kill_job_item_shell.signal_connect('activate') do |item|
|
||||
if current = @selection.selected
|
||||
stop_job(current)
|
||||
end
|
||||
end
|
||||
|
||||
refresh_job_item_shell.signal_connect('activate') do |item|
|
||||
refresh_job()
|
||||
end
|
||||
|
||||
end # def initialize
|
||||
|
||||
#
|
||||
# Add One Shot
|
||||
#
|
||||
def add_oneshot(exploit, rhost)
|
||||
time = Time.now
|
||||
oneshot_childiter = @model.append(@oneshot_iter)
|
||||
#oneshot_childiter.set_value(PIX, nil)
|
||||
oneshot_childiter.set_value(TIME, Time.now.strftime("%H:%m:%S"))
|
||||
oneshot_childiter.set_value(NAME, exploit.shortname)
|
||||
oneshot_childiter.set_value(OBJECT, exploit)
|
||||
oneshot_childiter.set_value(RHOST, rhost)
|
||||
oneshot_childiter.set_value(REFNAME, exploit.refname)
|
||||
@treeview2.expand_all()
|
||||
end
|
||||
|
||||
#
|
||||
# Stop job and remove it from the job tree
|
||||
#
|
||||
def stop_job(iter)
|
||||
framework.jobs.each_key do |i|
|
||||
if (framework.jobs[i].name.split(": ")[1] == iter[REFNAME])
|
||||
|
||||
# Stopping job
|
||||
framework.jobs.stop_job(i)
|
||||
|
||||
# Informing the user
|
||||
$gtk2driver.append_log_view("[*] Stopping exploit: #{iter[REFNAME]}")
|
||||
|
||||
# Removing the job from the job tree
|
||||
@model.remove(iter)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Refresh job
|
||||
#
|
||||
def refresh_job
|
||||
puts "TODO: refresh the job tree =>"
|
||||
framework.jobs.keys.sort.each do |k|
|
||||
puts framework.jobs[k].name
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Remove Target if not a passive exploit
|
||||
#
|
||||
def remove_job(rhost, name)
|
||||
found = nil
|
||||
@model.each do |model,path,iter|
|
||||
if (iter[RHOST] == rhost and iter[REFNAME] == name and iter[OBJECT].passive? == false)
|
||||
found = iter
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
@model.remove(found) if found
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,291 +1,291 @@
|
|||
module Msf
|
||||
module Ui
|
||||
module Gtk2
|
||||
module Ui
|
||||
module Gtk2
|
||||
|
||||
##
|
||||
# This class describe the modules treeview
|
||||
##
|
||||
class MyModuleTree < MyGlade
|
||||
|
||||
@@completion = []
|
||||
|
||||
PIX, CATEGORY, MODULE, ADV, APP = *(0..5).to_a
|
||||
|
||||
include Msf::Ui::Gtk2::MyControls
|
||||
|
||||
def initialize(treeview, viewmodule)
|
||||
super('menu_module')
|
||||
|
||||
@treeview1 = treeview
|
||||
@treeview1.enable_search = true
|
||||
|
||||
@model = Gtk::TreeStore.new( Gdk::Pixbuf, # pixbuf
|
||||
String, # Module name
|
||||
Object, # Exploit?
|
||||
TrueClass, # ADV?
|
||||
String # Appartenance
|
||||
)
|
||||
# Register the model for later use
|
||||
$gtk2driver.module_model = @model
|
||||
|
||||
# Init buffer module with tags
|
||||
buff = Gtk::TextBuffer.new
|
||||
viewmodule.set_buffer(buff)
|
||||
viewmodule.set_editable(false)
|
||||
viewmodule.set_cursor_visible(false)
|
||||
@buffer = MyModuleView.new(buff)
|
||||
|
||||
# Renderer Module
|
||||
renderer_pix = Gtk::CellRendererPixbuf.new
|
||||
renderer_module = Gtk::CellRendererText.new
|
||||
|
||||
column_module = Gtk::TreeViewColumn.new
|
||||
column_module.pack_start(renderer_pix, false)
|
||||
column_module.set_cell_data_func(renderer_pix) do |column, cell, model, iter|
|
||||
cell.pixbuf = iter[PIX]
|
||||
end
|
||||
column_module.pack_start(renderer_module, true)
|
||||
column_module.set_cell_data_func(renderer_module) do |column, cell, model, iter|
|
||||
cell.text = iter[CATEGORY]
|
||||
end
|
||||
|
||||
#set model to treeview
|
||||
@treeview1.set_size_request(380, -1)
|
||||
@treeview1.set_model(@model)
|
||||
|
||||
@treeview1.rules_hint = true
|
||||
|
||||
@selection = @treeview1.selection
|
||||
@treeview1.selection.mode = Gtk::SELECTION_BROWSE
|
||||
|
||||
@treeview1.append_column(column_module)
|
||||
|
||||
# Signals
|
||||
@treeview1.signal_connect('cursor-changed') do |widget, event|
|
||||
widget.selection.selected_each do |model, path, iter|
|
||||
active(iter)
|
||||
end
|
||||
end
|
||||
|
||||
@treeview1.signal_connect('button_press_event') do |treeview, event|
|
||||
if event.kind_of? Gdk::EventButton
|
||||
|
||||
# Right click
|
||||
if (event.button == 3)
|
||||
path, column, x, y = treeview.get_path_at_pos(event.x, event.y)
|
||||
begin
|
||||
iter = @treeview1.model.get_iter(path)
|
||||
if (iter.get_value(ADV) == false)
|
||||
treeview.selection.select_path(path)
|
||||
active(iter)
|
||||
@menu_module.popup(nil, nil, event.button, event.time)
|
||||
end
|
||||
rescue
|
||||
nil
|
||||
end
|
||||
|
||||
# Double click
|
||||
elsif (event.event_type == Gdk::Event::BUTTON2_PRESS)
|
||||
path, column, x, y = treeview.get_path_at_pos(event.x, event.y)
|
||||
begin
|
||||
iter = @treeview1.model.get_iter(path)
|
||||
if (iter.get_value(ADV) == false)
|
||||
if (iter.get_value(APP) == "Standard")
|
||||
treeview.selection.select_path(path)
|
||||
active(iter)
|
||||
MsfAssistant::Exploit.new(iter.get_value(MODULE))
|
||||
elsif (iter.get_value(APP) == "Payloads")
|
||||
treeview.selection.select_path(path)
|
||||
active(iter)
|
||||
MsfDialog::Error.new($gtk2driver.main, "Not available")
|
||||
else
|
||||
treeview.selection.select_path(path)
|
||||
active(iter)
|
||||
MsfDialog::Error.new($gtk2driver.main, "Not available")
|
||||
end
|
||||
end
|
||||
rescue
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@one_shot.signal_connect('activate') do |item|
|
||||
if active_module = @selection.selected
|
||||
type = active_module.get_value(APP)
|
||||
if (type == "Standard")
|
||||
MsfAssistant::Exploit.new(active_module.get_value(MODULE))
|
||||
elsif (type == "Payloads")
|
||||
MsfAssistant::Payload.new(active_module.get_value(MODULE))
|
||||
else
|
||||
MsfDialog::Error.new($gtk2driver.main, "Not available")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Add modules in the Gtk::TreeView
|
||||
add_modules()
|
||||
|
||||
# Configure the module completion handles for easy reference
|
||||
$gtk2driver.module_completion = @@completion
|
||||
|
||||
end # def initialize
|
||||
|
||||
#
|
||||
# Add Exploits module in the treeview
|
||||
#
|
||||
def add_modules(filter=/.*/)
|
||||
|
||||
# Add Parent "Standard (nbr exploits)"
|
||||
iter = @model.append(nil)
|
||||
iter.set_value(PIX, driver.get_icon("bug.png"))
|
||||
iter.set_value(CATEGORY, "Exploits (#{framework.stats.num_exploits.to_s})")
|
||||
iter.set_value(MODULE, nil)
|
||||
iter.set_value(ADV, true)
|
||||
|
||||
# Add Exploits childs
|
||||
framework.exploits.each_module do |mod, obj|
|
||||
next if not mod.match(filter)
|
||||
t_module = obj.new.name
|
||||
child_iter = @model.append(iter)
|
||||
child_iter.set_value(CATEGORY, t_module)
|
||||
child_iter.set_value(MODULE, obj.new)
|
||||
child_iter.set_value(ADV, false)
|
||||
child_iter.set_value(APP, "Standard")
|
||||
@@completion.push(t_module)
|
||||
end
|
||||
|
||||
# Add Parent "Auxiliary (nbr auxiliary)"
|
||||
iter = @model.append(nil)
|
||||
iter.set_value(PIX, driver.get_icon("zoom.png"))
|
||||
iter.set_value(CATEGORY, "Auxiliary (#{framework.stats.num_auxiliary.to_s})")
|
||||
iter.set_value(MODULE, nil)
|
||||
iter.set_value(ADV, true)
|
||||
|
||||
# Add Auxiliary childs
|
||||
framework.auxiliary.each_module do |mod, obj|
|
||||
next if not mod.match(filter)
|
||||
t_module = obj.new.name
|
||||
child_iter = @model.append(iter)
|
||||
child_iter.set_value(CATEGORY, t_module)
|
||||
child_iter.set_value(MODULE, obj.new)
|
||||
child_iter.set_value(ADV, false)
|
||||
child_iter.set_value(APP, "Auxiliary")
|
||||
@@completion.push(t_module)
|
||||
end
|
||||
|
||||
# Add Parent "Payloads (nbr payloads)"
|
||||
iter = @model.append(nil)
|
||||
iter.set_value(PIX, driver.get_icon("bomb.png"))
|
||||
iter.set_value(CATEGORY, "Payloads (#{framework.stats.num_payloads.to_s})")
|
||||
iter.set_value(MODULE, nil)
|
||||
iter.set_value(ADV, true)
|
||||
|
||||
# Add Payloads childs
|
||||
framework.payloads.each_module do |mod, obj|
|
||||
next if not mod.match(filter)
|
||||
t_module = obj.new.name
|
||||
child_iter = @model.append(iter)
|
||||
child_iter.set_value(CATEGORY, t_module)
|
||||
child_iter.set_value(MODULE, obj.new)
|
||||
child_iter.set_value(ADV, false)
|
||||
child_iter.set_value(APP, "Payloads")
|
||||
@@completion.push(t_module)
|
||||
end
|
||||
|
||||
# Add Parent "Nops (nbr nops)"
|
||||
iter = @model.append(nil)
|
||||
iter.set_value(PIX, driver.get_icon("encoders.png"))
|
||||
iter.set_value(CATEGORY, "NOPs (#{framework.stats.num_nops.to_s})")
|
||||
iter.set_value(MODULE, nil)
|
||||
iter.set_value(ADV, true)
|
||||
|
||||
# Add nops childs
|
||||
framework.nops.each_module do |mod, obj|
|
||||
next if not mod.match(filter)
|
||||
t_module = obj.new.name
|
||||
child_iter = @model.append(iter)
|
||||
child_iter.set_value(CATEGORY, t_module)
|
||||
child_iter.set_value(MODULE, obj.new)
|
||||
child_iter.set_value(ADV, false)
|
||||
child_iter.set_value(APP, "NOPs")
|
||||
@@completion.push(t_module)
|
||||
end
|
||||
|
||||
# Add Parent "Encoders (nbr encoders)"
|
||||
iter = @model.append(nil)
|
||||
iter.set_value(PIX, driver.get_icon("encoders.png"))
|
||||
iter.set_value(CATEGORY, "Encoders (#{framework.stats.num_encoders.to_s})")
|
||||
iter.set_value(MODULE, nil)
|
||||
iter.set_value(ADV, true)
|
||||
|
||||
# Add Encoders childs
|
||||
framework.encoders.each_module do |mod, obj|
|
||||
next if not mod.match(filter)
|
||||
t_module = obj.new.name
|
||||
child_iter = @model.append(iter)
|
||||
child_iter.set_value(CATEGORY, t_module)
|
||||
child_iter.set_value(MODULE, obj.new)
|
||||
child_iter.set_value(ADV, false)
|
||||
iter.set_value(APP, "Encoders")
|
||||
@@completion.push(t_module)
|
||||
end
|
||||
end # def add_modules
|
||||
|
||||
#
|
||||
# Display the module information
|
||||
#
|
||||
def active(iter)
|
||||
if not iter[MODULE].nil?
|
||||
@buffer.insert_module(iter.get_value(MODULE))
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Refresh the module treeview with all msf modules
|
||||
#
|
||||
def refresh
|
||||
@model.clear()
|
||||
add_modules()
|
||||
end
|
||||
|
||||
#
|
||||
# remove all iters in array_iter
|
||||
#
|
||||
def remove(iter_array)
|
||||
|
||||
# first loop to remove unmatched iter
|
||||
iter_array.each do |iter|
|
||||
if (iter[ADV] == false)
|
||||
@model.remove(iter)
|
||||
end
|
||||
end
|
||||
|
||||
# second loop to update parent iter with child iter
|
||||
no_child = []
|
||||
@model.each do |model, path, iter|
|
||||
if (iter[ADV] == true)
|
||||
no_child.push(iter) if not iter.has_child?
|
||||
iter[CATEGORY] = iter[CATEGORY].sub(/[0-9]+/, iter.n_children.to_s)
|
||||
end
|
||||
end
|
||||
|
||||
# remove iter
|
||||
no_child.each do |iter|
|
||||
@model.remove(iter)
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# expand the treeview
|
||||
#
|
||||
def expand
|
||||
@treeview1.expand_all
|
||||
end
|
||||
##
|
||||
# This class describe the modules treeview
|
||||
##
|
||||
class MyModuleTree < MyGlade
|
||||
|
||||
end
|
||||
@@completion = []
|
||||
|
||||
PIX, CATEGORY, MODULE, ADV, APP = *(0..5).to_a
|
||||
|
||||
include Msf::Ui::Gtk2::MyControls
|
||||
|
||||
def initialize(treeview, viewmodule)
|
||||
super('menu_module')
|
||||
|
||||
@treeview1 = treeview
|
||||
@treeview1.enable_search = true
|
||||
|
||||
@model = Gtk::TreeStore.new( Gdk::Pixbuf, # pixbuf
|
||||
String, # Module name
|
||||
Object, # Exploit?
|
||||
TrueClass, # ADV?
|
||||
String # Appartenance
|
||||
)
|
||||
# Register the model for later use
|
||||
$gtk2driver.module_model = @model
|
||||
|
||||
# Init buffer module with tags
|
||||
buff = Gtk::TextBuffer.new
|
||||
viewmodule.set_buffer(buff)
|
||||
viewmodule.set_editable(false)
|
||||
viewmodule.set_cursor_visible(false)
|
||||
@buffer = MyModuleView.new(buff)
|
||||
|
||||
# Renderer Module
|
||||
renderer_pix = Gtk::CellRendererPixbuf.new
|
||||
renderer_module = Gtk::CellRendererText.new
|
||||
|
||||
column_module = Gtk::TreeViewColumn.new
|
||||
column_module.pack_start(renderer_pix, false)
|
||||
column_module.set_cell_data_func(renderer_pix) do |column, cell, model, iter|
|
||||
cell.pixbuf = iter[PIX]
|
||||
end
|
||||
column_module.pack_start(renderer_module, true)
|
||||
column_module.set_cell_data_func(renderer_module) do |column, cell, model, iter|
|
||||
cell.text = iter[CATEGORY]
|
||||
end
|
||||
|
||||
#set model to treeview
|
||||
@treeview1.set_size_request(380, -1)
|
||||
@treeview1.set_model(@model)
|
||||
|
||||
@treeview1.rules_hint = true
|
||||
|
||||
@selection = @treeview1.selection
|
||||
@treeview1.selection.mode = Gtk::SELECTION_BROWSE
|
||||
|
||||
@treeview1.append_column(column_module)
|
||||
|
||||
# Signals
|
||||
@treeview1.signal_connect('cursor-changed') do |widget, event|
|
||||
widget.selection.selected_each do |model, path, iter|
|
||||
active(iter)
|
||||
end
|
||||
end
|
||||
|
||||
@treeview1.signal_connect('button_press_event') do |treeview, event|
|
||||
if event.kind_of? Gdk::EventButton
|
||||
|
||||
# Right click
|
||||
if (event.button == 3)
|
||||
path, column, x, y = treeview.get_path_at_pos(event.x, event.y)
|
||||
begin
|
||||
iter = @treeview1.model.get_iter(path)
|
||||
if (iter.get_value(ADV) == false)
|
||||
treeview.selection.select_path(path)
|
||||
active(iter)
|
||||
@menu_module.popup(nil, nil, event.button, event.time)
|
||||
end
|
||||
rescue
|
||||
nil
|
||||
end
|
||||
|
||||
# Double click
|
||||
elsif (event.event_type == Gdk::Event::BUTTON2_PRESS)
|
||||
path, column, x, y = treeview.get_path_at_pos(event.x, event.y)
|
||||
begin
|
||||
iter = @treeview1.model.get_iter(path)
|
||||
if (iter.get_value(ADV) == false)
|
||||
if (iter.get_value(APP) == "Standard")
|
||||
treeview.selection.select_path(path)
|
||||
active(iter)
|
||||
MsfAssistant::Exploit.new(iter.get_value(MODULE))
|
||||
elsif (iter.get_value(APP) == "Payloads")
|
||||
treeview.selection.select_path(path)
|
||||
active(iter)
|
||||
MsfDialog::Error.new($gtk2driver.main, "Not available")
|
||||
else
|
||||
treeview.selection.select_path(path)
|
||||
active(iter)
|
||||
MsfDialog::Error.new($gtk2driver.main, "Not available")
|
||||
end
|
||||
end
|
||||
rescue
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@one_shot.signal_connect('activate') do |item|
|
||||
if active_module = @selection.selected
|
||||
type = active_module.get_value(APP)
|
||||
if (type == "Standard")
|
||||
MsfAssistant::Exploit.new(active_module.get_value(MODULE))
|
||||
elsif (type == "Payloads")
|
||||
MsfAssistant::Payload.new(active_module.get_value(MODULE))
|
||||
else
|
||||
MsfDialog::Error.new($gtk2driver.main, "Not available")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Add modules in the Gtk::TreeView
|
||||
add_modules()
|
||||
|
||||
# Configure the module completion handles for easy reference
|
||||
$gtk2driver.module_completion = @@completion
|
||||
|
||||
end # def initialize
|
||||
|
||||
#
|
||||
# Add Exploits module in the treeview
|
||||
#
|
||||
def add_modules(filter=/.*/)
|
||||
|
||||
# Add Parent "Standard (nbr exploits)"
|
||||
iter = @model.append(nil)
|
||||
iter.set_value(PIX, driver.get_icon("bug.png"))
|
||||
iter.set_value(CATEGORY, "Exploits (#{framework.stats.num_exploits.to_s})")
|
||||
iter.set_value(MODULE, nil)
|
||||
iter.set_value(ADV, true)
|
||||
|
||||
# Add Exploits childs
|
||||
framework.exploits.each_module do |mod, obj|
|
||||
next if not mod.match(filter)
|
||||
t_module = obj.new.name
|
||||
child_iter = @model.append(iter)
|
||||
child_iter.set_value(CATEGORY, t_module)
|
||||
child_iter.set_value(MODULE, obj.new)
|
||||
child_iter.set_value(ADV, false)
|
||||
child_iter.set_value(APP, "Standard")
|
||||
@@completion.push(t_module)
|
||||
end
|
||||
|
||||
# Add Parent "Auxiliary (nbr auxiliary)"
|
||||
iter = @model.append(nil)
|
||||
iter.set_value(PIX, driver.get_icon("zoom.png"))
|
||||
iter.set_value(CATEGORY, "Auxiliary (#{framework.stats.num_auxiliary.to_s})")
|
||||
iter.set_value(MODULE, nil)
|
||||
iter.set_value(ADV, true)
|
||||
|
||||
# Add Auxiliary childs
|
||||
framework.auxiliary.each_module do |mod, obj|
|
||||
next if not mod.match(filter)
|
||||
t_module = obj.new.name
|
||||
child_iter = @model.append(iter)
|
||||
child_iter.set_value(CATEGORY, t_module)
|
||||
child_iter.set_value(MODULE, obj.new)
|
||||
child_iter.set_value(ADV, false)
|
||||
child_iter.set_value(APP, "Auxiliary")
|
||||
@@completion.push(t_module)
|
||||
end
|
||||
|
||||
# Add Parent "Payloads (nbr payloads)"
|
||||
iter = @model.append(nil)
|
||||
iter.set_value(PIX, driver.get_icon("bomb.png"))
|
||||
iter.set_value(CATEGORY, "Payloads (#{framework.stats.num_payloads.to_s})")
|
||||
iter.set_value(MODULE, nil)
|
||||
iter.set_value(ADV, true)
|
||||
|
||||
# Add Payloads childs
|
||||
framework.payloads.each_module do |mod, obj|
|
||||
next if not mod.match(filter)
|
||||
t_module = obj.new.name
|
||||
child_iter = @model.append(iter)
|
||||
child_iter.set_value(CATEGORY, t_module)
|
||||
child_iter.set_value(MODULE, obj.new)
|
||||
child_iter.set_value(ADV, false)
|
||||
child_iter.set_value(APP, "Payloads")
|
||||
@@completion.push(t_module)
|
||||
end
|
||||
|
||||
# Add Parent "Nops (nbr nops)"
|
||||
iter = @model.append(nil)
|
||||
iter.set_value(PIX, driver.get_icon("encoders.png"))
|
||||
iter.set_value(CATEGORY, "NOPs (#{framework.stats.num_nops.to_s})")
|
||||
iter.set_value(MODULE, nil)
|
||||
iter.set_value(ADV, true)
|
||||
|
||||
# Add nops childs
|
||||
framework.nops.each_module do |mod, obj|
|
||||
next if not mod.match(filter)
|
||||
t_module = obj.new.name
|
||||
child_iter = @model.append(iter)
|
||||
child_iter.set_value(CATEGORY, t_module)
|
||||
child_iter.set_value(MODULE, obj.new)
|
||||
child_iter.set_value(ADV, false)
|
||||
child_iter.set_value(APP, "NOPs")
|
||||
@@completion.push(t_module)
|
||||
end
|
||||
|
||||
# Add Parent "Encoders (nbr encoders)"
|
||||
iter = @model.append(nil)
|
||||
iter.set_value(PIX, driver.get_icon("encoders.png"))
|
||||
iter.set_value(CATEGORY, "Encoders (#{framework.stats.num_encoders.to_s})")
|
||||
iter.set_value(MODULE, nil)
|
||||
iter.set_value(ADV, true)
|
||||
|
||||
# Add Encoders childs
|
||||
framework.encoders.each_module do |mod, obj|
|
||||
next if not mod.match(filter)
|
||||
t_module = obj.new.name
|
||||
child_iter = @model.append(iter)
|
||||
child_iter.set_value(CATEGORY, t_module)
|
||||
child_iter.set_value(MODULE, obj.new)
|
||||
child_iter.set_value(ADV, false)
|
||||
iter.set_value(APP, "Encoders")
|
||||
@@completion.push(t_module)
|
||||
end
|
||||
end # def add_modules
|
||||
|
||||
#
|
||||
# Display the module information
|
||||
#
|
||||
def active(iter)
|
||||
if not iter[MODULE].nil?
|
||||
@buffer.insert_module(iter.get_value(MODULE))
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Refresh the module treeview with all msf modules
|
||||
#
|
||||
def refresh
|
||||
@model.clear()
|
||||
add_modules()
|
||||
end
|
||||
|
||||
#
|
||||
# remove all iters in array_iter
|
||||
#
|
||||
def remove(iter_array)
|
||||
|
||||
# first loop to remove unmatched iter
|
||||
iter_array.each do |iter|
|
||||
if (iter[ADV] == false)
|
||||
@model.remove(iter)
|
||||
end
|
||||
end
|
||||
|
||||
# second loop to update parent iter with child iter
|
||||
no_child = []
|
||||
@model.each do |model, path, iter|
|
||||
if (iter[ADV] == true)
|
||||
no_child.push(iter) if not iter.has_child?
|
||||
iter[CATEGORY] = iter[CATEGORY].sub(/[0-9]+/, iter.n_children.to_s)
|
||||
end
|
||||
end
|
||||
|
||||
# remove iter
|
||||
no_child.each do |iter|
|
||||
@model.remove(iter)
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# expand the treeview
|
||||
#
|
||||
def expand
|
||||
@treeview1.expand_all
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,196 +1,196 @@
|
|||
module Msf
|
||||
module Ui
|
||||
module Gtk2
|
||||
module Ui
|
||||
module Gtk2
|
||||
|
||||
class MySessionTree
|
||||
ID_SESSION, PEER, PAYLOAD, O_SESSION, O_BUFFER = *(0..5).to_a
|
||||
|
||||
include Msf::Ui::Gtk2::MyControls
|
||||
|
||||
def initialize(treeview)
|
||||
@treeview = treeview
|
||||
@model = Gtk::ListStore.new(String, # Session ID
|
||||
String, # IP Address
|
||||
String, # Payload Type
|
||||
Object, # Session Object
|
||||
Object # Gtk::TextBuffer
|
||||
)
|
||||
|
||||
# Renderer
|
||||
renderer_id = Gtk::CellRendererText.new
|
||||
renderer_peer = Gtk::CellRendererText.new
|
||||
renderer_payload = Gtk::CellRendererText.new
|
||||
class MySessionTree
|
||||
ID_SESSION, PEER, PAYLOAD, O_SESSION, O_BUFFER = *(0..5).to_a
|
||||
|
||||
# ID Session Gtk::TreeViewColumn
|
||||
column_id = Gtk::TreeViewColumn.new
|
||||
column_id.sizing = Gtk::TreeViewColumn::FIXED
|
||||
column_id.fixed_width = 20
|
||||
column_id.set_title("ID")
|
||||
column_id.pack_start(renderer_id, true)
|
||||
column_id.set_cell_data_func(renderer_id) do |column, cell, model, iter|
|
||||
cell.text = iter[ID_SESSION]
|
||||
end
|
||||
column_id.sort_column_id = ID_SESSION
|
||||
|
||||
# Target Gtk::TreeViewColumn
|
||||
column_peer = Gtk::TreeViewColumn.new
|
||||
column_peer.set_title("Target")
|
||||
column_peer.pack_start(renderer_peer, true)
|
||||
column_peer.set_cell_data_func(renderer_peer) do |column, cell, model, iter|
|
||||
cell.text = iter[PEER]
|
||||
end
|
||||
#column_peer.sort_column_id = PEER
|
||||
|
||||
# Payload type Gtk::TreeViewColumn
|
||||
column_payload = Gtk::TreeViewColumn.new
|
||||
column_payload.set_title("Payload")
|
||||
column_payload.pack_start(renderer_payload, true)
|
||||
column_payload.set_cell_data_func(renderer_payload) do |column, cell, model, iter|
|
||||
cell.text = iter[PAYLOAD]
|
||||
end
|
||||
#column_payload.sort_column_id = PAYLOAD
|
||||
|
||||
#set model to treeview
|
||||
@treeview.set_model(@model)
|
||||
|
||||
@selection = @treeview.selection
|
||||
@treeview.selection.mode = Gtk::SELECTION_BROWSE
|
||||
@treeview.rules_hint = true
|
||||
|
||||
# Add Gtk::TreeViewColumn
|
||||
@treeview.append_column(column_id)
|
||||
@treeview.append_column(column_peer)
|
||||
@treeview.append_column(column_payload)
|
||||
|
||||
# Session Gtk::Menu
|
||||
@menu_session = Gtk::Menu.new
|
||||
|
||||
session_item_shell = Gtk::ImageMenuItem.new("Interact Session")
|
||||
session_image_shell = Gtk::Image.new
|
||||
session_image_shell.set(Gtk::Stock::EXECUTE, Gtk::IconSize::MENU)
|
||||
session_item_shell.set_image(session_image_shell)
|
||||
@menu_session.append(session_item_shell)
|
||||
|
||||
separator1 = Gtk::SeparatorMenuItem.new
|
||||
@menu_session.append(separator1)
|
||||
|
||||
close_session_item_shell = Gtk::ImageMenuItem.new("Close Session")
|
||||
close_session_image_shell = Gtk::Image.new
|
||||
close_session_image_shell.set(Gtk::Stock::CLOSE, Gtk::IconSize::MENU)
|
||||
close_session_item_shell.set_image(close_session_image_shell)
|
||||
@menu_session.append(close_session_item_shell)
|
||||
include Msf::Ui::Gtk2::MyControls
|
||||
|
||||
separator2 = Gtk::SeparatorMenuItem.new
|
||||
@menu_session.append(separator2)
|
||||
|
||||
meterpreter_proc_item_shell = Gtk::ImageMenuItem.new("Process")
|
||||
meterpreter_proc_image_shell = Gtk::Image.new
|
||||
meterpreter_proc_image_shell.set(Gtk::Stock::CLOSE, Gtk::IconSize::MENU)
|
||||
meterpreter_proc_item_shell.set_image(meterpreter_proc_image_shell)
|
||||
@menu_session.append(meterpreter_proc_item_shell)
|
||||
|
||||
@menu_session.show_all
|
||||
|
||||
# TreeView signals
|
||||
@treeview.signal_connect('button_press_event') do |treeview, event|
|
||||
if event.kind_of? Gdk::EventButton
|
||||
if (event.button == 3)
|
||||
path, column, x, y = treeview.get_path_at_pos(event.x, event.y)
|
||||
|
||||
begin
|
||||
iter = @treeview.model.get_iter(path)
|
||||
treeview.selection.select_path(path)
|
||||
@menu_session.popup(nil, nil, event.button, event.time)
|
||||
rescue
|
||||
nil
|
||||
end
|
||||
elsif (event.event_type == Gdk::Event::BUTTON2_PRESS)
|
||||
path, column, x, y = treeview.get_path_at_pos(event.x, event.y)
|
||||
begin
|
||||
iter = @treeview.model.get_iter(path)
|
||||
treeview.selection.select_path(path)
|
||||
open_session(iter)
|
||||
rescue
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Items session signals
|
||||
session_item_shell.signal_connect('activate') do |item|
|
||||
if current = @selection.selected
|
||||
puts "yeah"
|
||||
open_session(current)
|
||||
end
|
||||
end
|
||||
|
||||
close_session_item_shell.signal_connect('activate') do |item|
|
||||
if session_iter = @selection.selected
|
||||
remove_session_iter(session_iter)
|
||||
end
|
||||
end
|
||||
|
||||
meterpreter_proc_item_shell.signal_connect('activate') do |item|
|
||||
if current = @selection.selected
|
||||
print current[O_SESSION].tunnel_peer
|
||||
end
|
||||
end
|
||||
|
||||
end # def initialize
|
||||
|
||||
#
|
||||
# Add an iter to the session treeview
|
||||
#
|
||||
def add_session(session)
|
||||
iter = @model.append
|
||||
iter[ID_SESSION] = session.sid.to_s
|
||||
iter[PEER] = session.tunnel_peer
|
||||
iter[PAYLOAD] = session.via_payload ? session.via_payload : nil
|
||||
iter[O_SESSION] = session
|
||||
iter[O_BUFFER] = Gtk::TextBuffer.new
|
||||
end
|
||||
|
||||
#
|
||||
# Open the session with the selected iter
|
||||
#
|
||||
def open_session(iter)
|
||||
session = iter[O_SESSION]
|
||||
if (session.type == "meterpreter")
|
||||
#Msf::Ui::Gtk2::Console::Meterpreter.new(iter)
|
||||
Msf::Ui::Gtk2::Console::Basic.new(iter)
|
||||
else
|
||||
Msf::Ui::Gtk2::Console::Basic.new(iter)
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Kill the session associated with this item
|
||||
# TODO: Bug on the sesson kill
|
||||
#
|
||||
def remove_session_iter(iter)
|
||||
# Just kill the session, let the event handler remove it
|
||||
iter[O_SESSION].kill
|
||||
end
|
||||
|
||||
#
|
||||
# Remove the item from the model
|
||||
# This is called by the framework on_session_close()
|
||||
#
|
||||
def remove_session(session)
|
||||
found = nil
|
||||
@model.each do |model,path,iter|
|
||||
if (iter[ID_SESSION] == session.sid.to_s)
|
||||
found = iter
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
@model.remove(found) if found
|
||||
end
|
||||
def initialize(treeview)
|
||||
@treeview = treeview
|
||||
@model = Gtk::ListStore.new(String, # Session ID
|
||||
String, # IP Address
|
||||
String, # Payload Type
|
||||
Object, # Session Object
|
||||
Object # Gtk::TextBuffer
|
||||
)
|
||||
|
||||
end # class MySessionTree
|
||||
# Renderer
|
||||
renderer_id = Gtk::CellRendererText.new
|
||||
renderer_peer = Gtk::CellRendererText.new
|
||||
renderer_payload = Gtk::CellRendererText.new
|
||||
|
||||
end
|
||||
end
|
||||
# ID Session Gtk::TreeViewColumn
|
||||
column_id = Gtk::TreeViewColumn.new
|
||||
column_id.sizing = Gtk::TreeViewColumn::FIXED
|
||||
column_id.fixed_width = 20
|
||||
column_id.set_title("ID")
|
||||
column_id.pack_start(renderer_id, true)
|
||||
column_id.set_cell_data_func(renderer_id) do |column, cell, model, iter|
|
||||
cell.text = iter[ID_SESSION]
|
||||
end
|
||||
column_id.sort_column_id = ID_SESSION
|
||||
|
||||
# Target Gtk::TreeViewColumn
|
||||
column_peer = Gtk::TreeViewColumn.new
|
||||
column_peer.set_title("Target")
|
||||
column_peer.pack_start(renderer_peer, true)
|
||||
column_peer.set_cell_data_func(renderer_peer) do |column, cell, model, iter|
|
||||
cell.text = iter[PEER]
|
||||
end
|
||||
#column_peer.sort_column_id = PEER
|
||||
|
||||
# Payload type Gtk::TreeViewColumn
|
||||
column_payload = Gtk::TreeViewColumn.new
|
||||
column_payload.set_title("Payload")
|
||||
column_payload.pack_start(renderer_payload, true)
|
||||
column_payload.set_cell_data_func(renderer_payload) do |column, cell, model, iter|
|
||||
cell.text = iter[PAYLOAD]
|
||||
end
|
||||
#column_payload.sort_column_id = PAYLOAD
|
||||
|
||||
#set model to treeview
|
||||
@treeview.set_model(@model)
|
||||
|
||||
@selection = @treeview.selection
|
||||
@treeview.selection.mode = Gtk::SELECTION_BROWSE
|
||||
@treeview.rules_hint = true
|
||||
|
||||
# Add Gtk::TreeViewColumn
|
||||
@treeview.append_column(column_id)
|
||||
@treeview.append_column(column_peer)
|
||||
@treeview.append_column(column_payload)
|
||||
|
||||
# Session Gtk::Menu
|
||||
@menu_session = Gtk::Menu.new
|
||||
|
||||
session_item_shell = Gtk::ImageMenuItem.new("Interact Session")
|
||||
session_image_shell = Gtk::Image.new
|
||||
session_image_shell.set(Gtk::Stock::EXECUTE, Gtk::IconSize::MENU)
|
||||
session_item_shell.set_image(session_image_shell)
|
||||
@menu_session.append(session_item_shell)
|
||||
|
||||
separator1 = Gtk::SeparatorMenuItem.new
|
||||
@menu_session.append(separator1)
|
||||
|
||||
close_session_item_shell = Gtk::ImageMenuItem.new("Close Session")
|
||||
close_session_image_shell = Gtk::Image.new
|
||||
close_session_image_shell.set(Gtk::Stock::CLOSE, Gtk::IconSize::MENU)
|
||||
close_session_item_shell.set_image(close_session_image_shell)
|
||||
@menu_session.append(close_session_item_shell)
|
||||
|
||||
separator2 = Gtk::SeparatorMenuItem.new
|
||||
@menu_session.append(separator2)
|
||||
|
||||
meterpreter_proc_item_shell = Gtk::ImageMenuItem.new("Process")
|
||||
meterpreter_proc_image_shell = Gtk::Image.new
|
||||
meterpreter_proc_image_shell.set(Gtk::Stock::CLOSE, Gtk::IconSize::MENU)
|
||||
meterpreter_proc_item_shell.set_image(meterpreter_proc_image_shell)
|
||||
@menu_session.append(meterpreter_proc_item_shell)
|
||||
|
||||
@menu_session.show_all
|
||||
|
||||
# TreeView signals
|
||||
@treeview.signal_connect('button_press_event') do |treeview, event|
|
||||
if event.kind_of? Gdk::EventButton
|
||||
if (event.button == 3)
|
||||
path, column, x, y = treeview.get_path_at_pos(event.x, event.y)
|
||||
|
||||
begin
|
||||
iter = @treeview.model.get_iter(path)
|
||||
treeview.selection.select_path(path)
|
||||
@menu_session.popup(nil, nil, event.button, event.time)
|
||||
rescue
|
||||
nil
|
||||
end
|
||||
elsif (event.event_type == Gdk::Event::BUTTON2_PRESS)
|
||||
path, column, x, y = treeview.get_path_at_pos(event.x, event.y)
|
||||
begin
|
||||
iter = @treeview.model.get_iter(path)
|
||||
treeview.selection.select_path(path)
|
||||
open_session(iter)
|
||||
rescue
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Items session signals
|
||||
session_item_shell.signal_connect('activate') do |item|
|
||||
if current = @selection.selected
|
||||
puts "yeah"
|
||||
open_session(current)
|
||||
end
|
||||
end
|
||||
|
||||
close_session_item_shell.signal_connect('activate') do |item|
|
||||
if session_iter = @selection.selected
|
||||
remove_session_iter(session_iter)
|
||||
end
|
||||
end
|
||||
|
||||
meterpreter_proc_item_shell.signal_connect('activate') do |item|
|
||||
if current = @selection.selected
|
||||
print current[O_SESSION].tunnel_peer
|
||||
end
|
||||
end
|
||||
|
||||
end # def initialize
|
||||
|
||||
#
|
||||
# Add an iter to the session treeview
|
||||
#
|
||||
def add_session(session)
|
||||
iter = @model.append
|
||||
iter[ID_SESSION] = session.sid.to_s
|
||||
iter[PEER] = session.tunnel_peer
|
||||
iter[PAYLOAD] = session.via_payload ? session.via_payload : nil
|
||||
iter[O_SESSION] = session
|
||||
iter[O_BUFFER] = Gtk::TextBuffer.new
|
||||
end
|
||||
|
||||
#
|
||||
# Open the session with the selected iter
|
||||
#
|
||||
def open_session(iter)
|
||||
session = iter[O_SESSION]
|
||||
if (session.type == "meterpreter")
|
||||
#Msf::Ui::Gtk2::Console::Meterpreter.new(iter)
|
||||
Msf::Ui::Gtk2::Console::Basic.new(iter)
|
||||
else
|
||||
Msf::Ui::Gtk2::Console::Basic.new(iter)
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Kill the session associated with this item
|
||||
# TODO: Bug on the sesson kill
|
||||
#
|
||||
def remove_session_iter(iter)
|
||||
# Just kill the session, let the event handler remove it
|
||||
iter[O_SESSION].kill
|
||||
end
|
||||
|
||||
#
|
||||
# Remove the item from the model
|
||||
# This is called by the framework on_session_close()
|
||||
#
|
||||
def remove_session(session)
|
||||
found = nil
|
||||
@model.each do |model,path,iter|
|
||||
if (iter[ID_SESSION] == session.sid.to_s)
|
||||
found = iter
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
@model.remove(found) if found
|
||||
end
|
||||
|
||||
end # class MySessionTree
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,63 +1,63 @@
|
|||
module Msf
|
||||
module Ui
|
||||
module Gtk2
|
||||
module Ui
|
||||
module Gtk2
|
||||
|
||||
###
|
||||
#
|
||||
# Handles events of various types that are sent from the framework.
|
||||
#
|
||||
###
|
||||
module FrameworkEventManager
|
||||
###
|
||||
#
|
||||
# Handles events of various types that are sent from the framework.
|
||||
#
|
||||
###
|
||||
module FrameworkEventManager
|
||||
|
||||
include Msf::SessionEvent
|
||||
include Msf::SessionEvent
|
||||
|
||||
#
|
||||
# Subscribes to the framework as a subscriber of various events.
|
||||
#
|
||||
def register_event_handlers
|
||||
framework.events.add_session_subscriber(self)
|
||||
end
|
||||
#
|
||||
# Subscribes to the framework as a subscriber of various events.
|
||||
#
|
||||
def register_event_handlers
|
||||
framework.events.add_session_subscriber(self)
|
||||
end
|
||||
|
||||
#
|
||||
# Unsubscribes from the framework.
|
||||
#
|
||||
def deregister_event_handlers
|
||||
framework.events.remove_session_subscriber(self)
|
||||
end
|
||||
#
|
||||
# Unsubscribes from the framework.
|
||||
#
|
||||
def deregister_event_handlers
|
||||
framework.events.remove_session_subscriber(self)
|
||||
end
|
||||
|
||||
#
|
||||
# Called when a session is registered with the framework.
|
||||
#
|
||||
def on_session_open(session)
|
||||
|
||||
$gtk2driver.append_log_view("[*] Session #{session.sid} created for #{session.tunnel_peer}\n")
|
||||
$gtk2driver.session_tree.add_session(session)
|
||||
|
||||
# remove job if not a passive exploit
|
||||
rhost = session.tunnel_peer.split(':')[0]
|
||||
$gtk2driver.job_tree.remove_job(rhost, session.via_exploit)
|
||||
|
||||
if (Msf::Logging.session_logging_enabled? == true)
|
||||
Msf::Logging.start_session_log(session)
|
||||
end
|
||||
end
|
||||
#
|
||||
# Called when a session is registered with the framework.
|
||||
#
|
||||
def on_session_open(session)
|
||||
|
||||
#
|
||||
# Called when a session is closed and removed from the framework.
|
||||
#
|
||||
def on_session_close(session)
|
||||
$gtk2driver.append_log_view("[*] Session #{session.sid} created for #{session.tunnel_peer}\n")
|
||||
$gtk2driver.session_tree.add_session(session)
|
||||
|
||||
$gtk2driver.append_log_view("[*] Session #{session.sid} closed for #{session.tunnel_peer}\n")
|
||||
|
||||
$gtk2driver.session_tree.remove_session(session)
|
||||
# remove job if not a passive exploit
|
||||
rhost = session.tunnel_peer.split(':')[0]
|
||||
$gtk2driver.job_tree.remove_job(rhost, session.via_exploit)
|
||||
|
||||
# If logging had been enabled for this session, stop it now.
|
||||
Msf::Logging::stop_session_log(session)
|
||||
|
||||
end
|
||||
if (Msf::Logging.session_logging_enabled? == true)
|
||||
Msf::Logging.start_session_log(session)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
#
|
||||
# Called when a session is closed and removed from the framework.
|
||||
#
|
||||
def on_session_close(session)
|
||||
|
||||
$gtk2driver.append_log_view("[*] Session #{session.sid} closed for #{session.tunnel_peer}\n")
|
||||
|
||||
$gtk2driver.session_tree.remove_session(session)
|
||||
|
||||
# If logging had been enabled for this session, stop it now.
|
||||
Msf::Logging::stop_session_log(session)
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,417 +1,417 @@
|
|||
module Msf
|
||||
module Ui
|
||||
module Gtk2
|
||||
module Ui
|
||||
module Gtk2
|
||||
|
||||
require 'rex/exploitation/opcodedb'
|
||||
require 'rex/exploitation/opcodedb'
|
||||
|
||||
require 'rexml/document'
|
||||
require 'rexml/document'
|
||||
|
||||
##
|
||||
# Gtk2 Interface for msfopcode
|
||||
##
|
||||
##
|
||||
# Gtk2 Interface for msfopcode
|
||||
##
|
||||
|
||||
#
|
||||
# Skeleton for opcodes stuff
|
||||
#
|
||||
class SkeletonOpcode < Gtk::Dialog
|
||||
|
||||
include Msf::Ui::Gtk2::MyControls
|
||||
|
||||
attr_accessor :comment, :stuff
|
||||
|
||||
def initialize(title, comments, buttons=[[ Gtk::Stock::CLOSE, Gtk::Dialog::RESPONSE_NONE ]])
|
||||
super("", $gtk2driver.main, Gtk::Dialog::DESTROY_WITH_PARENT, *buttons)
|
||||
|
||||
# Style
|
||||
console_style = File.join(driver.resource_directory, 'style', 'opcode.rc')
|
||||
Gtk::RC.parse(console_style)
|
||||
|
||||
self.border_width = 6
|
||||
self.resizable = true
|
||||
self.has_separator = true
|
||||
self.vbox.spacing = 12
|
||||
self.vbox.set_homogeneous(false)
|
||||
self.title = title
|
||||
self.set_default_size(500, 400)
|
||||
|
||||
@comment = Gtk::Label.new
|
||||
@comment.set_alignment(0, 0)
|
||||
@comment.set_markup("<b>#{comments}</b>")
|
||||
self.vbox.pack_start(@comment, false, false, 0)
|
||||
|
||||
@stuff = Gtk::VBox.new(false, 10)
|
||||
self.vbox.pack_start(@stuff, true, true, 0)
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Gtk2 Interface for Metasploit Opcodes database
|
||||
#
|
||||
class MsfOpcode
|
||||
|
||||
# Create the opcode client instance
|
||||
$client = Rex::Exploitation::OpcodeDb::Client.new
|
||||
|
||||
#
|
||||
# Opcodes statistics
|
||||
#
|
||||
class Stats < Msf::Ui::Gtk2::SkeletonOpcode
|
||||
|
||||
def initialize
|
||||
comment = "Current database statistics :"
|
||||
|
||||
# Call the parent
|
||||
super("Statistics", comment)
|
||||
|
||||
self.set_default_size(500, 230)
|
||||
|
||||
stats = $client.statistics
|
||||
|
||||
textview = Gtk::TextView.new
|
||||
textbuffer = Gtk::TextBuffer.new
|
||||
stuff.pack_start(textview, true, true, 0)
|
||||
|
||||
textbuffer.set_text(
|
||||
"\n" +
|
||||
"Last Updated : #{stats.last_update.to_s}\n" +
|
||||
"Number of Opcodes : #{stats.opcodes}\n" +
|
||||
"Number of Opcode Types : #{stats.opcode_types}\n" +
|
||||
"Number of Platforms : #{stats.platforms}\n" +
|
||||
"Number of Architectures : #{stats.architectures}\n" +
|
||||
"Number of Modules : #{stats.modules}\n" +
|
||||
"Number of Module Segments: #{stats.module_segments}\n" +
|
||||
"Number of Module Imports : #{stats.module_imports}\n" +
|
||||
"Number of Module Exports : #{stats.module_exports}\n\n")
|
||||
|
||||
textview.set_buffer(textbuffer)
|
||||
textview.set_editable(false)
|
||||
textview.set_cursor_visible(false)
|
||||
|
||||
show_all and run
|
||||
destroy
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Opcodes locales
|
||||
#
|
||||
class Locales < Msf::Ui::Gtk2::SkeletonOpcode
|
||||
def initialize
|
||||
comment = "Locales currently supported by the database:"
|
||||
|
||||
# call the parent
|
||||
super("Locales", comment)
|
||||
|
||||
self.set_default_size(500, 230)
|
||||
|
||||
textview = Gtk::TextView.new
|
||||
textbuffer = Gtk::TextBuffer.new
|
||||
stuff.pack_start(textview, true, true, 0)
|
||||
|
||||
locales = "\n"
|
||||
$client.locales.each do |locale|
|
||||
locales << " -" + locale.name + "\n"
|
||||
end
|
||||
|
||||
textbuffer.set_text( locales )
|
||||
|
||||
textview.set_buffer(textbuffer)
|
||||
textview.set_editable(false)
|
||||
textview.set_cursor_visible(false)
|
||||
|
||||
show_all and run
|
||||
destroy
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Opcodes meta types
|
||||
#
|
||||
class Metatypes < Msf::Ui::Gtk2::SkeletonOpcode
|
||||
def initialize
|
||||
comment = "Opcode meta types currently supported by the database :"
|
||||
|
||||
# call the parent
|
||||
super("Metatypes", comment)
|
||||
|
||||
textview = Gtk::TextView.new
|
||||
textbuffer = Gtk::TextBuffer.new
|
||||
stuff.pack_start(textview, true, true, 0)
|
||||
|
||||
mts = "\n"
|
||||
$client.meta_types.each do |mt|
|
||||
mts << " - " + mt.name + "\n"
|
||||
end
|
||||
|
||||
textbuffer.set_text( mts )
|
||||
|
||||
textview.set_buffer(textbuffer)
|
||||
textview.set_editable(false)
|
||||
textview.set_cursor_visible(false)
|
||||
|
||||
show_all and run
|
||||
destroy
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Opcodes groups
|
||||
#
|
||||
class Groups < Msf::Ui::Gtk2::SkeletonOpcode
|
||||
def initialize
|
||||
comment = "Opcode groups currently supported by the database :"
|
||||
|
||||
# call the parent
|
||||
super("Groups", comment)
|
||||
|
||||
textview = Gtk::TextView.new
|
||||
textbuffer = Gtk::TextBuffer.new
|
||||
stuff.pack_start(textview, true, true, 0)
|
||||
|
||||
gs = "\n"
|
||||
$client.groups.each do |g|
|
||||
gs << " - " + g.name + "\n"
|
||||
end
|
||||
|
||||
textbuffer.set_text( gs )
|
||||
|
||||
textview.set_buffer(textbuffer)
|
||||
textview.set_editable(false)
|
||||
textview.set_cursor_visible(false)
|
||||
|
||||
show_all and run
|
||||
destroy
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Opcodes types
|
||||
#
|
||||
class Types < Msf::Ui::Gtk2::SkeletonOpcode
|
||||
def initialize
|
||||
comment = "Lists of the various specific opcode types supported by the database :"
|
||||
|
||||
# call the parent
|
||||
super("Types", comment)
|
||||
|
||||
textview = Gtk::TextView.new
|
||||
textbuffer = Gtk::TextBuffer.new
|
||||
|
||||
scrolled_window = Gtk::ScrolledWindow.new
|
||||
scrolled_window.add(textview)
|
||||
stuff.pack_start(scrolled_window, true, true, 5)
|
||||
scrolled_window.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC)
|
||||
|
||||
tps = "\n"
|
||||
$client.types.each do |g|
|
||||
tps << " - " + g.name + "\n"
|
||||
end
|
||||
|
||||
textbuffer.set_text( tps )
|
||||
|
||||
textview.set_buffer(textbuffer)
|
||||
textview.set_editable(false)
|
||||
textview.set_cursor_visible(false)
|
||||
|
||||
show_all and run
|
||||
destroy
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Opcodes Platforms
|
||||
#
|
||||
class Platforms < Msf::Ui::Gtk2::SkeletonOpcode
|
||||
def initialize
|
||||
comment = "Supported operating system versions broken down by major version and service pack :"
|
||||
|
||||
# call the parent
|
||||
super("Platforms", comment)
|
||||
|
||||
textview = Gtk::TextView.new
|
||||
textbuffer = Gtk::TextBuffer.new
|
||||
|
||||
scrolled_window = Gtk::ScrolledWindow.new
|
||||
scrolled_window.add(textview)
|
||||
stuff.pack_start(scrolled_window, true, true, 5)
|
||||
scrolled_window.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC)
|
||||
|
||||
ps = "\n"
|
||||
$client.platforms.each do |p|
|
||||
ps << " - " + p.desc + "\n"
|
||||
end
|
||||
|
||||
textbuffer.set_text( ps )
|
||||
|
||||
textview.set_buffer(textbuffer)
|
||||
textview.set_editable(false)
|
||||
textview.set_cursor_visible(false)
|
||||
|
||||
show_all and run
|
||||
destroy
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Modules Opcodes
|
||||
#
|
||||
class Modules < Msf::Ui::Gtk2::SkeletonOpcode
|
||||
|
||||
def initialize
|
||||
comment = "information about imports, exports, segments, and specific module attributes "
|
||||
|
||||
# Array for the face buttons
|
||||
buttons = [ Gtk::Stock::OK, Gtk::Dialog::RESPONSE_OK ], [ Gtk::Stock::CLOSE, Gtk::Dialog::RESPONSE_NONE ]
|
||||
|
||||
# call the parent
|
||||
super("Modules", comment, buttons)
|
||||
self.default_response = Gtk::Dialog::RESPONSE_OK
|
||||
|
||||
# Hash to store the global values
|
||||
@filter = {}
|
||||
|
||||
@collect = {}
|
||||
@collect_locales = {}
|
||||
@collect_platforms = {}
|
||||
@collect_modules = Gtk::TextBuffer.new
|
||||
|
||||
@collect['Exports'] = Gtk::CheckButton.new("Include module export information")
|
||||
@collect['Imports'] = Gtk::CheckButton.new("Include module import information")
|
||||
@collect['Segments'] = Gtk::CheckButton.new("Include module segment information")
|
||||
@collect['Detailed'] = Gtk::CheckButton.new("Display detailed output")
|
||||
|
||||
stuff.pack_start(@collect['Exports'], false, false, 0)
|
||||
stuff.pack_start(@collect['Imports'], false, false, 0)
|
||||
stuff.pack_start(@collect['Segments'], false, false, 0)
|
||||
stuff.pack_start(@collect['Detailed'], false, false, 0)
|
||||
|
||||
# For Locales frame
|
||||
frame_locale = Gtk::Frame.new
|
||||
stuff.pack_start(frame_locale, false, false, 0)
|
||||
@table_locale = Gtk::Table.new(3, 2, true)
|
||||
frame_locale.add(@table_locale)
|
||||
create_locales
|
||||
|
||||
# For Platforms frame
|
||||
frame_platforms = Gtk::Frame.new
|
||||
stuff.pack_start(frame_platforms, false, false, 0)
|
||||
@table_platforms = Gtk::Table.new(3, 2, true)
|
||||
frame_platforms.add(@table_platforms)
|
||||
create_platforms
|
||||
|
||||
# For Modules frame
|
||||
frame_modules = Gtk::Frame.new
|
||||
stuff.pack_start(frame_modules, false, false, 0)
|
||||
@vbox_modules = Gtk::VBox.new(false, 10)
|
||||
frame_modules.add(@vbox_modules)
|
||||
create_modules(@collect_modules)
|
||||
|
||||
signal_connect('response') do |dialog, response_id|
|
||||
if response_id == Gtk::Dialog::RESPONSE_OK
|
||||
collect()
|
||||
end
|
||||
end
|
||||
|
||||
show_all and run
|
||||
destroy
|
||||
end
|
||||
|
||||
#
|
||||
# Display all supported locales
|
||||
#
|
||||
def create_locales
|
||||
@collect_locales['english'] = Gtk::CheckButton.new("English")
|
||||
@collect_locales['french'] = Gtk::CheckButton.new("French")
|
||||
@collect_locales['italian'] = Gtk::CheckButton.new("Italian")
|
||||
@collect_locales['german'] = Gtk::CheckButton.new("German")
|
||||
@table_locale.attach_defaults(@collect_locales['english'], 0, 1, 1, 2)
|
||||
@table_locale.attach_defaults(@collect_locales['french'], 0, 1, 2, 3)
|
||||
@table_locale.attach_defaults(@collect_locales['italian'], 1, 2, 1, 2)
|
||||
@table_locale.attach_defaults(@collect_locales['german'], 1, 2, 2, 3)
|
||||
end
|
||||
|
||||
#
|
||||
# Display all supported platforms
|
||||
#
|
||||
def create_platforms
|
||||
@collect_platforms['NT'] = Gtk::CheckButton.new("Windows NT")
|
||||
@collect_platforms['2000'] = Gtk::CheckButton.new("Windows 2000")
|
||||
@collect_platforms['XP'] = Gtk::CheckButton.new("Windows XP")
|
||||
@collect_platforms['2003'] = Gtk::CheckButton.new("Windows 2003")
|
||||
@table_platforms.attach_defaults(@collect_platforms['NT'], 0, 1, 1, 2)
|
||||
@table_platforms.attach_defaults(@collect_platforms['2000'], 0, 1, 2, 3)
|
||||
@table_platforms.attach_defaults(@collect_platforms['XP'], 1, 2, 1, 2)
|
||||
@table_platforms.attach_defaults(@collect_platforms['2003'], 1, 2, 2, 3)
|
||||
end
|
||||
|
||||
#
|
||||
# Display a Gtk::TextView for modules
|
||||
#
|
||||
def create_modules(buffer)
|
||||
label = Gtk::Label.new(" A comma separated list of module names to filter (Ex: kernel32.dll,user32.dll)")
|
||||
label.set_alignment(0, 0)
|
||||
@vbox_modules.pack_start(label, false, false, 0)
|
||||
textview = Gtk::TextView.new(buffer)
|
||||
textview.set_size_request(480, 50)
|
||||
@vbox_modules.pack_start(textview, true, true, 0)
|
||||
end
|
||||
|
||||
#
|
||||
# Collect data
|
||||
#
|
||||
def collect
|
||||
|
||||
# For Global option
|
||||
@collect.each_pair do |key, value|
|
||||
if value.active?
|
||||
@filter[key] = true
|
||||
end
|
||||
end
|
||||
|
||||
# For locales
|
||||
@filter['LocaleNames'] = ""
|
||||
@collect_locales.each_pair do |key, value|
|
||||
if value.active?
|
||||
@filter['LocaleNames'] = @filter['LocaleNames'] + key
|
||||
end
|
||||
end
|
||||
|
||||
# For platform
|
||||
@filter['PlatformNames'] = ""
|
||||
@collect_platforms.each_pair do |key, value|
|
||||
if value.active?
|
||||
@filter['PlatformNames'] = @filter['PlatformNames'] + key
|
||||
end
|
||||
end
|
||||
|
||||
# For module
|
||||
@filter['ModuleNames'] = @collect_modules.get_text.split(/,/)
|
||||
|
||||
# Perform an XML request
|
||||
modules = $client.modules(@filter)
|
||||
|
||||
display($client.last_xml)
|
||||
|
||||
end
|
||||
|
||||
#
|
||||
# Display the matched modules
|
||||
#
|
||||
def display(xml)
|
||||
|
||||
# Load XML
|
||||
doc = REXML::Document.new(xml)
|
||||
|
||||
doc.elements.each("Array/Hash/Entry[@name='name']") do |element|
|
||||
puts element.text
|
||||
end
|
||||
|
||||
# puts doc.elements["Array/Hash/Entry[@name='name']"].text
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
#
|
||||
# Skeleton for opcodes stuff
|
||||
#
|
||||
class SkeletonOpcode < Gtk::Dialog
|
||||
|
||||
include Msf::Ui::Gtk2::MyControls
|
||||
|
||||
attr_accessor :comment, :stuff
|
||||
|
||||
def initialize(title, comments, buttons=[[ Gtk::Stock::CLOSE, Gtk::Dialog::RESPONSE_NONE ]])
|
||||
super("", $gtk2driver.main, Gtk::Dialog::DESTROY_WITH_PARENT, *buttons)
|
||||
|
||||
# Style
|
||||
console_style = File.join(driver.resource_directory, 'style', 'opcode.rc')
|
||||
Gtk::RC.parse(console_style)
|
||||
|
||||
self.border_width = 6
|
||||
self.resizable = true
|
||||
self.has_separator = true
|
||||
self.vbox.spacing = 12
|
||||
self.vbox.set_homogeneous(false)
|
||||
self.title = title
|
||||
self.set_default_size(500, 400)
|
||||
|
||||
@comment = Gtk::Label.new
|
||||
@comment.set_alignment(0, 0)
|
||||
@comment.set_markup("<b>#{comments}</b>")
|
||||
self.vbox.pack_start(@comment, false, false, 0)
|
||||
|
||||
@stuff = Gtk::VBox.new(false, 10)
|
||||
self.vbox.pack_start(@stuff, true, true, 0)
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Gtk2 Interface for Metasploit Opcodes database
|
||||
#
|
||||
class MsfOpcode
|
||||
|
||||
# Create the opcode client instance
|
||||
$client = Rex::Exploitation::OpcodeDb::Client.new
|
||||
|
||||
#
|
||||
# Opcodes statistics
|
||||
#
|
||||
class Stats < Msf::Ui::Gtk2::SkeletonOpcode
|
||||
|
||||
def initialize
|
||||
comment = "Current database statistics :"
|
||||
|
||||
# Call the parent
|
||||
super("Statistics", comment)
|
||||
|
||||
self.set_default_size(500, 230)
|
||||
|
||||
stats = $client.statistics
|
||||
|
||||
textview = Gtk::TextView.new
|
||||
textbuffer = Gtk::TextBuffer.new
|
||||
stuff.pack_start(textview, true, true, 0)
|
||||
|
||||
textbuffer.set_text(
|
||||
"\n" +
|
||||
"Last Updated : #{stats.last_update.to_s}\n" +
|
||||
"Number of Opcodes : #{stats.opcodes}\n" +
|
||||
"Number of Opcode Types : #{stats.opcode_types}\n" +
|
||||
"Number of Platforms : #{stats.platforms}\n" +
|
||||
"Number of Architectures : #{stats.architectures}\n" +
|
||||
"Number of Modules : #{stats.modules}\n" +
|
||||
"Number of Module Segments: #{stats.module_segments}\n" +
|
||||
"Number of Module Imports : #{stats.module_imports}\n" +
|
||||
"Number of Module Exports : #{stats.module_exports}\n\n")
|
||||
|
||||
textview.set_buffer(textbuffer)
|
||||
textview.set_editable(false)
|
||||
textview.set_cursor_visible(false)
|
||||
|
||||
show_all and run
|
||||
destroy
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Opcodes locales
|
||||
#
|
||||
class Locales < Msf::Ui::Gtk2::SkeletonOpcode
|
||||
def initialize
|
||||
comment = "Locales currently supported by the database:"
|
||||
|
||||
# call the parent
|
||||
super("Locales", comment)
|
||||
|
||||
self.set_default_size(500, 230)
|
||||
|
||||
textview = Gtk::TextView.new
|
||||
textbuffer = Gtk::TextBuffer.new
|
||||
stuff.pack_start(textview, true, true, 0)
|
||||
|
||||
locales = "\n"
|
||||
$client.locales.each do |locale|
|
||||
locales << " -" + locale.name + "\n"
|
||||
end
|
||||
|
||||
textbuffer.set_text( locales )
|
||||
|
||||
textview.set_buffer(textbuffer)
|
||||
textview.set_editable(false)
|
||||
textview.set_cursor_visible(false)
|
||||
|
||||
show_all and run
|
||||
destroy
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Opcodes meta types
|
||||
#
|
||||
class Metatypes < Msf::Ui::Gtk2::SkeletonOpcode
|
||||
def initialize
|
||||
comment = "Opcode meta types currently supported by the database :"
|
||||
|
||||
# call the parent
|
||||
super("Metatypes", comment)
|
||||
|
||||
textview = Gtk::TextView.new
|
||||
textbuffer = Gtk::TextBuffer.new
|
||||
stuff.pack_start(textview, true, true, 0)
|
||||
|
||||
mts = "\n"
|
||||
$client.meta_types.each do |mt|
|
||||
mts << " - " + mt.name + "\n"
|
||||
end
|
||||
|
||||
textbuffer.set_text( mts )
|
||||
|
||||
textview.set_buffer(textbuffer)
|
||||
textview.set_editable(false)
|
||||
textview.set_cursor_visible(false)
|
||||
|
||||
show_all and run
|
||||
destroy
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Opcodes groups
|
||||
#
|
||||
class Groups < Msf::Ui::Gtk2::SkeletonOpcode
|
||||
def initialize
|
||||
comment = "Opcode groups currently supported by the database :"
|
||||
|
||||
# call the parent
|
||||
super("Groups", comment)
|
||||
|
||||
textview = Gtk::TextView.new
|
||||
textbuffer = Gtk::TextBuffer.new
|
||||
stuff.pack_start(textview, true, true, 0)
|
||||
|
||||
gs = "\n"
|
||||
$client.groups.each do |g|
|
||||
gs << " - " + g.name + "\n"
|
||||
end
|
||||
|
||||
textbuffer.set_text( gs )
|
||||
|
||||
textview.set_buffer(textbuffer)
|
||||
textview.set_editable(false)
|
||||
textview.set_cursor_visible(false)
|
||||
|
||||
show_all and run
|
||||
destroy
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Opcodes types
|
||||
#
|
||||
class Types < Msf::Ui::Gtk2::SkeletonOpcode
|
||||
def initialize
|
||||
comment = "Lists of the various specific opcode types supported by the database :"
|
||||
|
||||
# call the parent
|
||||
super("Types", comment)
|
||||
|
||||
textview = Gtk::TextView.new
|
||||
textbuffer = Gtk::TextBuffer.new
|
||||
|
||||
scrolled_window = Gtk::ScrolledWindow.new
|
||||
scrolled_window.add(textview)
|
||||
stuff.pack_start(scrolled_window, true, true, 5)
|
||||
scrolled_window.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC)
|
||||
|
||||
tps = "\n"
|
||||
$client.types.each do |g|
|
||||
tps << " - " + g.name + "\n"
|
||||
end
|
||||
|
||||
textbuffer.set_text( tps )
|
||||
|
||||
textview.set_buffer(textbuffer)
|
||||
textview.set_editable(false)
|
||||
textview.set_cursor_visible(false)
|
||||
|
||||
show_all and run
|
||||
destroy
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Opcodes Platforms
|
||||
#
|
||||
class Platforms < Msf::Ui::Gtk2::SkeletonOpcode
|
||||
def initialize
|
||||
comment = "Supported operating system versions broken down by major version and service pack :"
|
||||
|
||||
# call the parent
|
||||
super("Platforms", comment)
|
||||
|
||||
textview = Gtk::TextView.new
|
||||
textbuffer = Gtk::TextBuffer.new
|
||||
|
||||
scrolled_window = Gtk::ScrolledWindow.new
|
||||
scrolled_window.add(textview)
|
||||
stuff.pack_start(scrolled_window, true, true, 5)
|
||||
scrolled_window.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC)
|
||||
|
||||
ps = "\n"
|
||||
$client.platforms.each do |p|
|
||||
ps << " - " + p.desc + "\n"
|
||||
end
|
||||
|
||||
textbuffer.set_text( ps )
|
||||
|
||||
textview.set_buffer(textbuffer)
|
||||
textview.set_editable(false)
|
||||
textview.set_cursor_visible(false)
|
||||
|
||||
show_all and run
|
||||
destroy
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Modules Opcodes
|
||||
#
|
||||
class Modules < Msf::Ui::Gtk2::SkeletonOpcode
|
||||
|
||||
def initialize
|
||||
comment = "information about imports, exports, segments, and specific module attributes "
|
||||
|
||||
# Array for the face buttons
|
||||
buttons = [ Gtk::Stock::OK, Gtk::Dialog::RESPONSE_OK ], [ Gtk::Stock::CLOSE, Gtk::Dialog::RESPONSE_NONE ]
|
||||
|
||||
# call the parent
|
||||
super("Modules", comment, buttons)
|
||||
self.default_response = Gtk::Dialog::RESPONSE_OK
|
||||
|
||||
# Hash to store the global values
|
||||
@filter = {}
|
||||
|
||||
@collect = {}
|
||||
@collect_locales = {}
|
||||
@collect_platforms = {}
|
||||
@collect_modules = Gtk::TextBuffer.new
|
||||
|
||||
@collect['Exports'] = Gtk::CheckButton.new("Include module export information")
|
||||
@collect['Imports'] = Gtk::CheckButton.new("Include module import information")
|
||||
@collect['Segments'] = Gtk::CheckButton.new("Include module segment information")
|
||||
@collect['Detailed'] = Gtk::CheckButton.new("Display detailed output")
|
||||
|
||||
stuff.pack_start(@collect['Exports'], false, false, 0)
|
||||
stuff.pack_start(@collect['Imports'], false, false, 0)
|
||||
stuff.pack_start(@collect['Segments'], false, false, 0)
|
||||
stuff.pack_start(@collect['Detailed'], false, false, 0)
|
||||
|
||||
# For Locales frame
|
||||
frame_locale = Gtk::Frame.new
|
||||
stuff.pack_start(frame_locale, false, false, 0)
|
||||
@table_locale = Gtk::Table.new(3, 2, true)
|
||||
frame_locale.add(@table_locale)
|
||||
create_locales
|
||||
|
||||
# For Platforms frame
|
||||
frame_platforms = Gtk::Frame.new
|
||||
stuff.pack_start(frame_platforms, false, false, 0)
|
||||
@table_platforms = Gtk::Table.new(3, 2, true)
|
||||
frame_platforms.add(@table_platforms)
|
||||
create_platforms
|
||||
|
||||
# For Modules frame
|
||||
frame_modules = Gtk::Frame.new
|
||||
stuff.pack_start(frame_modules, false, false, 0)
|
||||
@vbox_modules = Gtk::VBox.new(false, 10)
|
||||
frame_modules.add(@vbox_modules)
|
||||
create_modules(@collect_modules)
|
||||
|
||||
signal_connect('response') do |dialog, response_id|
|
||||
if response_id == Gtk::Dialog::RESPONSE_OK
|
||||
collect()
|
||||
end
|
||||
end
|
||||
|
||||
show_all and run
|
||||
destroy
|
||||
end
|
||||
|
||||
#
|
||||
# Display all supported locales
|
||||
#
|
||||
def create_locales
|
||||
@collect_locales['english'] = Gtk::CheckButton.new("English")
|
||||
@collect_locales['french'] = Gtk::CheckButton.new("French")
|
||||
@collect_locales['italian'] = Gtk::CheckButton.new("Italian")
|
||||
@collect_locales['german'] = Gtk::CheckButton.new("German")
|
||||
@table_locale.attach_defaults(@collect_locales['english'], 0, 1, 1, 2)
|
||||
@table_locale.attach_defaults(@collect_locales['french'], 0, 1, 2, 3)
|
||||
@table_locale.attach_defaults(@collect_locales['italian'], 1, 2, 1, 2)
|
||||
@table_locale.attach_defaults(@collect_locales['german'], 1, 2, 2, 3)
|
||||
end
|
||||
|
||||
#
|
||||
# Display all supported platforms
|
||||
#
|
||||
def create_platforms
|
||||
@collect_platforms['NT'] = Gtk::CheckButton.new("Windows NT")
|
||||
@collect_platforms['2000'] = Gtk::CheckButton.new("Windows 2000")
|
||||
@collect_platforms['XP'] = Gtk::CheckButton.new("Windows XP")
|
||||
@collect_platforms['2003'] = Gtk::CheckButton.new("Windows 2003")
|
||||
@table_platforms.attach_defaults(@collect_platforms['NT'], 0, 1, 1, 2)
|
||||
@table_platforms.attach_defaults(@collect_platforms['2000'], 0, 1, 2, 3)
|
||||
@table_platforms.attach_defaults(@collect_platforms['XP'], 1, 2, 1, 2)
|
||||
@table_platforms.attach_defaults(@collect_platforms['2003'], 1, 2, 2, 3)
|
||||
end
|
||||
|
||||
#
|
||||
# Display a Gtk::TextView for modules
|
||||
#
|
||||
def create_modules(buffer)
|
||||
label = Gtk::Label.new(" A comma separated list of module names to filter (Ex: kernel32.dll,user32.dll)")
|
||||
label.set_alignment(0, 0)
|
||||
@vbox_modules.pack_start(label, false, false, 0)
|
||||
textview = Gtk::TextView.new(buffer)
|
||||
textview.set_size_request(480, 50)
|
||||
@vbox_modules.pack_start(textview, true, true, 0)
|
||||
end
|
||||
|
||||
#
|
||||
# Collect data
|
||||
#
|
||||
def collect
|
||||
|
||||
# For Global option
|
||||
@collect.each_pair do |key, value|
|
||||
if value.active?
|
||||
@filter[key] = true
|
||||
end
|
||||
end
|
||||
|
||||
# For locales
|
||||
@filter['LocaleNames'] = ""
|
||||
@collect_locales.each_pair do |key, value|
|
||||
if value.active?
|
||||
@filter['LocaleNames'] = @filter['LocaleNames'] + key
|
||||
end
|
||||
end
|
||||
|
||||
# For platform
|
||||
@filter['PlatformNames'] = ""
|
||||
@collect_platforms.each_pair do |key, value|
|
||||
if value.active?
|
||||
@filter['PlatformNames'] = @filter['PlatformNames'] + key
|
||||
end
|
||||
end
|
||||
|
||||
# For module
|
||||
@filter['ModuleNames'] = @collect_modules.get_text.split(/,/)
|
||||
|
||||
# Perform an XML request
|
||||
modules = $client.modules(@filter)
|
||||
|
||||
display($client.last_xml)
|
||||
|
||||
end
|
||||
|
||||
#
|
||||
# Display the matched modules
|
||||
#
|
||||
def display(xml)
|
||||
|
||||
# Load XML
|
||||
doc = REXML::Document.new(xml)
|
||||
|
||||
doc.elements.each("Array/Hash/Entry[@name='name']") do |element|
|
||||
puts element.text
|
||||
end
|
||||
|
||||
# puts doc.elements["Array/Hash/Entry[@name='name']"].text
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,286 +1,286 @@
|
|||
module Msf
|
||||
module Ui
|
||||
module Gtk2
|
||||
module Ui
|
||||
module Gtk2
|
||||
|
||||
##
|
||||
# Skeleton class for all parameters stuff
|
||||
# title = Options title (menu)
|
||||
# items = Array
|
||||
##
|
||||
class SkeletonOption < Gtk::Dialog
|
||||
|
||||
attr_accessor :frame
|
||||
|
||||
def initialize(title, items)
|
||||
super("", $gtk2driver.main, Gtk::Dialog::DESTROY_WITH_PARENT,
|
||||
[ Gtk::Stock::OK, Gtk::Dialog::RESPONSE_NONE ],
|
||||
[ Gtk::Stock::CLOSE, Gtk::Dialog::RESPONSE_NONE ])
|
||||
|
||||
self.border_width = 6
|
||||
self.resizable = true
|
||||
self.has_separator = true
|
||||
self.vbox.spacing = 12
|
||||
self.vbox.set_homogeneous(false)
|
||||
self.title = title
|
||||
self.set_default_size(500, 400)
|
||||
|
||||
model = create_model(items)
|
||||
treeview = Gtk::TreeView.new(model)
|
||||
treeview.set_size_request(5, 200)
|
||||
|
||||
@hbox = Gtk::HBox.new(false, 10)
|
||||
|
||||
# ScrolledWindow
|
||||
sw = Gtk::ScrolledWindow.new
|
||||
sw.set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC)
|
||||
@hbox.pack_start(sw)
|
||||
sw.add(treeview)
|
||||
|
||||
renderer = Gtk::CellRendererText.new
|
||||
column = Gtk::TreeViewColumn.new('Select an item', renderer, 'text' => 0)
|
||||
#column.fixed_width = 20
|
||||
column.pack_start(renderer, false)
|
||||
treeview.append_column(column)
|
||||
|
||||
self.vbox.pack_start(@hbox, false, false, 0)
|
||||
@frame = Gtk::Frame.new
|
||||
@frame.set_size_request(300, 400)
|
||||
@hbox.pack_end(@frame, true, true, 0)
|
||||
|
||||
# Signal
|
||||
selection = treeview.selection
|
||||
selection.mode = Gtk::SELECTION_SINGLE
|
||||
selection.signal_connect('changed') do |s|
|
||||
selection_changed(s)
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Create and return the model
|
||||
#
|
||||
def create_model(items)
|
||||
store = Gtk::ListStore.new(String)
|
||||
|
||||
items.each do |item|
|
||||
iter = store.append
|
||||
iter[0] = item
|
||||
end
|
||||
|
||||
return store
|
||||
end
|
||||
|
||||
#
|
||||
# Destroy all children widgets in the frame
|
||||
#
|
||||
def clean_frame
|
||||
@frame.each do |w|
|
||||
w.destroy
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Dummy
|
||||
#
|
||||
def selection_changed(selection)
|
||||
#
|
||||
# must be present in the real class
|
||||
#
|
||||
end
|
||||
|
||||
#
|
||||
# Return a dialog file chooser
|
||||
#
|
||||
def file_chooser(title=nil)
|
||||
dialog = Gtk::FileChooserDialog.new(title,
|
||||
nil,
|
||||
Gtk::FileChooser::ACTION_OPEN,
|
||||
nil,
|
||||
[Gtk::Stock::OPEN, Gtk::Dialog::RESPONSE_ACCEPT],
|
||||
[Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL]
|
||||
)
|
||||
end
|
||||
end
|
||||
##
|
||||
# Skeleton class for all parameters stuff
|
||||
# title = Options title (menu)
|
||||
# items = Array
|
||||
##
|
||||
class SkeletonOption < Gtk::Dialog
|
||||
|
||||
class MsfParameters
|
||||
##
|
||||
# Display the preference parameters
|
||||
##
|
||||
class Preferences < Msf::Ui::Gtk2::SkeletonOption
|
||||
def initialize
|
||||
menu = ["Exploits", "Payloads"]
|
||||
super("Preferences", menu)
|
||||
|
||||
w_exploits
|
||||
|
||||
show_all and run
|
||||
destroy
|
||||
end
|
||||
|
||||
#
|
||||
# Describe the exploits widget
|
||||
#
|
||||
def w_exploits
|
||||
frame.set_label("Exploits")
|
||||
frame.add(Gtk::Label.new("Add specifics widgets here"))
|
||||
frame.show_all
|
||||
end
|
||||
|
||||
#
|
||||
# Describe the payloads widget
|
||||
#
|
||||
def w_payloads
|
||||
frame.set_label("Payloads")
|
||||
frame.shadow_type = Gtk::SHADOW_IN
|
||||
#frame.add(Gtk::Label.new("Add specifics widgets here"))
|
||||
|
||||
#
|
||||
# add specific widget here
|
||||
#
|
||||
vbox_frame = Gtk::VBox.new(false, 0)
|
||||
|
||||
# VNC
|
||||
frame.add(vbox_frame)
|
||||
|
||||
table_vnc = Gtk::Table.new(2, 2, false)
|
||||
table_vnc.set_row_spacings(4)
|
||||
table_vnc.set_column_spacings(4)
|
||||
vbox_frame.pack_start(table_vnc, false, false, 5)
|
||||
|
||||
label_vnc = Gtk::Label.new("Viewer VNC path: ")
|
||||
table_vnc.attach_defaults(label_vnc, 0, 1, 0, 1)
|
||||
|
||||
hbox_vnc = Gtk::HBox.new(false, 5)
|
||||
entry_vnc = Gtk::Entry.new
|
||||
table_vnc.attach_defaults(entry_vnc, 0, 2, 1, 2)
|
||||
|
||||
button_vnc = Gtk::HButtonBox.new
|
||||
button_vnc.layout_style = Gtk::ButtonBox::END
|
||||
button = Gtk::Button.new(Gtk::Stock::OPEN)
|
||||
button_vnc.add(button)
|
||||
#button_vnc = Gtk::FileChooserButton.new("Select a file", Gtk::FileChooser::ACTION_OPEN)
|
||||
table_vnc.attach_defaults(button_vnc, 1, 2, 0, 1)
|
||||
button.signal_connect('clicked') do
|
||||
dialog = file_chooser("Select your VNC viewer")
|
||||
if dialog.run == Gtk::Dialog::RESPONSE_ACCEPT
|
||||
entry_vnc.set_text(dialog.uri)
|
||||
end
|
||||
dialog.destroy
|
||||
end
|
||||
|
||||
frame.show_all
|
||||
end
|
||||
|
||||
#
|
||||
# Signals
|
||||
#
|
||||
def selection_changed(selection)
|
||||
iter = selection.selected
|
||||
case iter[0]
|
||||
when "Exploits"
|
||||
clean_frame and w_exploits
|
||||
when "Payloads"
|
||||
clean_frame and w_payloads
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
##
|
||||
# Display the databases parameters
|
||||
##
|
||||
class Databases < Msf::Ui::Gtk2::SkeletonOption
|
||||
def initialize
|
||||
menu = ["AutoPOWN", "OPCODES"]
|
||||
super("Databases", menu)
|
||||
|
||||
show_all and run
|
||||
destroy
|
||||
end
|
||||
|
||||
#
|
||||
# Describe the autopown widget
|
||||
#
|
||||
def w_autopown
|
||||
frame.set_label("AutoPWN")
|
||||
end
|
||||
|
||||
#
|
||||
# Describe the opcode widget opcodes
|
||||
#
|
||||
def w_opcode
|
||||
frame.set_label("OPCODES")
|
||||
end
|
||||
|
||||
#
|
||||
# Signals
|
||||
#
|
||||
def selection_changed(selection)
|
||||
iter = selection.selected
|
||||
case iter[0]
|
||||
when "AutoPOWN"
|
||||
clean_frame and w_autopown
|
||||
when "OPCODES"
|
||||
clean_frame and w_opcode
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
###
|
||||
# Display the options parameters
|
||||
###
|
||||
class Options < Msf::Ui::Gtk2::SkeletonOption
|
||||
def initialize
|
||||
menu = ["Debug", "Tips", "Proxy", "Update"]
|
||||
super("Options", menu)
|
||||
|
||||
show_all and run
|
||||
destroy
|
||||
end
|
||||
|
||||
def w_debug
|
||||
frame.set_label("Debug")
|
||||
end
|
||||
|
||||
#
|
||||
# Want to show tips ... or not !
|
||||
#
|
||||
def w_tips
|
||||
frame.set_label("Tips")
|
||||
end
|
||||
|
||||
#
|
||||
# Need a proxy ?
|
||||
#
|
||||
def w_proxy
|
||||
frame.set_label("Proxy")
|
||||
end
|
||||
|
||||
#
|
||||
# Update stuff
|
||||
#
|
||||
def w_update
|
||||
frame.set_label("Update")
|
||||
end
|
||||
|
||||
#
|
||||
# Signals
|
||||
#
|
||||
def selection_changed(selection)
|
||||
iter = selection.selected
|
||||
case iter[0]
|
||||
when "Debug"
|
||||
clean_frame and w_debug
|
||||
when "Tips"
|
||||
clean_frame and w_tips
|
||||
when "Proxy"
|
||||
clean_frame and w_proxy
|
||||
when "Update"
|
||||
clean_frame and w_update
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
attr_accessor :frame
|
||||
|
||||
end
|
||||
end
|
||||
def initialize(title, items)
|
||||
super("", $gtk2driver.main, Gtk::Dialog::DESTROY_WITH_PARENT,
|
||||
[ Gtk::Stock::OK, Gtk::Dialog::RESPONSE_NONE ],
|
||||
[ Gtk::Stock::CLOSE, Gtk::Dialog::RESPONSE_NONE ])
|
||||
|
||||
self.border_width = 6
|
||||
self.resizable = true
|
||||
self.has_separator = true
|
||||
self.vbox.spacing = 12
|
||||
self.vbox.set_homogeneous(false)
|
||||
self.title = title
|
||||
self.set_default_size(500, 400)
|
||||
|
||||
model = create_model(items)
|
||||
treeview = Gtk::TreeView.new(model)
|
||||
treeview.set_size_request(5, 200)
|
||||
|
||||
@hbox = Gtk::HBox.new(false, 10)
|
||||
|
||||
# ScrolledWindow
|
||||
sw = Gtk::ScrolledWindow.new
|
||||
sw.set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC)
|
||||
@hbox.pack_start(sw)
|
||||
sw.add(treeview)
|
||||
|
||||
renderer = Gtk::CellRendererText.new
|
||||
column = Gtk::TreeViewColumn.new('Select an item', renderer, 'text' => 0)
|
||||
#column.fixed_width = 20
|
||||
column.pack_start(renderer, false)
|
||||
treeview.append_column(column)
|
||||
|
||||
self.vbox.pack_start(@hbox, false, false, 0)
|
||||
@frame = Gtk::Frame.new
|
||||
@frame.set_size_request(300, 400)
|
||||
@hbox.pack_end(@frame, true, true, 0)
|
||||
|
||||
# Signal
|
||||
selection = treeview.selection
|
||||
selection.mode = Gtk::SELECTION_SINGLE
|
||||
selection.signal_connect('changed') do |s|
|
||||
selection_changed(s)
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Create and return the model
|
||||
#
|
||||
def create_model(items)
|
||||
store = Gtk::ListStore.new(String)
|
||||
|
||||
items.each do |item|
|
||||
iter = store.append
|
||||
iter[0] = item
|
||||
end
|
||||
|
||||
return store
|
||||
end
|
||||
|
||||
#
|
||||
# Destroy all children widgets in the frame
|
||||
#
|
||||
def clean_frame
|
||||
@frame.each do |w|
|
||||
w.destroy
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Dummy
|
||||
#
|
||||
def selection_changed(selection)
|
||||
#
|
||||
# must be present in the real class
|
||||
#
|
||||
end
|
||||
|
||||
#
|
||||
# Return a dialog file chooser
|
||||
#
|
||||
def file_chooser(title=nil)
|
||||
dialog = Gtk::FileChooserDialog.new(title,
|
||||
nil,
|
||||
Gtk::FileChooser::ACTION_OPEN,
|
||||
nil,
|
||||
[Gtk::Stock::OPEN, Gtk::Dialog::RESPONSE_ACCEPT],
|
||||
[Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL]
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
class MsfParameters
|
||||
##
|
||||
# Display the preference parameters
|
||||
##
|
||||
class Preferences < Msf::Ui::Gtk2::SkeletonOption
|
||||
def initialize
|
||||
menu = ["Exploits", "Payloads"]
|
||||
super("Preferences", menu)
|
||||
|
||||
w_exploits
|
||||
|
||||
show_all and run
|
||||
destroy
|
||||
end
|
||||
|
||||
#
|
||||
# Describe the exploits widget
|
||||
#
|
||||
def w_exploits
|
||||
frame.set_label("Exploits")
|
||||
frame.add(Gtk::Label.new("Add specifics widgets here"))
|
||||
frame.show_all
|
||||
end
|
||||
|
||||
#
|
||||
# Describe the payloads widget
|
||||
#
|
||||
def w_payloads
|
||||
frame.set_label("Payloads")
|
||||
frame.shadow_type = Gtk::SHADOW_IN
|
||||
#frame.add(Gtk::Label.new("Add specifics widgets here"))
|
||||
|
||||
#
|
||||
# add specific widget here
|
||||
#
|
||||
vbox_frame = Gtk::VBox.new(false, 0)
|
||||
|
||||
# VNC
|
||||
frame.add(vbox_frame)
|
||||
|
||||
table_vnc = Gtk::Table.new(2, 2, false)
|
||||
table_vnc.set_row_spacings(4)
|
||||
table_vnc.set_column_spacings(4)
|
||||
vbox_frame.pack_start(table_vnc, false, false, 5)
|
||||
|
||||
label_vnc = Gtk::Label.new("Viewer VNC path: ")
|
||||
table_vnc.attach_defaults(label_vnc, 0, 1, 0, 1)
|
||||
|
||||
hbox_vnc = Gtk::HBox.new(false, 5)
|
||||
entry_vnc = Gtk::Entry.new
|
||||
table_vnc.attach_defaults(entry_vnc, 0, 2, 1, 2)
|
||||
|
||||
button_vnc = Gtk::HButtonBox.new
|
||||
button_vnc.layout_style = Gtk::ButtonBox::END
|
||||
button = Gtk::Button.new(Gtk::Stock::OPEN)
|
||||
button_vnc.add(button)
|
||||
#button_vnc = Gtk::FileChooserButton.new("Select a file", Gtk::FileChooser::ACTION_OPEN)
|
||||
table_vnc.attach_defaults(button_vnc, 1, 2, 0, 1)
|
||||
button.signal_connect('clicked') do
|
||||
dialog = file_chooser("Select your VNC viewer")
|
||||
if dialog.run == Gtk::Dialog::RESPONSE_ACCEPT
|
||||
entry_vnc.set_text(dialog.uri)
|
||||
end
|
||||
dialog.destroy
|
||||
end
|
||||
|
||||
frame.show_all
|
||||
end
|
||||
|
||||
#
|
||||
# Signals
|
||||
#
|
||||
def selection_changed(selection)
|
||||
iter = selection.selected
|
||||
case iter[0]
|
||||
when "Exploits"
|
||||
clean_frame and w_exploits
|
||||
when "Payloads"
|
||||
clean_frame and w_payloads
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
##
|
||||
# Display the databases parameters
|
||||
##
|
||||
class Databases < Msf::Ui::Gtk2::SkeletonOption
|
||||
def initialize
|
||||
menu = ["AutoPOWN", "OPCODES"]
|
||||
super("Databases", menu)
|
||||
|
||||
show_all and run
|
||||
destroy
|
||||
end
|
||||
|
||||
#
|
||||
# Describe the autopown widget
|
||||
#
|
||||
def w_autopown
|
||||
frame.set_label("AutoPWN")
|
||||
end
|
||||
|
||||
#
|
||||
# Describe the opcode widget opcodes
|
||||
#
|
||||
def w_opcode
|
||||
frame.set_label("OPCODES")
|
||||
end
|
||||
|
||||
#
|
||||
# Signals
|
||||
#
|
||||
def selection_changed(selection)
|
||||
iter = selection.selected
|
||||
case iter[0]
|
||||
when "AutoPOWN"
|
||||
clean_frame and w_autopown
|
||||
when "OPCODES"
|
||||
clean_frame and w_opcode
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
###
|
||||
# Display the options parameters
|
||||
###
|
||||
class Options < Msf::Ui::Gtk2::SkeletonOption
|
||||
def initialize
|
||||
menu = ["Debug", "Tips", "Proxy", "Update"]
|
||||
super("Options", menu)
|
||||
|
||||
show_all and run
|
||||
destroy
|
||||
end
|
||||
|
||||
def w_debug
|
||||
frame.set_label("Debug")
|
||||
end
|
||||
|
||||
#
|
||||
# Want to show tips ... or not !
|
||||
#
|
||||
def w_tips
|
||||
frame.set_label("Tips")
|
||||
end
|
||||
|
||||
#
|
||||
# Need a proxy ?
|
||||
#
|
||||
def w_proxy
|
||||
frame.set_label("Proxy")
|
||||
end
|
||||
|
||||
#
|
||||
# Update stuff
|
||||
#
|
||||
def w_update
|
||||
frame.set_label("Update")
|
||||
end
|
||||
|
||||
#
|
||||
# Signals
|
||||
#
|
||||
def selection_changed(selection)
|
||||
iter = selection.selected
|
||||
case iter[0]
|
||||
when "Debug"
|
||||
clean_frame and w_debug
|
||||
when "Tips"
|
||||
clean_frame and w_tips
|
||||
when "Proxy"
|
||||
clean_frame and w_proxy
|
||||
when "Update"
|
||||
clean_frame and w_update
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,126 +1,126 @@
|
|||
module Msf
|
||||
module Ui
|
||||
module Gtk2
|
||||
module Ui
|
||||
module Gtk2
|
||||
|
||||
##
|
||||
# This class describe all search stuff into the module treeview
|
||||
##
|
||||
class ModuleSearch
|
||||
include Msf::Ui::Gtk2::MyControls
|
||||
|
||||
RUNNING, CLEAR = *(0..2).to_a
|
||||
|
||||
@@state = nil
|
||||
|
||||
#
|
||||
# Initialize all stuff to perform a search
|
||||
#
|
||||
def initialize(search_entry, search_button, search_cancel_button)
|
||||
@search_entry = search_entry
|
||||
@search_button = search_button
|
||||
@cancel_button = search_cancel_button
|
||||
|
||||
# Active completion
|
||||
completion()
|
||||
|
||||
# Init state
|
||||
@@state = CLEAR
|
||||
|
||||
# Signals
|
||||
@search_entry.signal_connect('activate') do
|
||||
@search_button.activate
|
||||
end
|
||||
|
||||
@search_button.signal_connect('clicked') do
|
||||
search(@search_entry.text)
|
||||
end
|
||||
|
||||
@cancel_button.signal_connect('clicked') do
|
||||
cancel()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Perform a search throught the module treeview,
|
||||
# and return the array result to MyModuleTree::remove
|
||||
#
|
||||
def search(text)
|
||||
# If current state set to RUUNING, call cancel method
|
||||
cancel if @@state == RUNNING
|
||||
|
||||
# Set current state to RUNNING
|
||||
@@state = RUNNING
|
||||
|
||||
# Perform the search
|
||||
found = []
|
||||
filter = Regexp.new(text, Regexp::IGNORECASE)
|
||||
$gtk2driver.module_model.each do |model, path, iter|
|
||||
if (not iter[1][filter])
|
||||
found.push(iter)
|
||||
end
|
||||
end
|
||||
|
||||
# Colorize the Gtk::Entry
|
||||
state(RUNNING)
|
||||
|
||||
# pass the found array to the MyModuleTree and remove all not matched iter
|
||||
# and finish by expanding the treeview
|
||||
$gtk2driver.module_tree.remove(found)
|
||||
$gtk2driver.module_tree.expand
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Clean the Gtk::Entry and refresh the modules treeview
|
||||
#
|
||||
def cancel
|
||||
# clear the Gtk::Entry
|
||||
@search_entry.set_text("")
|
||||
|
||||
# Colorize the Gtk::Entry
|
||||
state(CLEAR)
|
||||
|
||||
# Refresh the modules treeview
|
||||
$gtk2driver.module_tree.refresh
|
||||
|
||||
# Register the current state
|
||||
@@state = CLEAR
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Colorize the Gtk::Entry by state parameter
|
||||
#
|
||||
def state(state)
|
||||
if (state == RUNNING)
|
||||
@search_entry.modify_base(Gtk::STATE_NORMAL, Gdk::Color.parse('gray'))
|
||||
elsif (state == CLEAR)
|
||||
@search_entry.modify_base(Gtk::STATE_NORMAL, Gdk::Color.parse('white'))
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Display completion for @search_entry
|
||||
#
|
||||
def completion
|
||||
# set completion
|
||||
completion = Gtk::EntryCompletion.new
|
||||
@search_entry.completion = completion
|
||||
|
||||
# Describe the model completion
|
||||
model = Gtk::ListStore.new(String)
|
||||
$gtk2driver.module_completion.each do |v|
|
||||
iter = model.append
|
||||
iter[0] = v
|
||||
end
|
||||
|
||||
# Attach the model completion to the completion object
|
||||
completion.model = model
|
||||
completion.text_column = 0
|
||||
end
|
||||
end
|
||||
##
|
||||
# This class describe all search stuff into the module treeview
|
||||
##
|
||||
class ModuleSearch
|
||||
include Msf::Ui::Gtk2::MyControls
|
||||
|
||||
end
|
||||
end
|
||||
RUNNING, CLEAR = *(0..2).to_a
|
||||
|
||||
@@state = nil
|
||||
|
||||
#
|
||||
# Initialize all stuff to perform a search
|
||||
#
|
||||
def initialize(search_entry, search_button, search_cancel_button)
|
||||
@search_entry = search_entry
|
||||
@search_button = search_button
|
||||
@cancel_button = search_cancel_button
|
||||
|
||||
# Active completion
|
||||
completion()
|
||||
|
||||
# Init state
|
||||
@@state = CLEAR
|
||||
|
||||
# Signals
|
||||
@search_entry.signal_connect('activate') do
|
||||
@search_button.activate
|
||||
end
|
||||
|
||||
@search_button.signal_connect('clicked') do
|
||||
search(@search_entry.text)
|
||||
end
|
||||
|
||||
@cancel_button.signal_connect('clicked') do
|
||||
cancel()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Perform a search throught the module treeview,
|
||||
# and return the array result to MyModuleTree::remove
|
||||
#
|
||||
def search(text)
|
||||
# If current state set to RUUNING, call cancel method
|
||||
cancel if @@state == RUNNING
|
||||
|
||||
# Set current state to RUNNING
|
||||
@@state = RUNNING
|
||||
|
||||
# Perform the search
|
||||
found = []
|
||||
filter = Regexp.new(text, Regexp::IGNORECASE)
|
||||
$gtk2driver.module_model.each do |model, path, iter|
|
||||
if (not iter[1][filter])
|
||||
found.push(iter)
|
||||
end
|
||||
end
|
||||
|
||||
# Colorize the Gtk::Entry
|
||||
state(RUNNING)
|
||||
|
||||
# pass the found array to the MyModuleTree and remove all not matched iter
|
||||
# and finish by expanding the treeview
|
||||
$gtk2driver.module_tree.remove(found)
|
||||
$gtk2driver.module_tree.expand
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Clean the Gtk::Entry and refresh the modules treeview
|
||||
#
|
||||
def cancel
|
||||
# clear the Gtk::Entry
|
||||
@search_entry.set_text("")
|
||||
|
||||
# Colorize the Gtk::Entry
|
||||
state(CLEAR)
|
||||
|
||||
# Refresh the modules treeview
|
||||
$gtk2driver.module_tree.refresh
|
||||
|
||||
# Register the current state
|
||||
@@state = CLEAR
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Colorize the Gtk::Entry by state parameter
|
||||
#
|
||||
def state(state)
|
||||
if (state == RUNNING)
|
||||
@search_entry.modify_base(Gtk::STATE_NORMAL, Gdk::Color.parse('gray'))
|
||||
elsif (state == CLEAR)
|
||||
@search_entry.modify_base(Gtk::STATE_NORMAL, Gdk::Color.parse('white'))
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Display completion for @search_entry
|
||||
#
|
||||
def completion
|
||||
# set completion
|
||||
completion = Gtk::EntryCompletion.new
|
||||
@search_entry.completion = completion
|
||||
|
||||
# Describe the model completion
|
||||
model = Gtk::ListStore.new(String)
|
||||
$gtk2driver.module_completion.each do |v|
|
||||
iter = model.append
|
||||
iter[0] = v
|
||||
end
|
||||
|
||||
# Attach the model completion to the completion object
|
||||
completion.model = model
|
||||
completion.text_column = 0
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,201 +1,201 @@
|
|||
module Msf
|
||||
module Ui
|
||||
module Gtk2
|
||||
module Ui
|
||||
module Gtk2
|
||||
|
||||
##
|
||||
# This class perform some tooltips for TreeView widget
|
||||
# This class is a port of Daniel J. Popowich coded in Python to ruby-gtk2 style
|
||||
##
|
||||
class TreeViewTooltips < Gtk::Window
|
||||
|
||||
def initialize
|
||||
super(Gtk::Window::POPUP)
|
||||
self.set_resizable(false)
|
||||
self.set_border_width(5)
|
||||
self.set_app_paintable(true)
|
||||
|
||||
# create the label
|
||||
@label = Gtk::Label.new
|
||||
@label.set_wrap(true)
|
||||
@label.set_alignment(0.5, 0.5)
|
||||
@label.set_use_markup(true)
|
||||
@label.show()
|
||||
self.add(@label)
|
||||
|
||||
# by default, the tooltip is enabled
|
||||
@enabled = true
|
||||
# saves the current cell
|
||||
@save = nil
|
||||
# the timer id for the next tooltip to be shown
|
||||
@next = nil
|
||||
# flag on whether the tooltip window is shown
|
||||
@shown = false
|
||||
end
|
||||
|
||||
#
|
||||
# Enable the tooltip
|
||||
#
|
||||
def enable
|
||||
@enable = true
|
||||
end
|
||||
|
||||
#
|
||||
# Disable the tooltip
|
||||
#
|
||||
def disable
|
||||
@enable = false
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Handler to be connected on to the Gtk::Treeview
|
||||
#
|
||||
def add_view(view)
|
||||
|
||||
# Enter
|
||||
view.signal_connect('motion-notify-event') do |view, event|
|
||||
motion_handler(view, event)
|
||||
end
|
||||
|
||||
# Leave
|
||||
view.signal_connect('leave-notify-event') do |view, event|
|
||||
leave_handler(view, event)
|
||||
end
|
||||
end
|
||||
##
|
||||
# This class perform some tooltips for TreeView widget
|
||||
# This class is a port of Daniel J. Popowich coded in Python to ruby-gtk2 style
|
||||
##
|
||||
class TreeViewTooltips < Gtk::Window
|
||||
|
||||
|
||||
#
|
||||
# Given the x,y coordinates of the pointer and the width and
|
||||
# height (w,h) demensions of the tooltip window, return the x, y
|
||||
# coordinates of the tooltip window.
|
||||
#
|
||||
# The default location is to center the window on the pointer
|
||||
# and 4 pixels below it.
|
||||
#
|
||||
def location(x, y, w, h)
|
||||
return x - w/2, y + 4
|
||||
end
|
||||
|
||||
|
||||
#########
|
||||
private #
|
||||
#########
|
||||
|
||||
#
|
||||
# show the tooltip popup with the text/markup given by
|
||||
# tooltip.
|
||||
#
|
||||
# tooltip: the text/markup for the tooltip.
|
||||
# x, y: the coord. (root window based) of the pointer.
|
||||
#
|
||||
def show(tooltip, x, y)
|
||||
# set label
|
||||
@label.set_label(tooltip)
|
||||
|
||||
# resize window
|
||||
w, h = self.size_request()
|
||||
|
||||
# Display the window with a 1-pixel black border
|
||||
self.style.paint_flat_box( self.window, # window: a Gdk::Window
|
||||
Gtk::STATE_NORMAL, # state_type: a state type (GtkStateType)
|
||||
Gtk::SHADOW_OUT, # shadow_type: a shadow type (GtkShadowType)
|
||||
nil, # area: a Gdk::Rectangle to which the output is clipped
|
||||
self, # widget: a Gtk::Widget
|
||||
'tooltip', # detail: a String or nil
|
||||
0, # x:
|
||||
0, # y:
|
||||
w, # width:
|
||||
h # height:
|
||||
)
|
||||
|
||||
# move the window
|
||||
self.move(*location(x,y,w,h))
|
||||
|
||||
# show it
|
||||
self.show_all
|
||||
@shown = true
|
||||
end
|
||||
def initialize
|
||||
super(Gtk::Window::POPUP)
|
||||
self.set_resizable(false)
|
||||
self.set_border_width(5)
|
||||
self.set_app_paintable(true)
|
||||
|
||||
#
|
||||
# hide the tooltip
|
||||
#
|
||||
def hide_me
|
||||
queue_next()
|
||||
self.hide()
|
||||
@shown = false
|
||||
end
|
||||
|
||||
#
|
||||
# When the pointer leaves the view, hide the tooltip
|
||||
#
|
||||
def leave_handler(view, event)
|
||||
hide_me()
|
||||
end
|
||||
# create the label
|
||||
@label = Gtk::Label.new
|
||||
@label.set_wrap(true)
|
||||
@label.set_alignment(0.5, 0.5)
|
||||
@label.set_use_markup(true)
|
||||
@label.show()
|
||||
self.add(@label)
|
||||
|
||||
#
|
||||
# As the pointer moves across the view, show a tooltip.
|
||||
#
|
||||
def motion_handler(view, event)
|
||||
# by default, the tooltip is enabled
|
||||
@enabled = true
|
||||
# saves the current cell
|
||||
@save = nil
|
||||
# the timer id for the next tooltip to be shown
|
||||
@next = nil
|
||||
# flag on whether the tooltip window is shown
|
||||
@shown = false
|
||||
end
|
||||
|
||||
path = view.get_path_at_pos(event.x, event.y)
|
||||
|
||||
if (@enabled and path)
|
||||
path, col, x, y = path
|
||||
tooltip = get_tooltip(view, col, path)
|
||||
if tooltip
|
||||
tooltip = tooltip.strip
|
||||
queue_next( [path, col], tooltip, event.x_root, event.y_root)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
hide_me()
|
||||
end
|
||||
#
|
||||
# Enable the tooltip
|
||||
#
|
||||
def enable
|
||||
@enable = true
|
||||
end
|
||||
|
||||
#
|
||||
# queue next request to show a tooltip
|
||||
#
|
||||
def queue_next(*args)
|
||||
|
||||
# if args is non-empty it means a request was made to show a
|
||||
# tooltip. if empty, no request is being made, but any
|
||||
# pending requests should be cancelled anyway.
|
||||
#
|
||||
# Disable the tooltip
|
||||
#
|
||||
def disable
|
||||
@enable = false
|
||||
end
|
||||
|
||||
cell = nil
|
||||
|
||||
# if called with args, break them out
|
||||
if args
|
||||
cell, tooltip, x, y = args
|
||||
end
|
||||
#
|
||||
# Handler to be connected on to the Gtk::Treeview
|
||||
#
|
||||
def add_view(view)
|
||||
|
||||
# if it's the same cell as previously shown, just return
|
||||
if (@save == cell)
|
||||
return
|
||||
end
|
||||
# Enter
|
||||
view.signal_connect('motion-notify-event') do |view, event|
|
||||
motion_handler(view, event)
|
||||
end
|
||||
|
||||
# if we have something queued up, cancel it
|
||||
if @next:
|
||||
Gtk.timeout_remove(@next)
|
||||
@next = nil
|
||||
end
|
||||
# Leave
|
||||
view.signal_connect('leave-notify-event') do |view, event|
|
||||
leave_handler(view, event)
|
||||
end
|
||||
end
|
||||
|
||||
# if there was a request...
|
||||
if cell
|
||||
# if the tooltip is already shown, show the new one
|
||||
# immediately
|
||||
if @shown
|
||||
show(tooltip, x, y)
|
||||
# else queue it up in 1/2 second
|
||||
else
|
||||
@next = Gtk.timeout_add(500) { show(tooltip, x, y) }
|
||||
end
|
||||
end
|
||||
|
||||
# save this cell
|
||||
@save = cell
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Given the x,y coordinates of the pointer and the width and
|
||||
# height (w,h) demensions of the tooltip window, return the x, y
|
||||
# coordinates of the tooltip window.
|
||||
#
|
||||
# The default location is to center the window on the pointer
|
||||
# and 4 pixels below it.
|
||||
#
|
||||
def location(x, y, w, h)
|
||||
return x - w/2, y + 4
|
||||
end
|
||||
|
||||
|
||||
#########
|
||||
private #
|
||||
#########
|
||||
|
||||
#
|
||||
# show the tooltip popup with the text/markup given by
|
||||
# tooltip.
|
||||
#
|
||||
# tooltip: the text/markup for the tooltip.
|
||||
# x, y: the coord. (root window based) of the pointer.
|
||||
#
|
||||
def show(tooltip, x, y)
|
||||
# set label
|
||||
@label.set_label(tooltip)
|
||||
|
||||
# resize window
|
||||
w, h = self.size_request()
|
||||
|
||||
# Display the window with a 1-pixel black border
|
||||
self.style.paint_flat_box( self.window, # window: a Gdk::Window
|
||||
Gtk::STATE_NORMAL, # state_type: a state type (GtkStateType)
|
||||
Gtk::SHADOW_OUT, # shadow_type: a shadow type (GtkShadowType)
|
||||
nil, # area: a Gdk::Rectangle to which the output is clipped
|
||||
self, # widget: a Gtk::Widget
|
||||
'tooltip', # detail: a String or nil
|
||||
0, # x:
|
||||
0, # y:
|
||||
w, # width:
|
||||
h # height:
|
||||
)
|
||||
|
||||
# move the window
|
||||
self.move(*location(x,y,w,h))
|
||||
|
||||
# show it
|
||||
self.show_all
|
||||
@shown = true
|
||||
end
|
||||
|
||||
#
|
||||
# hide the tooltip
|
||||
#
|
||||
def hide_me
|
||||
queue_next()
|
||||
self.hide()
|
||||
@shown = false
|
||||
end
|
||||
|
||||
#
|
||||
# When the pointer leaves the view, hide the tooltip
|
||||
#
|
||||
def leave_handler(view, event)
|
||||
hide_me()
|
||||
end
|
||||
|
||||
#
|
||||
# As the pointer moves across the view, show a tooltip.
|
||||
#
|
||||
def motion_handler(view, event)
|
||||
|
||||
path = view.get_path_at_pos(event.x, event.y)
|
||||
|
||||
if (@enabled and path)
|
||||
path, col, x, y = path
|
||||
tooltip = get_tooltip(view, col, path)
|
||||
if tooltip
|
||||
tooltip = tooltip.strip
|
||||
queue_next( [path, col], tooltip, event.x_root, event.y_root)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
hide_me()
|
||||
end
|
||||
|
||||
#
|
||||
# queue next request to show a tooltip
|
||||
#
|
||||
def queue_next(*args)
|
||||
|
||||
# if args is non-empty it means a request was made to show a
|
||||
# tooltip. if empty, no request is being made, but any
|
||||
# pending requests should be cancelled anyway.
|
||||
|
||||
cell = nil
|
||||
|
||||
# if called with args, break them out
|
||||
if args
|
||||
cell, tooltip, x, y = args
|
||||
end
|
||||
|
||||
# if it's the same cell as previously shown, just return
|
||||
if (@save == cell)
|
||||
return
|
||||
end
|
||||
|
||||
# if we have something queued up, cancel it
|
||||
if @next:
|
||||
Gtk.timeout_remove(@next)
|
||||
@next = nil
|
||||
end
|
||||
|
||||
# if there was a request...
|
||||
if cell
|
||||
# if the tooltip is already shown, show the new one
|
||||
# immediately
|
||||
if @shown
|
||||
show(tooltip, x, y)
|
||||
# else queue it up in 1/2 second
|
||||
else
|
||||
@next = Gtk.timeout_add(500) { show(tooltip, x, y) }
|
||||
end
|
||||
end
|
||||
|
||||
# save this cell
|
||||
@save = cell
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,71 +1,71 @@
|
|||
module Msf
|
||||
module Ui
|
||||
module Gtk2
|
||||
module Ui
|
||||
module Gtk2
|
||||
|
||||
##
|
||||
# This class describe all tags and behaviour for module view rendering
|
||||
# To initialize, a Gtk::TextBuffer must be passed in argument
|
||||
# TODO: Add a pixmap for platform
|
||||
#
|
||||
class MyModuleView
|
||||
def initialize(buffer)
|
||||
@buffer = buffer
|
||||
@buffer.create_tag("_",
|
||||
:'weight' => Pango::FontDescription::WEIGHT_BOLD
|
||||
)
|
||||
@buffer.create_tag("type",
|
||||
:'foreground' => 'red',
|
||||
:'weight' => Pango::FontDescription::WEIGHT_BOLD,
|
||||
:'left_margin' => 100
|
||||
)
|
||||
@buffer.create_tag("author",
|
||||
:'foreground' => 'ForestGreen',
|
||||
:'weight' => Pango::FontDescription::WEIGHT_BOLD,
|
||||
:'left_margin' => 100
|
||||
)
|
||||
@buffer.create_tag("refname",
|
||||
:'foreground' => 'RosyBrown',
|
||||
:'weight' => Pango::FontDescription::WEIGHT_BOLD,
|
||||
:'left_margin' => 100
|
||||
)
|
||||
@buffer.create_tag("reference",
|
||||
:'foreground' => 'blue',
|
||||
:'weight' => Pango::FontDescription::WEIGHT_BOLD,
|
||||
:'underline' => Pango::UNDERLINE_SINGLE,
|
||||
:'left_margin' => 100
|
||||
)
|
||||
@buffer.create_tag("description",
|
||||
:'style' => Pango::FontDescription::STYLE_ITALIC,
|
||||
:'wrap_mode' => Gtk::TextTag::WRAP_WORD
|
||||
)
|
||||
end
|
||||
|
||||
def insert_module(obj)
|
||||
@buffer.delete(*@buffer.bounds)
|
||||
start = @buffer.get_iter_at_offset(0)
|
||||
@buffer.insert_with_tags(start, "Type : ", "_")
|
||||
@buffer.insert_with_tags(start, obj.type + "\n", 'type')
|
||||
@buffer.insert_with_tags(start, "Author : ", "_")
|
||||
@buffer.insert_with_tags(start, obj.author_to_s + "\n", 'author')
|
||||
@buffer.insert_with_tags(start, "Path : ", "_")
|
||||
@buffer.insert_with_tags(start, obj.refname + "\n\n", 'refname')
|
||||
@buffer.insert_with_tags(start, "External Reference :\n", "_")
|
||||
extref = ""
|
||||
obj.references.each do |refs|
|
||||
extref << refs.to_s + "\n"
|
||||
end
|
||||
@buffer.insert_with_tags(start, extref + "\n", 'reference')
|
||||
@buffer.insert_with_tags(start, "Description :", '_')
|
||||
|
||||
# Ugly ... ;-( but crafty
|
||||
desc = ""
|
||||
obj.description.each_line do |line|
|
||||
desc << line.strip + "\n"
|
||||
end
|
||||
@buffer.insert_with_tags(start, desc, 'description')
|
||||
end
|
||||
end
|
||||
##
|
||||
# This class describe all tags and behaviour for module view rendering
|
||||
# To initialize, a Gtk::TextBuffer must be passed in argument
|
||||
# TODO: Add a pixmap for platform
|
||||
#
|
||||
class MyModuleView
|
||||
def initialize(buffer)
|
||||
@buffer = buffer
|
||||
@buffer.create_tag("_",
|
||||
:'weight' => Pango::FontDescription::WEIGHT_BOLD
|
||||
)
|
||||
@buffer.create_tag("type",
|
||||
:'foreground' => 'red',
|
||||
:'weight' => Pango::FontDescription::WEIGHT_BOLD,
|
||||
:'left_margin' => 100
|
||||
)
|
||||
@buffer.create_tag("author",
|
||||
:'foreground' => 'ForestGreen',
|
||||
:'weight' => Pango::FontDescription::WEIGHT_BOLD,
|
||||
:'left_margin' => 100
|
||||
)
|
||||
@buffer.create_tag("refname",
|
||||
:'foreground' => 'RosyBrown',
|
||||
:'weight' => Pango::FontDescription::WEIGHT_BOLD,
|
||||
:'left_margin' => 100
|
||||
)
|
||||
@buffer.create_tag("reference",
|
||||
:'foreground' => 'blue',
|
||||
:'weight' => Pango::FontDescription::WEIGHT_BOLD,
|
||||
:'underline' => Pango::UNDERLINE_SINGLE,
|
||||
:'left_margin' => 100
|
||||
)
|
||||
@buffer.create_tag("description",
|
||||
:'style' => Pango::FontDescription::STYLE_ITALIC,
|
||||
:'wrap_mode' => Gtk::TextTag::WRAP_WORD
|
||||
)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
def insert_module(obj)
|
||||
@buffer.delete(*@buffer.bounds)
|
||||
start = @buffer.get_iter_at_offset(0)
|
||||
@buffer.insert_with_tags(start, "Type : ", "_")
|
||||
@buffer.insert_with_tags(start, obj.type + "\n", 'type')
|
||||
@buffer.insert_with_tags(start, "Author : ", "_")
|
||||
@buffer.insert_with_tags(start, obj.author_to_s + "\n", 'author')
|
||||
@buffer.insert_with_tags(start, "Path : ", "_")
|
||||
@buffer.insert_with_tags(start, obj.refname + "\n\n", 'refname')
|
||||
@buffer.insert_with_tags(start, "External Reference :\n", "_")
|
||||
extref = ""
|
||||
obj.references.each do |refs|
|
||||
extref << refs.to_s + "\n"
|
||||
end
|
||||
@buffer.insert_with_tags(start, extref + "\n", 'reference')
|
||||
@buffer.insert_with_tags(start, "Description :", '_')
|
||||
|
||||
# Ugly ... ;-( but crafty
|
||||
desc = ""
|
||||
obj.description.each_line do |line|
|
||||
desc << line.strip + "\n"
|
||||
end
|
||||
@buffer.insert_with_tags(start, desc, 'description')
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue