# frozen_string_literal: true # # ronin-post_ex - a Ruby API for Post-Exploitation. # # Copyright (c) 2007-2023 Hal Brodigan (postmodern.mod3 at gmail.com) # # ronin-post_ex is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published # by the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # ronin-post_ex is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with ronin-post_ex. If not, see . # require 'ronin/post_ex/resource' require 'ronin/post_ex/remote_process' require 'time' module Ronin module PostEx class System < Resource # # Provides access to the current process and managing child processes. # # # Supported Control Methods # # The Process resource uses the following post-exploitation API methods, # defined by the {#session} object. # # * `process_getpid -> Integer` # * `process_getppid -> Integer` # * `process_getuid -> Integer` # * `process_setuid(uid : Integer)` # * `process_geteuid -> Integer` # * `process_seteuid(euid : Integer)` # * `process_getgid -> Integer` # * `process_setgid(gid : Integer)` # * `process_getegid -> Integer` # * `process_setegid(egid : Integer)` # * `process_getsid -> Integer` # * `process_setsid(sid : Integer) -> Integer` # * `process_environ -> Hash[String, String]` # * `process_getenv(name : String) -> String | env` # * `process_setenv(name : String, value : String)` # * `process_unsetenv(name : String)` # * `process_kill(pid : Integer, signal : Integer)` # * `process_popen(command : String) -> Integer` # * `process_read(fd : Integer, length : Integer) -> String` # * `process_write(fd : Integer, data : String)` # * `process_close(fd : Integer)` # * `process_spawn(program : String, *arguments : Array[String]) -> Integer` # * `process_exit` # class Process < Resource # # Gets the pid of the current process. # # @return [Integer] # The current PID. # # @note # Requires the `process_getpid` method be defined by the {#session} # object. # def getpid @session.process_getpid end resource_method :pid, [:process_getpid] alias pid getpid # # Gets the pid of the parent process. # # @return [Integer] # The parent PID. # # @note # Requires the `process_getppid` method be defined by the {#session} # object. # def getppid @session.process_getppid end resource_method :ppid, [:process_getppid] alias ppid getppid # # Gets the UID that the current process is running under. # # @return [Integer] # The current UID. # # @note # Requires the `process_getuid` method be defined by the {#session} # object. # def getuid @session.process_getuid end resource_method :uid, [:process_getuid] alias uid getuid # # Attempts to set the UID of the current process. # # @param [Integer] new_uid # The new UID. # # @note # Requires the `process_setuid` method be defined by the {#session} # object. # def setuid(new_uid) @session.process_setuid(new_uid) end resource_method :uid=, [:process_setuid] alias uid= setuid # # Gets the effective UID that the current process is running under. # # @return [Integer] # The effective UID. # # @note # Requires the `process_geteuid` method be defined by the {#session} # object. # def geteuid @session.process_geteuid end resource_method :euid, [:process_geteuid] alias euid geteuid # # Attempts to set the effective UID of the current process. # # @param [Integer] new_euid # The new effective UID. # # @note # Requires the `process_seteuid` method be defined by the {#session} # object. # def seteuid(new_euid) @session.process_seteuid(new_euid) end resource_method :euid=, [:process_seteuid] alias euid= seteuid # # Gets the GID that the current process is running under. # # @return [Integer] # The current GID. # # @note # Requires the `process_getgid` method be defined by the {#session} # object. # def getgid @session.process_getgid end resource_method :gid, [:process_getgid] alias gid getgid # # Attempts to set the GID of the current process. # # @param [Integer] new_gid # The new GID. # # @note # Requires the `process_setgid` method be defined by the {#session} # object. # def setgid(new_gid) @session.process_setgid(new_gid) end resource_method :gid=, [:process_setgid] alias gid= setgid # # Gets the effective GID that the current process is running under. # # @return [Integer] # The effective GID. # # @note # Requires the `process_getegid` method be defined by the {#session} # object. # def getegid @session.process_getegid end resource_method :egid, [:process_getegid] alias egid getegid # # Attempts to set the effective GID of the current process. # # @param [Integer] new_egid # The new effective GID. # # @note # Requires the `process_setegid` method be defined by the {#session} # object. # def setegid(new_egid) @session.process_setegid(new_egid) end resource_method :egid=, [:process_setegid] alias egid= setegid # # Gets the SID of the current process. # # @return [Integer] # The current SID. # # @note # Requires the `process_getsid` method be defined by the {#session} # object. # def getsid @session.process_getsid end resource_method :sid, [:process_getsid] alias sid getsid # # Sets the SID of the current process. # # @note # Requires the `process_setsid` method be defined by the {#session} # object. # def setsid @session.process_setsid end resource_method :setsid, [:process_setsid] alias sid! setsid # # Retrieves the whole environment Hash. # # @return [Hash{String => String}] # The Hash of environment variables. # # @note # Requires the `process_environ` method be defined by the {#session} # object. # # @api public # def environ @session.process_environ end resource_method :environ, [:process_environ] alias env environ # # Retrieves the value of a environment variable. # # @param [String] name # The name of the environment variable. # # @return [String, nil] # The value of the environment variable. # # @note # Requires `process_getenv` or `process_environ` methods be defined by # the {#session} object. # # @api public # def getenv(name) if @session.respond_to?(:process_getenv) @session.process_getenv(name) elsif @session.respond_to?(:process_environ) @session.process_environ[name] else raise(NoMethodError,"#{@session} does not define process_getenv or process_environ") end end resource_method :getenv, [:process_getenv] # # Sets the value of a environment variable. # # @param [String] name # The name of the environment variable. # # @param [String] value # The new value for the environment variable. # # @note # Requires the `process_setenv` method be defined by the {#session} # object. # # @api public # def setenv(name,value) @session.process_setenv(name,value) end resource_method :setenv, [:process_setenv] # # Unsets an environment variable. # # @param [String] name # The name of the environment variable. # # @note # Requires the `process_unsetenv` method be defined by the {#session} # object. # # @api public # def unsetenv(name) @session.process_unsetenv(name) end resource_method :unsetenv, [:process_unsetenv] # # Kills a process. # # @param [Integer] pid # The PID of the process to kill. # # @param [String] signal # The POSIX signal name to send to the process. # # @note # Requires the `process_kill` method be defined by the {#session} # object. # def kill(pid,signal='KILL') @session.process_kill(pid,signal) end resource_method :kill, [:process_kill] # # Opens a new process. # # @param [String] command # The command string to execute. # # @return [RemoteProcess] # The newly opened remote process. # # @note # Requires the `process_popen` method be defined by the {#session} # object. # # @api public # def popen(command) RemoteProcess.new(@session,command) end resource_method :spawn, [:process_popen] # # Executes a program as a separate child process. # # @param [String] program # The name or path of the program. # # @param [Array] arguments # Additional arguments to execute the program with. # # @return [Integer] # The pid of the new process. # # @note # Requires the `process_spawn` method be defined by the {#session} # object. # # @api public # def spawn(program,*arguments) @session.process_spawn(program,*arguments) end resource_method :spawn, [:process_spawn] # # Exits the current running process. # # @note # Requires the `process_exit` method be defined by the {#session} # object. # def exit @session.process_exit end resource_method :exit, [:process_exit] end end end end