74 lines
1.6 KiB
Ruby
74 lines
1.6 KiB
Ruby
# -*- coding: binary -*-
|
|
|
|
module Msf::Sessions
|
|
###
|
|
#
|
|
# This class provides basic interaction with a ChannelFD
|
|
# abstraction provided by the Rex::Proto::Ssh wrapper
|
|
# around HrrRbSsh.
|
|
#
|
|
# Date: June 22, 2019
|
|
# Author: RageLtMan
|
|
#
|
|
###
|
|
class SshCommandShellReverse < Msf::Sessions::CommandShell
|
|
|
|
#
|
|
# This interface supports basic interaction.
|
|
#
|
|
include Msf::Session::Basic
|
|
|
|
#
|
|
# This interface supports interacting with a single command shell.
|
|
#
|
|
include Msf::Session::Provider::SingleCommandShell
|
|
|
|
##
|
|
#
|
|
# Returns the session description.
|
|
#
|
|
def desc
|
|
'SSH command shell'
|
|
end
|
|
|
|
def shell_command(cmd)
|
|
# Send the command to the session's stdin.
|
|
shell_write(cmd + "\n")
|
|
|
|
timeo = 0.5
|
|
etime = ::Time.now.to_f + timeo
|
|
buff = ''
|
|
|
|
# Keep reading data until no more data is available or the timeout is
|
|
# reached.
|
|
while ((::Time.now.to_f < etime) && ::IO.select([rstream.fd_rd], nil, nil, timeo))
|
|
res = shell_read(-1, 0.01)
|
|
buff << res if res
|
|
timeo = etime - ::Time.now.to_f
|
|
end
|
|
|
|
buff
|
|
end
|
|
|
|
protected
|
|
|
|
def _interact_stream
|
|
fdr = [rstream.fd_rd, user_input.fd]
|
|
fdw = [rstream.fd_wr, user_input.fd]
|
|
while interacting
|
|
sd = Rex::ThreadSafe.select(fdr, nil, fdw, 0.5)
|
|
next unless sd
|
|
|
|
if sd[0].include? rstream.fd_rd
|
|
user_output.print(shell_read)
|
|
end
|
|
if sd[0].include? user_input.fd
|
|
run_single((user_input.gets || '').chomp("\n"))
|
|
end
|
|
Thread.pass
|
|
end
|
|
end
|
|
|
|
end
|
|
end
|