Skip to content

Commit

Permalink
adds cmd_shell initial output reading to bootstrap
Browse files Browse the repository at this point in the history
  • Loading branch information
agalway-r7 committed Sep 7, 2021
1 parent 3b59829 commit e99c229
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 15 deletions.
1 change: 1 addition & 0 deletions lib/msf/base/serializer/readable_text.rb
Original file line number Diff line number Diff line change
Expand Up @@ -844,6 +844,7 @@ def self.create_msf_session_row(session, show_extended)
end

sinfo = session.info.to_s
sinfo = sinfo.gsub(/[\r\n\t]+/, ' ')
# Arbitrarily cut info at 80 columns
if sinfo.length > 80
sinfo = "#{sinfo[0,77]}..."
Expand Down
46 changes: 32 additions & 14 deletions lib/msf/base/sessions/command_shell.rb
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,27 @@ def bootstrap(datastore = {}, handler = nil)
session = self

if datastore['AutoVerifySession']
session_info = ''

# Read the initial output and mash it into a single line
# Timeout set to 1 to read in banner and shell prompt of all payload responses
# Encoding is not forced to support non ASCII shells
if session.info.nil? or session.info.empty?
banner = shell_read(-1, 1)
if banner && !banner.empty?
banner.gsub!(/[\x00-\x08\x0b\x0c\x0e-\x19\x7f-\xff]+/n, "_")
banner.strip!

banner = """
Shell Banner:
#{banner}
-----
"""

session_info = banner
end
end

token = Rex::Text.rand_text_alphanumeric(8..24)
response = shell_command("echo #{token}", 3)
unless response&.include?(token)
Expand All @@ -100,6 +121,10 @@ def bootstrap(datastore = {}, handler = nil)
session.kill
return nil
end

# Only populate +session.info+ with a captured banner if the shell is responsive and verified
session.info = session_info
session
end
end

Expand Down Expand Up @@ -729,20 +754,6 @@ def cleanup
# Execute any specified auto-run scripts for this session
#
def process_autoruns(datastore)
# Read the initial output and mash it into a single line
if (not self.info or self.info.empty?)
initial_output = shell_read(-1, 0.01)
if (initial_output)
initial_output.force_encoding("ASCII-8BIT") if initial_output.respond_to?(:force_encoding)
initial_output.gsub!(/[\x00-\x08\x0b\x0c\x0e-\x19\x7f-\xff]+/n,"_")
initial_output.gsub!(/[\r\n\t]+/, ' ')
initial_output.strip!

# Set the inital output to .info
self.info = initial_output
end
end

if datastore['InitialAutoRunScript'] && !datastore['InitialAutoRunScript'].empty?
args = Shellwords.shellwords( datastore['InitialAutoRunScript'] )
print_status("Session ID #{sid} (#{tunnel_to_s}) processing InitialAutoRunScript '#{datastore['InitialAutoRunScript']}'")
Expand Down Expand Up @@ -779,6 +790,13 @@ def _interact
#
def _interact_stream
fds = [rstream.fd, user_input.fd]

# Displays +info+ on all session startups
# +info+ is set to the shell banner and initial prompt in the +bootstrap+ method
user_output.print("#{self.info}\n") if (self.info && !self.info.empty?) && self.interacting

run_single(('').chomp("\n"))

while self.interacting
sd = Rex::ThreadSafe.select(fds, nil, fds, 0.5)
next unless sd
Expand Down
6 changes: 5 additions & 1 deletion lib/msf/base/sessions/encrypted_shell.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def self.type
self.class.type = "Encrypted"
end

def process_autoruns(datastore)
def bootstrap(datastore = {}, handler = nil)
@key = datastore[:key] || datastore['ChachaKey']
nonce = datastore[:nonce] || datastore['ChachaNonce']
@iv = nonce
Expand Down Expand Up @@ -70,6 +70,8 @@ def process_autoruns(datastore)
@key = new_key
@iv = new_nonce
@chacha_cipher.reset_cipher(@key, @iv)

super(datastore, handler)
end

##
Expand All @@ -79,6 +81,8 @@ def process_autoruns(datastore)
#
def shell_read(length=-1, timeout=1)
rv = rstream.get_once(length, timeout)
# Needed to avoid crashing the +chacha20_crypt+ method
return nil unless rv
decrypted = @chacha_cipher.chacha20_crypt(rv)
framework.events.on_session_output(self, decrypted) if decrypted

Expand Down

0 comments on commit e99c229

Please sign in to comment.