Tnos of updates, overhaul of the session/IO stuff, still quite broken

git-svn-id: file:///home/svn/framework3/trunk@4354 4d416f70-5f16-0410-b530-b9f4589650da
unstable
HD Moore 2007-02-11 08:57:43 +00:00
parent ba04593187
commit 043e338f72
8 changed files with 152 additions and 130 deletions

View File

@ -37,7 +37,7 @@
<child>
<widget class="GtkMenuItem" id="menuitem1">
<property name="visible">True</property>
<property name="label" translatable="yes">MSF</property>
<property name="label" translatable="yes">_System</property>
<property name="use_underline">True</property>
<child>
@ -96,7 +96,7 @@
<child>
<widget class="GtkMenuItem" id="on_about">
<property name="visible">True</property>
<property name="label" translatable="yes">À _propos</property>
<property name="label" translatable="yes">_About</property>
<property name="use_underline">True</property>
<signal name="activate" handler="on_about_activate" last_modification_time="Tue, 02 Jan 2007 18:19:55 GMT"/>
</widget>
@ -284,7 +284,7 @@
<child>
<widget class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="label" translatable="yes">-&gt;</property>
<property name="label" translatable="yes">Information</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
@ -342,7 +342,7 @@
<child>
<widget class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="label" translatable="yes">MSF Logs</property>
<property name="label" translatable="yes">Logs</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
@ -400,7 +400,7 @@
<child>
<widget class="GtkLabel" id="label8">
<property name="visible">True</property>
<property name="label" translatable="yes">Jobs</property>
<property name="label" translatable="yes">Console</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>

View File

@ -62,13 +62,19 @@ class MyApp < MyGlade
@viewlogs.set_cursor_visible(false)
# Sessions Tree
session_tree = MySessionTree.new(@treeview_session)
@session_tree = MySessionTree.new(@treeview_session)
# Target Tree
@target_tree = MyTargetTree.new(@treeview2, session_tree)
@target_tree = MyTargetTree.new(@treeview2, @session_tree)
# Module Tree
@module_tree = MyModuleTree.new(@treeview1, @viewmodule, @target_tree, session_tree)
@module_tree = MyModuleTree.new(@treeview1, @viewmodule, @target_tree, @session_tree)
# Configure the window handles for easy reference
$gtk2driver.session_tree = @session_tree
$gtk2driver.target_tree = @target_tree
$gtk2driver.module_tree = @module_tree
$gtk2driver.log_text = @viewlogs
# Update the StatusBar with all framework modules
refresh()

View File

@ -16,9 +16,8 @@ class MsfAssistant
include Msf::Ui::Gtk2::MyControls
def initialize(session_tree, target_tree, active_module)
@buffer = Gtk::TextBuffer.new
@session_tree = session_tree
@target_tree = target_tree
@session_tree = session_tree
@target_tree = target_tree
@active_module = active_module
# initialize exploit driver's exploit instance
@ -336,7 +335,7 @@ class MsfAssistant
puts "#{key}: #{value}"
end
# Import options from the supplied assitant
# Import options from the supplied assistant
@mydriver.exploit.datastore.import_options_from_hash(@hash)
# Share the exploit's datastore with the payload
@ -344,34 +343,26 @@ class MsfAssistant
@mydriver.target_idx = (@mydriver.exploit.datastore['TARGET']).to_i
pipe = Msf::Ui::Gtk2::Stream::GtkConsolePipe.new(@buffer)
pipe = Rex::IO::BidirectionalPipe.new
input = pipe.pipe_input
output = pipe
@mydriver.exploit.init_ui(pipe, pipe)
@mydriver.payload.init_ui(pipe, pipe)
@mydriver.exploit.init_ui(input, output)
@mydriver.payload.init_ui(input, output)
# Session registration is done by event handler
# XXX: No output from the exploit when this is set!
# @mydriver.use_job = true
@target_tree.add_oneshot(@active_module)
session = @mydriver.run
if (session)
@t_ses = Thread.new do
Msf::Ui::Gtk2::Stream::Session.new(@buffer,
@session_tree,
@hash,
session,
pipe,
input,
output)
end
else
puts "TODO: redirect to MsfLogs"
pipe.create_subscriber_proc() do |msg|
$stderr.puts "MSG: #{msg}"
$gtk2driver.append_log_view(msg)
end
# Kill off the session thread
@t_ses.kill
begin
$stderr.puts @mydriver.run.inspect
@target_tree.add_oneshot(@active_module)
rescue ::Exception => e
pipe.print_error("Exploit failed: #{e}")
end
end
end # def update_page

View File

@ -11,6 +11,8 @@ require 'msf/ui/gtk2/logs'
require 'msf/ui/gtk2/stream'
require 'msf/ui/gtk2/view'
require 'msf/ui/gtk2/framework_event_manager'
module Msf
module Ui
module Gtk2
@ -22,6 +24,11 @@ module Gtk2
###
class Driver < Msf::Ui::Driver
attr_accessor :session_tree, :module_tree, :target_tree, :log_text
include Msf::Ui::Gtk2::FrameworkEventManager
ConfigCore = "framework/core"
ConfigGroup = "framework/ui/gtk2"
@ -57,6 +64,9 @@ class Driver < Msf::Ui::Driver
# Initialize the Gtk2 application object
@gtk2app = Msf::Ui::Gtk2::MyApp.new()
# Register event handlers
register_event_handlers
end
#
@ -81,6 +91,28 @@ class Driver < Msf::Ui::Driver
def get_icon(name)
Gdk::Pixbuf.new(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.

View File

@ -111,7 +111,7 @@ class MyModuleTree < MyGlade
#
# Add Exploits module in the treeview
#
def add_modules(filter=/.*/)
def add_modules(filter=/.*/)
@m_tree_modules_items = {}
#
@ -360,7 +360,7 @@ class MyTargetTree < MyGlade
end #class MyTargetTree
class MySessionTree
ID_SESSION, RHOST, PAYLOAD, O_SESSION, BUFFER, PIPE, INPUT, OUTPUT = *(0..8).to_a
ID_SESSION, PEER, PAYLOAD, O_SESSION, BUFFER, PIPE, INPUT, OUTPUT = *(0..8).to_a
def initialize(treeview)
@treeview = treeview
@ -375,8 +375,8 @@ class MySessionTree
)
# Renderer
renderer_id = Gtk::CellRendererText.new
renderer_rhost = Gtk::CellRendererText.new
renderer_id = Gtk::CellRendererText.new
renderer_peer = Gtk::CellRendererText.new
renderer_payload = Gtk::CellRendererText.new
# ID Session Gtk::TreeViewColumn
@ -391,20 +391,20 @@ class MySessionTree
column_id.sort_column_id = ID_SESSION
# Target Gtk::TreeViewColumn
column_rhost = Gtk::TreeViewColumn.new
column_rhost.set_title("Target")
column_rhost.pack_start(renderer_rhost, true)
column_rhost.set_cell_data_func(renderer_rhost) do |column, cell, model, iter|
cell.text = iter[RHOST]
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[O_SESSION].tunnel_peer
end
column_rhost.sort_column_id = RHOST
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]
cell.text = iter[O_SESSION].via_payload ? iter[O_SESSION].via_payload : nil
end
column_payload.sort_column_id = PAYLOAD
@ -417,13 +417,13 @@ class MySessionTree
# Add Gtk::TreeViewColumn
@treeview.append_column(column_id)
@treeview.append_column(column_rhost)
@treeview.append_column(column_peer)
@treeview.append_column(column_payload)
# Session Gtk::Menu
@menu_session = Gtk::Menu.new
session_item_shell = Gtk::ImageMenuItem.new("Bind Shell")
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)
@ -454,30 +454,19 @@ class MySessionTree
# Items session signals
session_item_shell.signal_connect('activate') do |item|
if current = @selection.selected
Msf::Ui::Gtk2::Stream::Console.new(current[O_SESSION],
current[BUFFER],
current[PIPE],
current[INPUT],
current[OUTPUT]
)
Msf::Ui::Gtk2::Stream::Console.new(current[O_SESSION])
end
end
end # def initialize
def add_session(session, options, buffer, pipe, input, output)
def add_session(session)
iter = @model.append
iter[ID_SESSION] = session.sid.to_s
iter[RHOST] = options['RHOST']
iter[PAYLOAD] = options['PAYLOAD']
iter[O_SESSION] = session
iter[BUFFER] = buffer
iter[PIPE] = pipe
iter[INPUT] = input
iter[OUTPUT] = output
iter[O_SESSION] = session
end
end # class MySessionTree
end
end
end
end

View File

@ -29,25 +29,37 @@ module FrameworkEventManager
# Called when a session is registered with the framework.
#
def on_session_open(session)
output.print_status("#{session.desc} session #{session.name} opened (#{session.tunnel_to_s})")
$stderr.puts "NEW SESSION"
begin
Msf::Ui::Gtk2::Stream::Session.new($gtk2driver.session_tree, session)
if (Msf::Logging.session_logging_enabled? == true)
Msf::Logging.start_session_log(session)
end
rescue ::Exception => e
$stderr.puts e
$stderr.puts e.class
$stderr.puts e.backtrace.inspect
end
end
#
# Called when a session is closed and removed from the framework.
#
def on_session_close(session)
$stderr.puts "DEAD SESSION"
if (session.interacting == true)
output.print_line
end
# If logging had been enabled for this session, stop it now.
Msf::Logging::stop_session_log(session)
output.print_status("#{session.desc} session #{session.name} closed.")
end
end

View File

@ -4,68 +4,58 @@ module Gtk2
module Stream
class Console < MyGlade
require 'rex/io/bidirectional_pipe'
def initialize(session, buffer, pipe, input, output)
def initialize(session)
super('console2')
@textview.set_buffer(buffer)
@buffer = Gtk::TextBuffer.new
@textview.set_buffer(@buffer)
@textview.editable = false
@buffer = buffer
@textview.set_cursor_visible(false)
@buffer.create_mark('end_mark', @buffer.end_iter, false)
@session = session
@input = input
@output = output
@pipe = pipe
# Create a read subscriber
@pipe.create_subscriber(@session.sid)
# Create the pipe interface
@pipe = Rex::IO::BidirectionalPipe.new
@output.print_status("Session #{@session.sid} created, interacting")
@output.print_line("\n")
# Initialize the session
@session.init_ui(@pipe, @pipe)
@session.init_ui(@input, @output)
# One thread to interact
@t_mon = Thread.new do
@session.interact
# Start the session interaction
@t_run = Thread.new do
@session.interact()
end
# Another to monitor the output and update the UI
@t_rdr = Thread.new do
if (not @buffer.get_mark('end_mark'))
@buffer.create_mark('end_mark', @buffer.end_iter, false)
end
while(true)
data = @pipe.read_subscriber(@session.sid)
if (data and data.length > 0)
@buffer.insert(@buffer.end_iter, data)
@buffer.move_mark('end_mark', @buffer.end_iter)
@textview.scroll_mark_onscreen(@buffer.get_mark('end_mark'))
else
select(nil, nil, nil, 0.10)
end
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
if @console2.run == Gtk::Dialog::RESPONSE_OK
puts "ok"
@console2.destroy
end
# Kill off the helper threads
@t_rdr.kill
@t_mon.kill
update_access
# Run the console interface
res = @console2.run
# Kill the interaction thread
@t_run.kill
# Reset the session UI handles
@session.reset_ui
# Close the pipes
@pipe.close
# Determine how we were closed
case res
when Gtk::Dialog::RESPONSE_OK
$stderr.puts "ok"
else
end
@console2.destroy
end
#
@ -89,24 +79,26 @@ class Console < MyGlade
update_access
# Write the command plus a newline to the input
@input.put(cmd + "\n")
@pipe.write_input(cmd + "\n")
# Clear entry
# Clear the text entry
@cmd_entry.set_text("")
end
end
require 'rex/io/bidirectional_pipe'
class GtkConsolePipe < Rex::IO::BidirectionalPipe
attr_accessor :input
attr_accessor :output
attr_accessor :prompt
attr_accessor :killed
attr_accessor :buffer
attr_accessor :tree
def initialize(buffer)
@buffer = buffer
self.buffer = buffer
super()
end
@ -128,10 +120,15 @@ class GtkConsolePipe < Rex::IO::BidirectionalPipe
def pgets
self.pipe_input.gets
end
def print_line(msg = "")
@buffer.insert_at_cursor(msg + "\n")
print(msg + "\n")
end
def print(msg = "")
self.buffer.insert(self.buffer.end_iter, Time.now.strftime("%H:%m:%S") + " " + Rex::Text.to_utf8(msg))
end
end

View File

@ -4,13 +4,8 @@ module Gtk2
module Stream
class Session
def initialize(buffer, session_tree, options, session, pipe, input, output)
@session_tree = session_tree
@session = session
@session_tree.add_session(@session, options, buffer, pipe, input, output)
def initialize(session_tree, session)
session_tree.add_session(session)
end
end