Module: Msf::Session::Provider::SingleCommandShell
- Included in:
- MultiCommandShell, Msf::Sessions::CommandShell, Msf::Sessions::EncryptedShell, Msf::Sessions::MainframeShell, Msf::Sessions::Meterpreter, Msf::Sessions::NetwareConsole, Msf::Sessions::SshCommandShell, Msf::Sessions::TTY
- Defined in:
- lib/msf/core/session/provider/single_command_shell.rb
Overview
This interface is to be implemented by a session that is only capable of providing an interface to a single command shell.
Instance Method Summary collapse
-
#set_shell_token_index(timeout) ⇒ Object
NOTE: if the session echoes input we don't need to echo the token twice.
-
#shell_close ⇒ Object
Closes the command shell.
- #shell_command_token(cmd, timeout = 10) ⇒ Object
-
#shell_command_token_unix(cmd, timeout = 10) ⇒ Object
Explicitly run a single command and return the output.
-
#shell_command_token_win32(cmd, timeout = 10) ⇒ Object
Explicitly run a single command and return the output.
-
#shell_init ⇒ Object
Initializes the command shell.
-
#shell_read(length = nil) ⇒ Object
Reads data from the command shell.
-
#shell_read_until_token(token, wanted_idx = 0, timeout = 10) ⇒ Object
Read data until we find the token.
-
#shell_write(buf) ⇒ Object
Writes data to the command shell.
Instance Method Details
#set_shell_token_index(timeout) ⇒ Object
NOTE: if the session echoes input we don't need to echo the token twice. This setting will persist for the duration of the session.
108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/msf/core/session/provider/single_command_shell.rb', line 108 def set_shell_token_index(timeout) return @shell_token_index if @shell_token_index token = ::Rex::Text.rand_text_alpha(32) numeric_token = rand(0xffffffff) + 1 cmd = "echo #{numeric_token}" shell_write(cmd + ";echo #{token}\n") res = shell_read_until_token(token, 0, timeout) if res.to_i == numeric_token @shell_token_index = 0 else @shell_token_index = 1 end end |
#shell_close ⇒ Object
Closes the command shell.
38 39 40 |
# File 'lib/msf/core/session/provider/single_command_shell.rb', line 38 def shell_close() raise NotImplementedError end |
#shell_command_token(cmd, timeout = 10) ⇒ Object
82 83 84 85 86 87 88 89 |
# File 'lib/msf/core/session/provider/single_command_shell.rb', line 82 def shell_command_token(cmd, timeout=10) if platform == 'windows' output = shell_command_token_win32(cmd, timeout) else output = shell_command_token_unix(cmd, timeout) end output end |
#shell_command_token_unix(cmd, timeout = 10) ⇒ Object
Explicitly run a single command and return the output. This version uses a marker to denote the end of data (instead of a timeout).
95 96 97 98 99 100 101 102 103 104 |
# File 'lib/msf/core/session/provider/single_command_shell.rb', line 95 def shell_command_token_unix(cmd, timeout=10) # read any pending data buf = shell_read(-1, 0.01) set_shell_token_index(timeout) token = ::Rex::Text.rand_text_alpha(32) # Send the command to the session's stdin. shell_write(cmd + ";echo #{token}\n") shell_read_until_token(token, @shell_token_index, timeout) end |
#shell_command_token_win32(cmd, timeout = 10) ⇒ Object
Explicitly run a single command and return the output. This version uses a marker to denote the end of data (instead of a timeout).
126 127 128 129 130 131 132 133 134 135 136 137 138 |
# File 'lib/msf/core/session/provider/single_command_shell.rb', line 126 def shell_command_token_win32(cmd, timeout=10) # read any pending data buf = shell_read(-1, 0.01) token = ::Rex::Text.rand_text_alpha(32) # Send the command to the session's stdin. # NOTE: if the session echoes input we don't need to echo the token twice. shell_write(cmd + "&echo #{token}\n") res = shell_read_until_token(token, 1, timeout) # I would like a better way to do this, but I don't know of one res.reverse!.chomp!.reverse! # the presence of a leading newline is not consistent res end |
#shell_init ⇒ Object
Initializes the command shell.
17 18 19 |
# File 'lib/msf/core/session/provider/single_command_shell.rb', line 17 def shell_init() raise NotImplementedError end |
#shell_read(length = nil) ⇒ Object
Reads data from the command shell.
24 25 26 |
# File 'lib/msf/core/session/provider/single_command_shell.rb', line 24 def shell_read(length = nil) raise NotImplementedError end |
#shell_read_until_token(token, wanted_idx = 0, timeout = 10) ⇒ Object
Read data until we find the token
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/msf/core/session/provider/single_command_shell.rb', line 45 def shell_read_until_token(token, wanted_idx=0, timeout=10) return if timeout.to_i == 0 if wanted_idx == 0 parts_needed = 2 else parts_needed = 1 + (wanted_idx * 2) end # Read until we get the data between two tokens or absolute timeout. begin ::Timeout.timeout(timeout) do buf = '' idx = nil loop do if (tmp = shell_read(-1)) buf << tmp # see if we have the wanted idx parts = buf.split(token, -1) if parts.length == parts_needed # cause another prompt to appear (just in case) shell_write("\n") return parts[wanted_idx] end end end end rescue # nothing, just continue end # failed to get any data or find the token! nil end |
#shell_write(buf) ⇒ Object
Writes data to the command shell.
31 32 33 |
# File 'lib/msf/core/session/provider/single_command_shell.rb', line 31 def shell_write(buf) raise NotImplementedError end |