CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/lib/rex/post/smb/ui/console.rb
Views: 11705
1
# -*- coding: binary -*-
2
3
require 'English'
4
require 'rex/post/session_compatible_modules'
5
6
module Rex
7
module Post
8
module SMB
9
module Ui
10
###
11
#
12
# This class provides a shell driven interface to the RubySMB client API.
13
#
14
###
15
class Console
16
17
include Rex::Ui::Text::DispatcherShell
18
include Rex::Post::SessionCompatibleModules
19
20
# Dispatchers
21
require 'rex/post/smb/ui/console/command_dispatcher'
22
require 'rex/post/smb/ui/console/command_dispatcher/core'
23
require 'rex/post/smb/ui/console/command_dispatcher/shares'
24
25
#
26
# Initialize the SMB console.
27
#
28
# @param [Msf::Sessions::SMB] session
29
def initialize(session)
30
if Rex::Compat.is_windows
31
super('smb')
32
else
33
super('%undSMB%clr', '>', Msf::Config.smb_session_history, nil, :smb)
34
end
35
36
# The ruby smb client context
37
self.session = session
38
self.client = session.client
39
self.simple_client = session.simple_client
40
41
# Queued commands array
42
self.commands = []
43
44
# Point the input/output handles elsewhere
45
reset_ui
46
47
enstack_dispatcher(Rex::Post::SMB::Ui::Console::CommandDispatcher::Core)
48
enstack_dispatcher(Rex::Post::SMB::Ui::Console::CommandDispatcher::Shares)
49
enstack_dispatcher(Msf::Ui::Console::CommandDispatcher::LocalFileSystem)
50
51
# Set up logging to whatever logsink 'core' is using
52
if !$dispatcher['smb']
53
$dispatcher['smb'] = $dispatcher['core']
54
end
55
end
56
57
#
58
# Called when someone wants to interact with the smb client. It's
59
# assumed that init_ui has been called prior.
60
#
61
def interact(&block)
62
# Run queued commands
63
commands.delete_if do |ent|
64
run_single(ent)
65
true
66
end
67
68
# Run the interactive loop
69
run do |line|
70
# Run the command
71
run_single(line)
72
73
# If a block was supplied, call it, otherwise return false
74
if block
75
block.call
76
else
77
false
78
end
79
end
80
end
81
82
#
83
# Queues a command to be run when the interactive loop is entered.
84
#
85
def queue_cmd(cmd)
86
commands << cmd
87
end
88
89
#
90
# Runs the specified command wrapper in something to catch meterpreter
91
# exceptions.
92
#
93
def run_command(dispatcher, method, arguments)
94
super
95
rescue Timeout::Error
96
log_error('Operation timed out.')
97
rescue Rex::InvalidDestination => e
98
log_error(e.message)
99
rescue ::Errno::EPIPE, ::OpenSSL::SSL::SSLError, ::IOError
100
session.kill
101
rescue ::RubySMB::Error::CommunicationError => e
102
log_error("Error running command #{method}: #{e.class} #{e}")
103
elog(e)
104
session.alive = false
105
rescue ::StandardError => e
106
log_error("Error running command #{method}: #{e.class} #{e}")
107
elog(e)
108
end
109
110
# @param [Hash] opts
111
# @return [String]
112
def help_to_s(opts = {})
113
super + format_session_compatible_modules
114
end
115
116
#
117
# Logs that an error occurred and persists the callstack.
118
#
119
def log_error(msg)
120
print_error(msg)
121
122
elog(msg, 'smb')
123
124
dlog("Call stack:\n#{$ERROR_POSITION.join("\n")}", 'smb')
125
end
126
127
# @return [Msf::Sessions::SMB]
128
attr_reader :session
129
130
# @return [RubySMB::Client]
131
attr_reader :client # :nodoc:
132
133
# @return [Rex::Proto::SMB::SimpleClient]
134
attr_reader :simple_client
135
136
# @return [RubySMB::SMB2::Tree]
137
attr_accessor :active_share
138
139
# @return [String]
140
attr_accessor :cwd
141
142
def format_prompt(val)
143
if active_share
144
share_name = active_share.share[/[^\\].*$/, 0]
145
cwd = self.cwd.blank? ? '' : "\\#{Rex::Ntpath.as_ntpath(self.cwd)}"
146
prompt = "#{share_name}#{cwd}"
147
else
148
prompt = session.address.to_s
149
end
150
151
substitute_colors("%undSMB%clr (#{prompt}) > ", true)
152
end
153
154
protected
155
156
attr_writer :session, :client, :simple_client # :nodoc: # :nodoc:
157
attr_accessor :commands # :nodoc:
158
end
159
end
160
end
161
end
162
end
163
164