Class: Ronin::PostEx::Sessions::ShellSession
- Defined in:
- lib/ronin/post_ex/sessions/shell_session.rb
Overview
Base class for all interactive shell based post-exploitation sessions.
Features
- Supports Bash, Zsh, and all POSIX shells.
- Emulates most of the post-exploitation API via shell commands.
Direct Known Subclasses
Shell Methods collapse
- DELIMINATOR =
Deliminator line to indicate the beginning and end of output
'---'
Instance Attribute Summary collapse
-
#io ⇒ Socket, IO
readonly
private
The IO object used to communicate with the shell.
Shell Methods collapse
-
#command_exec(command, *arguments) ⇒ String?
private
Invokes a specific command with arguments.
-
#command_join(command, *arguments) ⇒ String
private
Joins a command with arguments into a single command String.
-
#shell_exec(command) ⇒ String
Executes a shell command and returns it's output.
-
#shell_gets ⇒ String?
private
Reads a line from the shell.
-
#shell_puts(line) ⇒ Object
private
Writes a line to the shell.
System Methods collapse
-
#sys_hostname ⇒ String
Gets the system's hostname.
-
#sys_time ⇒ Integer
Gets the current time and returns the UNIX timestamp.
File-System methods collapse
-
#fs_chdir(path) ⇒ Object
Changes the current working directory.
-
#fs_chgrp(group, path) ⇒ Object
Changes the group ownership of a remote file or directory.
-
#fs_chmod(mode, path) ⇒ Object
Changes the permissions on a remote file or directory.
-
#fs_chown(user, path) ⇒ Object
Changes the user ownership of remote a file or directory.
-
#fs_copy(path, new_path) ⇒ Object
Copies a source file to the destination path.
-
#fs_getcwd ⇒ String
Gets the current working directory and returns the directory path.
-
#fs_glob(pattern, &block) ⇒ Array<String>
Evaluates a directory glob pattern and returns all matching paths.
-
#fs_link(src, dest) ⇒ Object
Creates a remote symbolic link at the destination path pointing to the source path.
-
#fs_mkdir(new_path) ⇒ Object
Creates a new remote directory at the given path.
-
#fs_mktemp(basename) ⇒ String
Creates a remote temporary file with the given file basename.
-
#fs_move(path, new_path) ⇒ Object
Moves or renames a remote source file to a new destination path.
-
#fs_readdir(path) ⇒ Array<String>
Reads the contents of a remote directory and returns an Array of directory entry names.
-
#fs_readfile(path) ⇒ String?
Reads the entire file at the given path and returns the full file's contents.
-
#fs_readlink(path) ⇒ String?
Reads the destination path of a remote symbolic link.
-
#fs_rmdir(path) ⇒ Object
Removes an empty directory at the given path.
-
#fs_stat(path) ⇒ Hash{Symbol => Object}?
Queries file information for the given remote path and returns a Hash of file metadata.
-
#fs_unlink(path) ⇒ Object
Removes a file at the given path.
Process methods collapse
-
#close ⇒ Object
Closes the remote shell.
-
#process_environ ⇒ Hash{String => String}
Queries all environment variables of the current process.
-
#process_exit ⇒ Object
Exits the current process.
-
#process_getenv(name) ⇒ String
Gets an individual environment variable.
-
#process_getgid ⇒ Integer
Gets the current process's group ID (GID).
-
#process_getpid ⇒ Integer
Gets the current process's Process ID (PID).
-
#process_getppid ⇒ Integer
Gets the current process's parent Process ID (PPID).
-
#process_getuid ⇒ Integer
Gets the current process's user ID (UID).
-
#process_kill(pid, signal) ⇒ Object
Kills another process using the given Process ID (POD) and the signal number.
-
#process_setenv(name, value) ⇒ Object
Sets an environment variable to the given value.
-
#process_spawn(command, *arguments) ⇒ Integer
Spawns a new process using the given program and additional arguments.
-
#process_unsetenv(name) ⇒ Object
Un-sets an environment variable.
Instance Method Summary collapse
-
#initialize(io) ⇒ ShellSession
constructor
Initializes the shell session.
Methods inherited from Session
Constructor Details
#initialize(io) ⇒ ShellSession
Initializes the shell session.
52 53 54 |
# File 'lib/ronin/post_ex/sessions/shell_session.rb', line 52 def initialize(io) @io = io end |
Instance Attribute Details
#io ⇒ Socket, IO (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
The IO object used to communicate with the shell.
44 45 46 |
# File 'lib/ronin/post_ex/sessions/shell_session.rb', line 44 def io @io end |
Instance Method Details
#close ⇒ Object
Closes the remote shell.
611 612 613 |
# File 'lib/ronin/post_ex/sessions/shell_session.rb', line 611 def close @io.close end |
#command_exec(command, *arguments) ⇒ String?
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Invokes a specific command with arguments.
150 151 152 153 154 155 156 |
# File 'lib/ronin/post_ex/sessions/shell_session.rb', line 150 def command_exec(command,*arguments) output = shell_exec(command_join(command,*arguments)) if output.empty? then nil else output end end |
#command_join(command, *arguments) ⇒ String
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Joins a command with arguments into a single command String.
132 133 134 |
# File 'lib/ronin/post_ex/sessions/shell_session.rb', line 132 def command_join(command,*arguments) Shellwords.join([command,*arguments]) end |
#fs_chdir(path) ⇒ Object
executes the cd <path>
command.
Changes the current working directory.
209 210 211 |
# File 'lib/ronin/post_ex/sessions/shell_session.rb', line 209 def fs_chdir(path) shell_puts("cd #{Shellwords.escape(path)} 2>/dev/null") end |
#fs_chgrp(group, path) ⇒ Object
executes the chgrp <group> <path>
command.
Changes the group ownership of a remote file or directory.
385 386 387 |
# File 'lib/ronin/post_ex/sessions/shell_session.rb', line 385 def fs_chgrp(group,path) command_exec('chgrp',group,path) end |
#fs_chmod(mode, path) ⇒ Object
executes the chmod <umask> <path>
command.
Changes the permissions on a remote file or directory.
415 416 417 418 419 |
# File 'lib/ronin/post_ex/sessions/shell_session.rb', line 415 def fs_chmod(mode,path) umask = "%.4o" % mode command_exec('chmod',umask,path) end |
#fs_chown(user, path) ⇒ Object
executes the chown <user> <path>
command.
Changes the user ownership of remote a file or directory.
400 401 402 |
# File 'lib/ronin/post_ex/sessions/shell_session.rb', line 400 def fs_chown(user,path) command_exec('chown',user,path) end |
#fs_copy(path, new_path) ⇒ Object
executes the cp -r <path> <new_path>
command.
Copies a source file to the destination path.
315 316 317 |
# File 'lib/ronin/post_ex/sessions/shell_session.rb', line 315 def fs_copy(path,new_path) command_exec('cp','-r',path,new_path) end |
#fs_getcwd ⇒ String
executes the pwd
command.
Gets the current working directory and returns the directory path.
197 198 199 |
# File 'lib/ronin/post_ex/sessions/shell_session.rb', line 197 def fs_getcwd shell_exec('pwd').chomp end |
#fs_glob(pattern, &block) ⇒ Array<String>
executes the ls <pattern>
command.
Evaluates a directory glob pattern and returns all matching paths.
273 274 275 |
# File 'lib/ronin/post_ex/sessions/shell_session.rb', line 273 def fs_glob(pattern,&block) shell_exec("ls #{pattern}").lines(chomp: true) end |
#fs_link(src, dest) ⇒ Object
executes the ln -s <src> <dest>
command.
Creates a remote symbolic link at the destination path pointing to the source path.
370 371 372 |
# File 'lib/ronin/post_ex/sessions/shell_session.rb', line 370 def fs_link(src,dest) command_exec('ln','-s',src,dest) end |
#fs_mkdir(new_path) ⇒ Object
executes the mkdir <path>
command.
Creates a new remote directory at the given path.
300 301 302 |
# File 'lib/ronin/post_ex/sessions/shell_session.rb', line 300 def fs_mkdir(new_path) command_exec('mkdir',new_path) end |
#fs_mktemp(basename) ⇒ String
executes the mktemp <basename>
command.
Creates a remote temporary file with the given file basename.
288 289 290 |
# File 'lib/ronin/post_ex/sessions/shell_session.rb', line 288 def fs_mktemp(basename) command_exec('mktemp',basename).chomp end |
#fs_move(path, new_path) ⇒ Object
executes the mv <path> <new_path>
command.
Moves or renames a remote source file to a new destination path.
354 355 356 |
# File 'lib/ronin/post_ex/sessions/shell_session.rb', line 354 def fs_move(path,new_path) command_exec('mv',path,new_path) end |
#fs_readdir(path) ⇒ Array<String>
executes the ls <path>
command.
Reads the contents of a remote directory and returns an Array of directory entry names.
258 259 260 |
# File 'lib/ronin/post_ex/sessions/shell_session.rb', line 258 def fs_readdir(path) command_exec('ls',path).lines(chomp: true) end |
#fs_readfile(path) ⇒ String?
executes the cat <path>
command.
Reads the entire file at the given path and returns the full file's contents.
226 227 228 |
# File 'lib/ronin/post_ex/sessions/shell_session.rb', line 226 def fs_readfile(path) command_exec('cat',path) end |
#fs_readlink(path) ⇒ String?
executes the readlink -f <path>
command.
Reads the destination path of a remote symbolic link.
242 243 244 |
# File 'lib/ronin/post_ex/sessions/shell_session.rb', line 242 def fs_readlink(path) command_exec('readlink','-f',path).chomp end |
#fs_rmdir(path) ⇒ Object
executes the rmdir <path>
command.
Removes an empty directory at the given path.
339 340 341 |
# File 'lib/ronin/post_ex/sessions/shell_session.rb', line 339 def fs_rmdir(path) command_exec('rmdir',path) end |
#fs_stat(path) ⇒ Hash{Symbol => Object}?
executes the stat -t <path>
command.
Queries file information for the given remote path and returns a Hash of file metadata.
433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 |
# File 'lib/ronin/post_ex/sessions/shell_session.rb', line 433 def fs_stat(path) fields = command_exec('stat','-t',path).strip.split(' ') return { path: path, size: fields[1].to_i, blocks: fields[2].to_i, uid: fields[4].to_i, gid: fields[5].to_i, inode: fields[7].to_i, links: fields[8].to_i, atime: Time.at(fields[11].to_i), mtime: Time.at(fields[12].to_i), ctime: Time.at(fields[13].to_i), blocksize: fields[14].to_i } end |
#fs_unlink(path) ⇒ Object
executes the rm <path>
command.
Removes a file at the given path.
327 328 329 |
# File 'lib/ronin/post_ex/sessions/shell_session.rb', line 327 def fs_unlink(path) command_exec('rm',path) end |
#process_environ ⇒ Hash{String => String}
executes the env
command.
Queries all environment variables of the current process. Returns a Hash of the env variable names and values.
512 513 514 515 516 |
# File 'lib/ronin/post_ex/sessions/shell_session.rb', line 512 def process_environ Hash[command_exec('env').each_line(chomp: true).map { |line| line.split('=',2) }] end |
#process_exit ⇒ Object
executes the exit
command.
Exits the current process.
604 605 606 |
# File 'lib/ronin/post_ex/sessions/shell_session.rb', line 604 def process_exit shell_puts('exit') end |
#process_getenv(name) ⇒ String
executes the echo $<name>
command.
Gets an individual environment variable. If the environment variable
has not been set, nil
will be returned.
530 531 532 |
# File 'lib/ronin/post_ex/sessions/shell_session.rb', line 530 def process_getenv(name) shell_exec("echo $#{name}").chomp end |
#process_getgid ⇒ Integer
executes the id -g
command.
Gets the current process's group ID (GID).
499 500 501 |
# File 'lib/ronin/post_ex/sessions/shell_session.rb', line 499 def process_getgid command_exec('id','-g').to_i end |
#process_getpid ⇒ Integer
executes the echo $$
command.
Gets the current process's Process ID (PID).
463 464 465 |
# File 'lib/ronin/post_ex/sessions/shell_session.rb', line 463 def process_getpid shell_exec('echo $$').to_i end |
#process_getppid ⇒ Integer
executes the echo $PPID
command.
Gets the current process's parent Process ID (PPID).
475 476 477 |
# File 'lib/ronin/post_ex/sessions/shell_session.rb', line 475 def process_getppid shell_exec('echo $PPID').to_i end |
#process_getuid ⇒ Integer
executes the id -u
command.
Gets the current process's user ID (UID).
487 488 489 |
# File 'lib/ronin/post_ex/sessions/shell_session.rb', line 487 def process_getuid command_exec('id','-u').to_i end |
#process_kill(pid, signal) ⇒ Object
executes the kill -s <signal> <pid>
command.
Kills another process using the given Process ID (POD) and the signal number.
573 574 575 |
# File 'lib/ronin/post_ex/sessions/shell_session.rb', line 573 def process_kill(pid,signal) command_exec('kill','-s',signal,pid) end |
#process_setenv(name, value) ⇒ Object
executes the export <name>=<value>
command.
Sets an environment variable to the given value.
545 546 547 |
# File 'lib/ronin/post_ex/sessions/shell_session.rb', line 545 def process_setenv(name,value) shell_puts("export #{name}=#{value}") end |
#process_spawn(command, *arguments) ⇒ Integer
executes the command with additional arguments as a background process.
Spawns a new process using the given program and additional arguments.
593 594 595 596 597 |
# File 'lib/ronin/post_ex/sessions/shell_session.rb', line 593 def process_spawn(command,*arguments) command = command_join(command,*arguments) shell_exec("#{command} 2>&1 >/dev/null &; echo $!").to_i end |
#process_unsetenv(name) ⇒ Object
executes the unset <name>
command.
Un-sets an environment variable.
557 558 559 |
# File 'lib/ronin/post_ex/sessions/shell_session.rb', line 557 def process_unsetenv(name) shell_puts("unset #{name}") end |
#shell_exec(command) ⇒ String
Executes a shell command and returns it's output.
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/ronin/post_ex/sessions/shell_session.rb', line 95 def shell_exec(command) shell_puts("echo #{DELIMINATOR}; #{command} 2>/dev/null | base64; echo #{DELIMINATOR}") # consume any leading output before the command output while (line = shell_gets) if line.chomp == DELIMINATOR break end end output = String.new while (line = shell_gets) if line.chomp == DELIMINATOR break end output << line end return Base64.decode64(output) end |
#shell_gets ⇒ String?
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Reads a line from the shell.
79 80 81 |
# File 'lib/ronin/post_ex/sessions/shell_session.rb', line 79 def shell_gets @io.gets end |
#shell_puts(line) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Writes a line to the shell.
68 69 70 |
# File 'lib/ronin/post_ex/sessions/shell_session.rb', line 68 def shell_puts(line) @io.write("#{line}\n") end |
#sys_hostname ⇒ String
executes the echo $HOSTNAME
command.
Gets the system's hostname.
181 182 183 |
# File 'lib/ronin/post_ex/sessions/shell_session.rb', line 181 def sys_hostname shell_exec("echo $HOSTNAME").chomp end |
#sys_time ⇒ Integer
executes the date +%s
command.
Gets the current time and returns the UNIX timestamp.
170 171 172 |
# File 'lib/ronin/post_ex/sessions/shell_session.rb', line 170 def sys_time shell_exec('date +%s').to_i end |