Skip to content

Commit

Permalink
Avoid code duplication between interactive_shell_write and `meterpr…
Browse files Browse the repository at this point in the history
…eter_write` methods
  • Loading branch information
ekalinichev-r7 committed Mar 21, 2024
1 parent 3f3b903 commit 0399846
Showing 1 changed file with 25 additions and 28 deletions.
53 changes: 25 additions & 28 deletions lib/msf/core/rpc/v10/rpc_session.rb
Original file line number Diff line number Diff line change
Expand Up @@ -181,16 +181,7 @@ def rpc_interactive_shell_write(sid, data)
# and we don't know exact type of the session, so we just pass empty string
session = _valid_session(sid, '')

unless session.user_output.respond_to?(:dump_buffer)
session.init_ui(Rex::Ui::Text::Input::Buffer.new, Rex::Ui::Text::Output::Buffer.new)
end

if session.interacting
session.user_input.put(data + "\n")
else
framework.threads.spawn('InteractiveRunSingle', false, session) { |s| s.console.run_single(data) }
end
{ 'result' => 'success' }
_interactive_write(session)
end

# Reads the output from interactive session (such as a command output).
Expand Down Expand Up @@ -308,7 +299,6 @@ def rpc_ring_clear(sid)
{ "result" => "success" }
end


# Sends an input to a meterpreter prompt.
# You may want to use #rpc_meterpreter_read to retrieve the output.
#
Expand All @@ -325,26 +315,12 @@ def rpc_ring_clear(sid)
# @see #rpc_meterpreter_run_single
# @example Here's how you would use this from the client:
# rpc.call('session.meterpreter_write', 2, "sysinfo")
def rpc_meterpreter_write( sid, data)
s = _valid_session(sid,"meterpreter")

if not s.user_output.respond_to? :dump_buffer
s.init_ui(Rex::Ui::Text::Input::Buffer.new, Rex::Ui::Text::Output::Buffer.new)
end
def rpc_meterpreter_write(sid, data)
session = _valid_session(sid, 'meterpreter')

interacting = false
s.channels.each_value do |ch|
interacting ||= ch.respond_to?('interacting') && ch.interacting
end
if interacting
s.user_input.put(data + "\n")
else
self.framework.threads.spawn("MeterpreterRunSingle", false, s) { |sess| sess.console.run_single(data) }
end
{ "result" => "success" }
_interactive_write(session)
end


# Detaches from a meterpreter session. Serves the same purpose as [CTRL]+[Z].
#
# @param [Integer] sid Session ID.
Expand Down Expand Up @@ -559,6 +535,27 @@ def _interactive_read(session)
{ 'data' => data }
end

def _interactive_write(session)
unless session.user_output.respond_to? :dump_buffer
session.init_ui(Rex::Ui::Text::Input::Buffer.new, Rex::Ui::Text::Output::Buffer.new)
end

interacting = false
if session.respond_to? :channels
session.channels.each_value do |ch|
interacting ||= ch.respond_to?('interacting') && ch.interacting
end
end

if interacting
session.user_input.put(data + "\n")
else
framework.threads.spawn('InteractiveRunSingle', false, session) { |s| s.console.run_single(data) }
end

{ 'result' => 'success' }
end

end
end
end

0 comments on commit 0399846

Please sign in to comment.