Class: Rex::Post::SMB::Ui::Console

Inherits:
Object
  • Object
show all
Includes:
Rex::Post::SessionCompatibleModules, Ui::Text::DispatcherShell
Defined in:
lib/rex/post/smb/ui/console.rb

Overview

This class provides a shell driven interface to the RubySMB client API.

Defined Under Namespace

Modules: CommandDispatcher

Instance Attribute Summary collapse

Attributes included from Ui::Text::DispatcherShell

#blocked, #busy, #dispatcher_stack

Attributes included from Ui::Text::Shell

#cont_flag, #cont_prompt, #disable_output, #framework, #hist_last_saved, #histfile, #history_manager, #input, #local_hostname, #local_username, #log_source, #name, #on_command_proc, #on_print_proc, #output, #prompt, #prompt_char, #stop_count, #stop_flag, #tab_complete_proc

Instance Method Summary collapse

Methods included from Rex::Post::SessionCompatibleModules

#format_session_compatible_modules, #session_compatible_modules

Methods included from Ui::Text::DispatcherShell

#append_dispatcher, #block_command, #blocked_command?, #current_dispatcher, #destack_dispatcher, #enstack_dispatcher, #remove_dispatcher, #run_single, #shellsplitex, #tab_complete, #tab_complete_helper, #tab_complete_stub, #unblock_command, #unknown_command

Methods included from Ui::Text::Shell

#_print_prompt, #get_input_line, #init_tab_complete, #init_ui, #log_input, #log_output, #parse_line, #print, #print_error, #print_good, #print_line, #print_status, #print_warning, #prompt_yesno, #reset_ui, #run, #set_log_source, #stop, #stopped?, #supports_color?, #tab_complete, #unset_log_source, #update_prompt, #with_history_manager_context

Methods included from Ui::Text::Resource

#load_resource

Constructor Details

#initialize(session) ⇒ Console

Initialize the SMB console.

Parameters:



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/rex/post/smb/ui/console.rb', line 29

def initialize(session)
  if Rex::Compat.is_windows
    super('smb')
  else
    super('%undSMB%clr', '>', Msf::Config.smb_session_history, nil, :smb)
  end

  # The ruby smb client context
  self.session = session
  self.client = session.client
  self.simple_client = session.simple_client

  # Queued commands array
  self.commands = []

  # Point the input/output handles elsewhere
  reset_ui

  enstack_dispatcher(Rex::Post::SMB::Ui::Console::CommandDispatcher::Core)
  enstack_dispatcher(Rex::Post::SMB::Ui::Console::CommandDispatcher::Shares)
  enstack_dispatcher(Msf::Ui::Console::CommandDispatcher::LocalFileSystem)

  # Set up logging to whatever logsink 'core' is using
  if !$dispatcher['smb']
    $dispatcher['smb'] = $dispatcher['core']
  end
end

Instance Attribute Details

#active_shareRubySMB::SMB2::Tree

Returns:

  • (RubySMB::SMB2::Tree)


137
138
139
# File 'lib/rex/post/smb/ui/console.rb', line 137

def active_share
  @active_share
end

#clientRubySMB::Client

Returns:

  • (RubySMB::Client)


131
132
133
# File 'lib/rex/post/smb/ui/console.rb', line 131

def client
  @client
end

#commandsObject (protected)

:nodoc:



157
158
159
# File 'lib/rex/post/smb/ui/console.rb', line 157

def commands
  @commands
end

#cwdString

Returns:

  • (String)


140
141
142
# File 'lib/rex/post/smb/ui/console.rb', line 140

def cwd
  @cwd
end

#sessionMsf::Sessions::SMB

Returns:



128
129
130
# File 'lib/rex/post/smb/ui/console.rb', line 128

def session
  @session
end

#simple_clientRex::Proto::SMB::SimpleClient



134
135
136
# File 'lib/rex/post/smb/ui/console.rb', line 134

def simple_client
  @simple_client
end

Instance Method Details

#format_prompt(val) ⇒ Object



142
143
144
145
146
147
148
149
150
151
152
# File 'lib/rex/post/smb/ui/console.rb', line 142

def format_prompt(val)
  if active_share
    share_name = active_share.share[/[^\\].*$/, 0]
    cwd = self.cwd.blank? ? '' : "\\#{Rex::Ntpath.as_ntpath(self.cwd)}"
    prompt = "#{share_name}#{cwd}"
  else
    prompt = session.address.to_s
  end

  substitute_colors("%undSMB%clr (#{prompt}) > ", true)
end

#help_to_s(opts = {}) ⇒ String

Parameters:

  • opts (Hash) (defaults to: {})

Returns:

  • (String)


112
113
114
# File 'lib/rex/post/smb/ui/console.rb', line 112

def help_to_s(opts = {})
  super + format_session_compatible_modules
end

#interact(&block) ⇒ Object

Called when someone wants to interact with the smb client. It's assumed that init_ui has been called prior.



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/rex/post/smb/ui/console.rb', line 61

def interact(&block)
  # Run queued commands
  commands.delete_if do |ent|
    run_single(ent)
    true
  end

  # Run the interactive loop
  run do |line|
    # Run the command
    run_single(line)

    # If a block was supplied, call it, otherwise return false
    if block
      block.call
    else
      false
    end
  end
end

#log_error(msg) ⇒ Object

Logs that an error occurred and persists the callstack.



119
120
121
122
123
124
125
# File 'lib/rex/post/smb/ui/console.rb', line 119

def log_error(msg)
  print_error(msg)

  elog(msg, 'smb')

  dlog("Call stack:\n#{$ERROR_POSITION.join("\n")}", 'smb')
end

#queue_cmd(cmd) ⇒ Object

Queues a command to be run when the interactive loop is entered.



85
86
87
# File 'lib/rex/post/smb/ui/console.rb', line 85

def queue_cmd(cmd)
  commands << cmd
end

#run_command(dispatcher, method, arguments) ⇒ Object

Runs the specified command wrapper in something to catch meterpreter exceptions.



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/rex/post/smb/ui/console.rb', line 93

def run_command(dispatcher, method, arguments)
  super
rescue Timeout::Error
  log_error('Operation timed out.')
rescue Rex::InvalidDestination => e
  log_error(e.message)
rescue ::Errno::EPIPE, ::OpenSSL::SSL::SSLError, ::IOError
  session.kill
rescue ::RubySMB::Error::CommunicationError => e
  log_error("Error running command #{method}: #{e.class} #{e}")
  elog(e)
  session.alive = false
rescue ::StandardError => e
  log_error("Error running command #{method}: #{e.class} #{e}")
  elog(e)
end