From b6d64b770a1dd20d318dd4530e2924d701032fa8 Mon Sep 17 00:00:00 2001 From: Stephen Haywood Date: Thu, 23 Aug 2012 23:57:55 -0400 Subject: [PATCH] Adding documentation to the post modules library. --- lib/msf/core/post/common.rb | 4 + lib/msf/core/post/file.rb | 12 +- lib/msf/core/post/linux/priv.rb | 2 + lib/msf/core/post/linux/system.rb | 5 +- lib/msf/core/post/osx/system.rb | 160 +++++++++++++----------- lib/msf/core/post/solaris/priv.rb | 18 +-- lib/msf/core/post/solaris/system.rb | 1 - lib/msf/core/post/unix.rb | 8 +- lib/msf/core/post/windows/eventlog.rb | 10 +- lib/msf/core/post/windows/powershell.rb | 39 +++++- lib/msf/core/post/windows/railgun.rb | 9 ++ lib/msf/core/post/windows/registry.rb | 70 ++++++++++- 12 files changed, 241 insertions(+), 97 deletions(-) diff --git a/lib/msf/core/post/common.rb b/lib/msf/core/post/common.rb index aa379f66d3..3a763f6c4d 100644 --- a/lib/msf/core/post/common.rb +++ b/lib/msf/core/post/common.rb @@ -80,6 +80,10 @@ module Common return o end + # + # Reports to the database that the host is a virtual machine and reports + # the type of virtual machine it is (e.g VirtualBox, VMware, Xen) + # def report_vm(vm) return unless session return unless vm diff --git a/lib/msf/core/post/file.rb b/lib/msf/core/post/file.rb index 6f0364e43f..c931e51f0d 100644 --- a/lib/msf/core/post/file.rb +++ b/lib/msf/core/post/file.rb @@ -2,6 +2,9 @@ module Msf::Post::File + # + # Change directory in the remote session to +path+ + # def cd(path) if session.type == "meterpreter" e_path = session.fs.file.expand_path(path) rescue path @@ -11,6 +14,9 @@ module Msf::Post::File end end + # + # Returns the current working directory in the remote session + # def pwd if session.type == "meterpreter" return session.fs.dir.getwd @@ -110,7 +116,7 @@ module Msf::Post::File end # - # Writes a given string to a file specified + # Writes a given string to a given local file # def file_local_write(file2wrt, data2wrt) if not ::File.exists?(file2wrt) @@ -141,7 +147,6 @@ module Msf::Post::File # # Returns a MD5 checksum of a given remote file # - def file_remote_digestmd5(file2md5) data = read_file(file2md5) chksum = nil @@ -266,7 +271,8 @@ module Msf::Post::File end # - # Read a local file and write it to the remote file system + # Read a local file +local+ and write it as +remote+ on the remote file + # system # def upload_file(remote, local) write_file(remote, ::File.read(local)) diff --git a/lib/msf/core/post/linux/priv.rb b/lib/msf/core/post/linux/priv.rb index 78f9c04015..9034b008ec 100644 --- a/lib/msf/core/post/linux/priv.rb +++ b/lib/msf/core/post/linux/priv.rb @@ -7,7 +7,9 @@ module Linux module Priv include ::Msf::Post::Common + # # Returns true if running as root, false if not. + # def is_root? root_priv = false user_id = cmd_exec("id -u") diff --git a/lib/msf/core/post/linux/system.rb b/lib/msf/core/post/linux/system.rb index b1f267e718..8923db2bfd 100644 --- a/lib/msf/core/post/linux/system.rb +++ b/lib/msf/core/post/linux/system.rb @@ -9,10 +9,11 @@ module Linux module System include ::Msf::Post::Common include ::Msf::Post::File - include ::Msf::Post::Unix + # # Returns a Hash containing Distribution Name, Version and Kernel Information + # def get_sysinfo system_data = {} etc_files = cmd_exec("ls /etc").split() @@ -97,6 +98,6 @@ module System end # System -end #Linux +end # Linux end # Post end # Msf diff --git a/lib/msf/core/post/osx/system.rb b/lib/msf/core/post/osx/system.rb index 5d96a8a5ec..e96aff2f58 100644 --- a/lib/msf/core/post/osx/system.rb +++ b/lib/msf/core/post/osx/system.rb @@ -7,97 +7,107 @@ class Post module OSX module System include ::Msf::Post::Common - include ::Msf::Post::File + include ::Msf::Post::File - # Return a hash with system Information - def get_sysinfo - system_info = {} - cmd_output = cmd_exec("/usr/bin/sw_vers").split("\n") - cmd_output.each do |l| - field,val = l.chomp.split(":") - system_info[field] = val.strip - end - system_info["Kernel"] = cmd_exec("uname -a") - system_info["Hostname"] = system_info["Kernel"].split(" ")[1] - - return system_info + # + # Return a hash with system Information + # + def get_sysinfo + system_info = {} + cmd_output = cmd_exec("/usr/bin/sw_vers").split("\n") + cmd_output.each do |l| + field,val = l.chomp.split(":") + system_info[field] = val.strip end + system_info["Kernel"] = cmd_exec("uname -a") + system_info["Hostname"] = system_info["Kernel"].split(" ")[1] - # Returns an array of hashes each representing a user on the system - # Keys are name, gid, uid, dir and shell - def get_users - cmd_output = cmd_exec("/usr/bin/dscacheutil -q user") - users = [] - users_arry = cmd_output.split("\n\n") - users_arry.each do |u| - entry = Hash.new - u.each_line do |l| - field,val = l.chomp.split(": ") - next if field == "password" - entry[field] = val.chomp + return system_info + end + + # + # Returns an array of hashes each representing a user on the system + # Keys are name, gid, uid, dir and shell + # + def get_users + cmd_output = cmd_exec("/usr/bin/dscacheutil -q user") + users = [] + users_arry = cmd_output.split("\n\n") + users_arry.each do |u| + entry = Hash.new + u.each_line do |l| + field,val = l.chomp.split(": ") + next if field == "password" + entry[field] = val.chomp - end - users << entry end - return users + users << entry end + return users + end - # Returns an array of hashes each representing a system accounts on the system - # Keys are name, gid, uid, dir and shell - def get_system_accounts - cmd_output = cmd_exec("/usr/bin/dscacheutil -q user") - users = [] - users_arry = cmd_output.split("\n\n") - users_arry.each do |u| - entry = {} - u.each_line do |l| - field,val = l.chomp.split(": ") - next if field == "password" - entry[field] = val.chomp - end - next if entry["name"] !~ /^_/ - users << entry + # + # Returns an array of hashes each representing a system accounts on the system + # Keys are name, gid, uid, dir and shell + # + def get_system_accounts + cmd_output = cmd_exec("/usr/bin/dscacheutil -q user") + users = [] + users_arry = cmd_output.split("\n\n") + users_arry.each do |u| + entry = {} + u.each_line do |l| + field,val = l.chomp.split(": ") + next if field == "password" + entry[field] = val.chomp end - return users + next if entry["name"] !~ /^_/ + users << entry end + return users + end - # Returns an array of hashes each representing non system accounts on the system - # Keys are name, gid, uid, dir and shell - def get_nonsystem_accounts - cmd_output = cmd_exec("/usr/bin/dscacheutil -q user") - users = [] - users_arry = cmd_output.split("\n\n") - users_arry.each do |u| - entry = {} - u.each_line do |l| - field,val = l.chomp.split(": ") - next if field == "password" - entry[field] = val.chomp - end - next if entry["name"] =~ /^_/ - users << entry + # + # Returns an array of hashes each representing non system accounts on the system + # Keys are name, gid, uid, dir and shell + # + def get_nonsystem_accounts + cmd_output = cmd_exec("/usr/bin/dscacheutil -q user") + users = [] + users_arry = cmd_output.split("\n\n") + users_arry.each do |u| + entry = {} + u.each_line do |l| + field,val = l.chomp.split(": ") + next if field == "password" + entry[field] = val.chomp end - return users + next if entry["name"] =~ /^_/ + users << entry end + return users + end - # Returns an array of hashes each representing user group on the system - # Keys are name, guid and users - def get_groups - cmd_output = cmd_exec("/usr/bin/dscacheutil -q group") - groups = [] - groups_arry = cmd_output.split("\n\n") - groups_arry.each do |u| - entry = Hash.new - u.each_line do |l| - field,val = l.chomp.split(": ") - next if field == "password" - entry[field] = val.chomp + # + # Returns an array of hashes each representing user group on the system + # Keys are name, guid and users + # + def get_groups + cmd_output = cmd_exec("/usr/bin/dscacheutil -q group") + groups = [] + groups_arry = cmd_output.split("\n\n") + groups_arry.each do |u| + entry = Hash.new + u.each_line do |l| + field,val = l.chomp.split(": ") + next if field == "password" + entry[field] = val.chomp - end - groups << entry end - return groups + groups << entry end + return groups + end end # System end # OSX end # Post diff --git a/lib/msf/core/post/solaris/priv.rb b/lib/msf/core/post/solaris/priv.rb index 80ceaee439..ffabd58480 100644 --- a/lib/msf/core/post/solaris/priv.rb +++ b/lib/msf/core/post/solaris/priv.rb @@ -7,15 +7,17 @@ module Solaris module Priv include ::Msf::Post::Common - # Returns true if running as root, false if not. - def is_root? - root_priv = false - user_id = cmd_exec("/usr/xpg4/bin/id -u") - if user_id.to_i == 0 - root_priv = true - end - return root_priv + # + # Returns true if running as root, false if not. + # + def is_root? + root_priv = false + user_id = cmd_exec("/usr/xpg4/bin/id -u") + if user_id.to_i == 0 + root_priv = true end + return root_priv + end end # Priv end # Solaris diff --git a/lib/msf/core/post/solaris/system.rb b/lib/msf/core/post/solaris/system.rb index 7cae267453..0b46d312c9 100644 --- a/lib/msf/core/post/solaris/system.rb +++ b/lib/msf/core/post/solaris/system.rb @@ -9,7 +9,6 @@ module Solaris module System include ::Msf::Post::Common include ::Msf::Post::File - include ::Msf::Post::Unix # diff --git a/lib/msf/core/post/unix.rb b/lib/msf/core/post/unix.rb index 73d8fd69ca..5f46d9554f 100644 --- a/lib/msf/core/post/unix.rb +++ b/lib/msf/core/post/unix.rb @@ -4,8 +4,10 @@ module Msf class Post module Unix + # # Returns an array of hashes each representing a user # Keys are name, uid, gid, info, dir and shell + # def get_users users = [] etc_passwd = nil @@ -34,8 +36,10 @@ module Unix return users end + # # Returns an array of hashes each hash representing a user group # Keys are name, gid and users + # def get_groups groups = [] cmd_out = read_file("/etc/group").split("\n") @@ -50,7 +54,9 @@ module Unix return groups end - # returns all user directories found + # + # Enumerates the user directories in /Users or /home + # def enum_user_directories user_dirs = [] diff --git a/lib/msf/core/post/windows/eventlog.rb b/lib/msf/core/post/windows/eventlog.rb index c21fa270e3..6bbf0bc7e7 100644 --- a/lib/msf/core/post/windows/eventlog.rb +++ b/lib/msf/core/post/windows/eventlog.rb @@ -4,7 +4,10 @@ class Post module Windows module Eventlog - #enumerate eventlogs + + # + # Enumerate eventlogs + # def eventlog_list key = "HKLM\\SYSTEM\\CurrentControlSet\\Services\\" if session.sys.config.sysinfo['OS'] =~ /Windows 2003|.Net|XP|2000/ @@ -16,7 +19,10 @@ module Eventlog return eventlogs end - #clears a given eventlog or all eventlogs if none is given. Returns an array of eventlogs that where cleared. + # + # Clears a given eventlog or all eventlogs if none is given. Returns an array of eventlogs + # that where cleared. + # def eventlog_clear(evt = "") evntlog = [] if evt.empty? diff --git a/lib/msf/core/post/windows/powershell.rb b/lib/msf/core/post/windows/powershell.rb index 2e08d549e9..38b3909543 100644 --- a/lib/msf/core/post/windows/powershell.rb +++ b/lib/msf/core/post/windows/powershell.rb @@ -15,13 +15,18 @@ module Powershell # Suffix for environment variables - + # + # Returns true if powershell is installed + # def have_powershell? cmd_out = cmd_exec("powershell get-host") return true if cmd_out =~ /Name.*Version.*InstanceID/ return false end + # + # Insert substitutions into the powershell script + # def make_subs(script, subs) subs.each do |set| script.gsub!(set[0],set[1]) @@ -32,6 +37,9 @@ module Powershell end end + # + # Return an array of substitutions for use in make_subs + # def process_subs(subs) return [] if subs.nil? or subs.empty? new_subs = [] @@ -41,6 +49,9 @@ module Powershell return new_subs end + # + # Read in a powershell script stored in +script+ + # def read_script(script) script_in = '' begin @@ -60,9 +71,11 @@ module Powershell end + # + # Return a zlib compressed powershell script + # def compress_script(script_in, eof = nil) - # Compress using the Deflate algorithm compressed_stream = ::Zlib::Deflate.deflate(script_in, ::Zlib::BEST_COMPRESSION) @@ -96,6 +109,10 @@ module Powershell return encoded_expression end + # + # Execute a powershell script and return the results. The script is never written + # to disk. + # def execute_script(script, time_out = 15) running_pids, open_channels = [], [] # Execute using -EncodedCommand @@ -112,6 +129,13 @@ module Powershell return [cmd_out, running_pids, open_channels] end + + # + # Powershell scripts that are longer than 8000 bytes are split into 8000 + # 8000 byte chunks and stored as environment variables. A new powershell + # script is built that will reassemble the chunks and execute the script. + # Returns the reassembly script. + # def stage_to_env(compressed_script, env_suffix = Rex::Text.rand_text_alpha(8)) # Check to ensure script is encoded and compressed @@ -159,6 +183,9 @@ module Powershell return encoded_script end + # + # Log the results of the powershell script + # def write_to_log(cmd_out, log_file, eof) # Open log file for writing fd = ::File.new(log_file, 'w+') @@ -181,6 +208,9 @@ module Powershell return end + # + # Clean up powershell script including process and chunks stored in environment variables + # def clean_up(script_file = nil, eof = '', running_pids =[], open_channels = [], env_suffix = Rex::Text.rand_text_alpha(8), delete = false) # Remove environment variables env_del_command = "[Environment]::GetEnvironmentVariables('User').keys|" @@ -206,5 +236,8 @@ module Powershell return end -end; end; end; end +end +end +end +end diff --git a/lib/msf/core/post/windows/railgun.rb b/lib/msf/core/post/windows/railgun.rb index 72b12f179f..65d3c1dcb5 100644 --- a/lib/msf/core/post/windows/railgun.rb +++ b/lib/msf/core/post/windows/railgun.rb @@ -40,10 +40,16 @@ module Railgun end end + # + # Read +length+ bytes starting at +address+ + # def memread(address, length) railgun.memread(address, length) end + # + # Write +length+ bytes starting at +address+ + # def memwrite(address, length) railgun.memwrite(address, length) end @@ -52,6 +58,9 @@ module Railgun client.railgun end + # + # Returns the pointer size of the remote system + # def pointer_size railgun.util.pointer_size end diff --git a/lib/msf/core/post/windows/registry.rb b/lib/msf/core/post/windows/registry.rb index 957c165ee0..bb77e8c9b2 100644 --- a/lib/msf/core/post/windows/registry.rb +++ b/lib/msf/core/post/windows/registry.rb @@ -10,7 +10,9 @@ module Registry include Msf::Post::Windows::CliParse - + # + # Load a hive file + # def registry_loadkey(key,file) if session_has_registry_ext retval=meterpreter_registry_loadkey(key,file) @@ -20,6 +22,9 @@ module Registry return retval end + # + # Unload a hive file + # def registry_unloadkey(key) if session_has_registry_ext retval=meterpreter_registry_unloadkey(key) @@ -141,7 +146,9 @@ protected # Generic registry manipulation methods based on reg.exe ## - + # + # Use reg.exe to load the hive file +file+ into +key+ + # def shell_registry_loadkey(key,file) key = normalize_key(key) boo = false @@ -158,6 +165,9 @@ protected return boo end + # + # Use reg.exe to unload the hive in +key+ + # def shell_registry_unloadkey(key) key = normalize_key(key) boo = false @@ -174,6 +184,9 @@ protected end + # + # Use reg.exe to create a new registry key + # def shell_registry_createkey(key) key = normalize_key(key) boo = false @@ -191,6 +204,9 @@ protected end end + # + # Use reg.exe to delete +valname+ in +key+ + # def shell_registry_deleteval(key, valname) key = normalize_key(key) boo = false @@ -209,6 +225,9 @@ protected return boo end + # + # Use reg.exe to delete +key+ and all its subkeys and values + # def shell_registry_deletekey(key) key = normalize_key(key) boo = false @@ -227,6 +246,9 @@ protected return boo end + # + # Use reg.exe to enumerate all the subkeys in +key+ + # def shell_registry_enumkeys(key) key = normalize_key(key) subkeys = [] @@ -258,6 +280,9 @@ protected return subkeys end + # + # Use reg.exe to enumerate all the values in +key+ + # def shell_registry_enumvals(key) key = normalize_key(key) values = [] @@ -285,6 +310,9 @@ protected return values end + # + # Returns the data portion of the value +valname+ + # def shell_registry_getvaldata(key, valname) value = nil begin @@ -294,6 +322,10 @@ protected return value end + # + # Enumerate the type and data stored in the registry value +valname+ in + # +key+ + # def shell_registry_getvalinfo(key, valname) key = normalize_key(key) value = {} @@ -319,6 +351,10 @@ protected return value end + # + # Use reg.exe to add a value +valname+ in the key +key+ with the specified + # +type+ and +data+ + # def shell_registry_setvaldata(key, valname, data, type) key = normalize_key(key) boo = false @@ -343,6 +379,9 @@ protected # Meterpreter-specific registry manipulation methods ## + # + # Load a registry hive stored in +file+ into +key+ + # def meterpreter_registry_loadkey(key,file) begin client.sys.config.getprivs() @@ -376,6 +415,9 @@ protected end + # + # Unload the hive file stored in +key+ + # def meterpreter_registry_unloadkey(key) begin client.sys.config.getprivs() @@ -400,6 +442,9 @@ protected end end + # + # Create a new registry key + # def meterpreter_registry_createkey(key) begin root_key, base_key = session.sys.registry.splitkey(key) @@ -412,6 +457,9 @@ protected end end + # + # Delete the registry value +valname+ store in +key+ + # def meterpreter_registry_deleteval(key, valname) begin root_key, base_key = session.sys.registry.splitkey(key) @@ -424,6 +472,9 @@ protected end end + # + # Delete the registry key +key+ + # def meterpreter_registry_deletekey(key) begin root_key, base_key = session.sys.registry.splitkey(key) @@ -434,6 +485,9 @@ protected end end + # + # Enumerate the subkeys in +key+ + # def meterpreter_registry_enumkeys(key) subkeys = [] begin @@ -450,6 +504,9 @@ protected return subkeys end + # + # Enumerate the values in +key+ + # def meterpreter_registry_enumvals(key) values = [] begin @@ -467,6 +524,9 @@ protected return values end + # + # Get the data stored in the value +valname+ + # def meterpreter_registry_getvaldata(key, valname) value = nil begin @@ -481,6 +541,9 @@ protected return value end + # + # Enumerate the type and data of the value +valname+ + # def meterpreter_registry_getvalinfo(key, valname) value = {} begin @@ -496,6 +559,9 @@ protected return value end + # + # Add the value +valname+ to the key +key+ with the specified +type+ and +data+ + # def meterpreter_registry_setvaldata(key, valname, data, type) begin root_key, base_key = session.sys.registry.splitkey(key)