Adding documentation to the post modules library.

unstable
Stephen Haywood 2012-08-23 23:57:55 -04:00
parent a93c7836bd
commit b6d64b770a
12 changed files with 241 additions and 97 deletions

View File

@ -80,6 +80,10 @@ module Common
return o return o
end 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) def report_vm(vm)
return unless session return unless session
return unless vm return unless vm

View File

@ -2,6 +2,9 @@
module Msf::Post::File module Msf::Post::File
#
# Change directory in the remote session to +path+
#
def cd(path) def cd(path)
if session.type == "meterpreter" if session.type == "meterpreter"
e_path = session.fs.file.expand_path(path) rescue path e_path = session.fs.file.expand_path(path) rescue path
@ -11,6 +14,9 @@ module Msf::Post::File
end end
end end
#
# Returns the current working directory in the remote session
#
def pwd def pwd
if session.type == "meterpreter" if session.type == "meterpreter"
return session.fs.dir.getwd return session.fs.dir.getwd
@ -110,7 +116,7 @@ module Msf::Post::File
end end
# #
# Writes a given string to a file specified # Writes a given string to a given local file
# #
def file_local_write(file2wrt, data2wrt) def file_local_write(file2wrt, data2wrt)
if not ::File.exists?(file2wrt) if not ::File.exists?(file2wrt)
@ -141,7 +147,6 @@ module Msf::Post::File
# #
# Returns a MD5 checksum of a given remote file # Returns a MD5 checksum of a given remote file
# #
def file_remote_digestmd5(file2md5) def file_remote_digestmd5(file2md5)
data = read_file(file2md5) data = read_file(file2md5)
chksum = nil chksum = nil
@ -266,7 +271,8 @@ module Msf::Post::File
end 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) def upload_file(remote, local)
write_file(remote, ::File.read(local)) write_file(remote, ::File.read(local))

View File

@ -7,7 +7,9 @@ module Linux
module Priv module Priv
include ::Msf::Post::Common include ::Msf::Post::Common
#
# Returns true if running as root, false if not. # Returns true if running as root, false if not.
#
def is_root? def is_root?
root_priv = false root_priv = false
user_id = cmd_exec("id -u") user_id = cmd_exec("id -u")

View File

@ -9,10 +9,11 @@ module Linux
module System module System
include ::Msf::Post::Common include ::Msf::Post::Common
include ::Msf::Post::File include ::Msf::Post::File
include ::Msf::Post::Unix include ::Msf::Post::Unix
#
# Returns a Hash containing Distribution Name, Version and Kernel Information # Returns a Hash containing Distribution Name, Version and Kernel Information
#
def get_sysinfo def get_sysinfo
system_data = {} system_data = {}
etc_files = cmd_exec("ls /etc").split() etc_files = cmd_exec("ls /etc").split()
@ -97,6 +98,6 @@ module System
end # System end # System
end #Linux end # Linux
end # Post end # Post
end # Msf end # Msf

View File

@ -7,97 +7,107 @@ class Post
module OSX module OSX
module System module System
include ::Msf::Post::Common include ::Msf::Post::Common
include ::Msf::Post::File include ::Msf::Post::File
# Return a hash with system Information #
def get_sysinfo # Return a hash with system Information
system_info = {} #
cmd_output = cmd_exec("/usr/bin/sw_vers").split("\n") def get_sysinfo
cmd_output.each do |l| system_info = {}
field,val = l.chomp.split(":") cmd_output = cmd_exec("/usr/bin/sw_vers").split("\n")
system_info[field] = val.strip cmd_output.each do |l|
end field,val = l.chomp.split(":")
system_info["Kernel"] = cmd_exec("uname -a") system_info[field] = val.strip
system_info["Hostname"] = system_info["Kernel"].split(" ")[1]
return system_info
end 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 return system_info
# Keys are name, gid, uid, dir and shell end
def get_users
cmd_output = cmd_exec("/usr/bin/dscacheutil -q user") #
users = [] # Returns an array of hashes each representing a user on the system
users_arry = cmd_output.split("\n\n") # Keys are name, gid, uid, dir and shell
users_arry.each do |u| #
entry = Hash.new def get_users
u.each_line do |l| cmd_output = cmd_exec("/usr/bin/dscacheutil -q user")
field,val = l.chomp.split(": ") users = []
next if field == "password" users_arry = cmd_output.split("\n\n")
entry[field] = val.chomp 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 end
return users users << entry
end 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 # Returns an array of hashes each representing a system accounts on the system
def get_system_accounts # Keys are name, gid, uid, dir and shell
cmd_output = cmd_exec("/usr/bin/dscacheutil -q user") #
users = [] def get_system_accounts
users_arry = cmd_output.split("\n\n") cmd_output = cmd_exec("/usr/bin/dscacheutil -q user")
users_arry.each do |u| users = []
entry = {} users_arry = cmd_output.split("\n\n")
u.each_line do |l| users_arry.each do |u|
field,val = l.chomp.split(": ") entry = {}
next if field == "password" u.each_line do |l|
entry[field] = val.chomp field,val = l.chomp.split(": ")
end next if field == "password"
next if entry["name"] !~ /^_/ entry[field] = val.chomp
users << entry
end end
return users next if entry["name"] !~ /^_/
users << entry
end 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 # Returns an array of hashes each representing non system accounts on the system
def get_nonsystem_accounts # Keys are name, gid, uid, dir and shell
cmd_output = cmd_exec("/usr/bin/dscacheutil -q user") #
users = [] def get_nonsystem_accounts
users_arry = cmd_output.split("\n\n") cmd_output = cmd_exec("/usr/bin/dscacheutil -q user")
users_arry.each do |u| users = []
entry = {} users_arry = cmd_output.split("\n\n")
u.each_line do |l| users_arry.each do |u|
field,val = l.chomp.split(": ") entry = {}
next if field == "password" u.each_line do |l|
entry[field] = val.chomp field,val = l.chomp.split(": ")
end next if field == "password"
next if entry["name"] =~ /^_/ entry[field] = val.chomp
users << entry
end end
return users next if entry["name"] =~ /^_/
users << entry
end end
return users
end
# Returns an array of hashes each representing user group on the system #
# Keys are name, guid and users # Returns an array of hashes each representing user group on the system
def get_groups # Keys are name, guid and users
cmd_output = cmd_exec("/usr/bin/dscacheutil -q group") #
groups = [] def get_groups
groups_arry = cmd_output.split("\n\n") cmd_output = cmd_exec("/usr/bin/dscacheutil -q group")
groups_arry.each do |u| groups = []
entry = Hash.new groups_arry = cmd_output.split("\n\n")
u.each_line do |l| groups_arry.each do |u|
field,val = l.chomp.split(": ") entry = Hash.new
next if field == "password" u.each_line do |l|
entry[field] = val.chomp field,val = l.chomp.split(": ")
next if field == "password"
entry[field] = val.chomp
end
groups << entry
end end
return groups groups << entry
end end
return groups
end
end # System end # System
end # OSX end # OSX
end # Post end # Post

View File

@ -7,15 +7,17 @@ module Solaris
module Priv module Priv
include ::Msf::Post::Common include ::Msf::Post::Common
# Returns true if running as root, false if not. #
def is_root? # Returns true if running as root, false if not.
root_priv = false #
user_id = cmd_exec("/usr/xpg4/bin/id -u") def is_root?
if user_id.to_i == 0 root_priv = false
root_priv = true user_id = cmd_exec("/usr/xpg4/bin/id -u")
end if user_id.to_i == 0
return root_priv root_priv = true
end end
return root_priv
end
end # Priv end # Priv
end # Solaris end # Solaris

View File

@ -9,7 +9,6 @@ module Solaris
module System module System
include ::Msf::Post::Common include ::Msf::Post::Common
include ::Msf::Post::File include ::Msf::Post::File
include ::Msf::Post::Unix include ::Msf::Post::Unix
# #

View File

@ -4,8 +4,10 @@ module Msf
class Post class Post
module Unix module Unix
#
# Returns an array of hashes each representing a user # Returns an array of hashes each representing a user
# Keys are name, uid, gid, info, dir and shell # Keys are name, uid, gid, info, dir and shell
#
def get_users def get_users
users = [] users = []
etc_passwd = nil etc_passwd = nil
@ -34,8 +36,10 @@ module Unix
return users return users
end end
#
# Returns an array of hashes each hash representing a user group # Returns an array of hashes each hash representing a user group
# Keys are name, gid and users # Keys are name, gid and users
#
def get_groups def get_groups
groups = [] groups = []
cmd_out = read_file("/etc/group").split("\n") cmd_out = read_file("/etc/group").split("\n")
@ -50,7 +54,9 @@ module Unix
return groups return groups
end end
# returns all user directories found #
# Enumerates the user directories in /Users or /home
#
def enum_user_directories def enum_user_directories
user_dirs = [] user_dirs = []

View File

@ -4,7 +4,10 @@ class Post
module Windows module Windows
module Eventlog module Eventlog
#enumerate eventlogs
#
# Enumerate eventlogs
#
def eventlog_list def eventlog_list
key = "HKLM\\SYSTEM\\CurrentControlSet\\Services\\" key = "HKLM\\SYSTEM\\CurrentControlSet\\Services\\"
if session.sys.config.sysinfo['OS'] =~ /Windows 2003|.Net|XP|2000/ if session.sys.config.sysinfo['OS'] =~ /Windows 2003|.Net|XP|2000/
@ -16,7 +19,10 @@ module Eventlog
return eventlogs return eventlogs
end 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 = "") def eventlog_clear(evt = "")
evntlog = [] evntlog = []
if evt.empty? if evt.empty?

View File

@ -15,13 +15,18 @@ module Powershell
# Suffix for environment variables # Suffix for environment variables
#
# Returns true if powershell is installed
#
def have_powershell? def have_powershell?
cmd_out = cmd_exec("powershell get-host") cmd_out = cmd_exec("powershell get-host")
return true if cmd_out =~ /Name.*Version.*InstanceID/ return true if cmd_out =~ /Name.*Version.*InstanceID/
return false return false
end end
#
# Insert substitutions into the powershell script
#
def make_subs(script, subs) def make_subs(script, subs)
subs.each do |set| subs.each do |set|
script.gsub!(set[0],set[1]) script.gsub!(set[0],set[1])
@ -32,6 +37,9 @@ module Powershell
end end
end end
#
# Return an array of substitutions for use in make_subs
#
def process_subs(subs) def process_subs(subs)
return [] if subs.nil? or subs.empty? return [] if subs.nil? or subs.empty?
new_subs = [] new_subs = []
@ -41,6 +49,9 @@ module Powershell
return new_subs return new_subs
end end
#
# Read in a powershell script stored in +script+
#
def read_script(script) def read_script(script)
script_in = '' script_in = ''
begin begin
@ -60,9 +71,11 @@ module Powershell
end end
#
# Return a zlib compressed powershell script
#
def compress_script(script_in, eof = nil) def compress_script(script_in, eof = nil)
# Compress using the Deflate algorithm # Compress using the Deflate algorithm
compressed_stream = ::Zlib::Deflate.deflate(script_in, compressed_stream = ::Zlib::Deflate.deflate(script_in,
::Zlib::BEST_COMPRESSION) ::Zlib::BEST_COMPRESSION)
@ -96,6 +109,10 @@ module Powershell
return encoded_expression return encoded_expression
end end
#
# Execute a powershell script and return the results. The script is never written
# to disk.
#
def execute_script(script, time_out = 15) def execute_script(script, time_out = 15)
running_pids, open_channels = [], [] running_pids, open_channels = [], []
# Execute using -EncodedCommand # Execute using -EncodedCommand
@ -112,6 +129,13 @@ module Powershell
return [cmd_out, running_pids, open_channels] return [cmd_out, running_pids, open_channels]
end 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)) def stage_to_env(compressed_script, env_suffix = Rex::Text.rand_text_alpha(8))
# Check to ensure script is encoded and compressed # Check to ensure script is encoded and compressed
@ -159,6 +183,9 @@ module Powershell
return encoded_script return encoded_script
end end
#
# Log the results of the powershell script
#
def write_to_log(cmd_out, log_file, eof) def write_to_log(cmd_out, log_file, eof)
# Open log file for writing # Open log file for writing
fd = ::File.new(log_file, 'w+') fd = ::File.new(log_file, 'w+')
@ -181,6 +208,9 @@ module Powershell
return return
end 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) def clean_up(script_file = nil, eof = '', running_pids =[], open_channels = [], env_suffix = Rex::Text.rand_text_alpha(8), delete = false)
# Remove environment variables # Remove environment variables
env_del_command = "[Environment]::GetEnvironmentVariables('User').keys|" env_del_command = "[Environment]::GetEnvironmentVariables('User').keys|"
@ -206,5 +236,8 @@ module Powershell
return return
end end
end; end; end; end end
end
end
end

View File

@ -40,10 +40,16 @@ module Railgun
end end
end end
#
# Read +length+ bytes starting at +address+
#
def memread(address, length) def memread(address, length)
railgun.memread(address, length) railgun.memread(address, length)
end end
#
# Write +length+ bytes starting at +address+
#
def memwrite(address, length) def memwrite(address, length)
railgun.memwrite(address, length) railgun.memwrite(address, length)
end end
@ -52,6 +58,9 @@ module Railgun
client.railgun client.railgun
end end
#
# Returns the pointer size of the remote system
#
def pointer_size def pointer_size
railgun.util.pointer_size railgun.util.pointer_size
end end

View File

@ -10,7 +10,9 @@ module Registry
include Msf::Post::Windows::CliParse include Msf::Post::Windows::CliParse
#
# Load a hive file
#
def registry_loadkey(key,file) def registry_loadkey(key,file)
if session_has_registry_ext if session_has_registry_ext
retval=meterpreter_registry_loadkey(key,file) retval=meterpreter_registry_loadkey(key,file)
@ -20,6 +22,9 @@ module Registry
return retval return retval
end end
#
# Unload a hive file
#
def registry_unloadkey(key) def registry_unloadkey(key)
if session_has_registry_ext if session_has_registry_ext
retval=meterpreter_registry_unloadkey(key) retval=meterpreter_registry_unloadkey(key)
@ -141,7 +146,9 @@ protected
# Generic registry manipulation methods based on reg.exe # 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) def shell_registry_loadkey(key,file)
key = normalize_key(key) key = normalize_key(key)
boo = false boo = false
@ -158,6 +165,9 @@ protected
return boo return boo
end end
#
# Use reg.exe to unload the hive in +key+
#
def shell_registry_unloadkey(key) def shell_registry_unloadkey(key)
key = normalize_key(key) key = normalize_key(key)
boo = false boo = false
@ -174,6 +184,9 @@ protected
end end
#
# Use reg.exe to create a new registry key
#
def shell_registry_createkey(key) def shell_registry_createkey(key)
key = normalize_key(key) key = normalize_key(key)
boo = false boo = false
@ -191,6 +204,9 @@ protected
end end
end end
#
# Use reg.exe to delete +valname+ in +key+
#
def shell_registry_deleteval(key, valname) def shell_registry_deleteval(key, valname)
key = normalize_key(key) key = normalize_key(key)
boo = false boo = false
@ -209,6 +225,9 @@ protected
return boo return boo
end end
#
# Use reg.exe to delete +key+ and all its subkeys and values
#
def shell_registry_deletekey(key) def shell_registry_deletekey(key)
key = normalize_key(key) key = normalize_key(key)
boo = false boo = false
@ -227,6 +246,9 @@ protected
return boo return boo
end end
#
# Use reg.exe to enumerate all the subkeys in +key+
#
def shell_registry_enumkeys(key) def shell_registry_enumkeys(key)
key = normalize_key(key) key = normalize_key(key)
subkeys = [] subkeys = []
@ -258,6 +280,9 @@ protected
return subkeys return subkeys
end end
#
# Use reg.exe to enumerate all the values in +key+
#
def shell_registry_enumvals(key) def shell_registry_enumvals(key)
key = normalize_key(key) key = normalize_key(key)
values = [] values = []
@ -285,6 +310,9 @@ protected
return values return values
end end
#
# Returns the data portion of the value +valname+
#
def shell_registry_getvaldata(key, valname) def shell_registry_getvaldata(key, valname)
value = nil value = nil
begin begin
@ -294,6 +322,10 @@ protected
return value return value
end end
#
# Enumerate the type and data stored in the registry value +valname+ in
# +key+
#
def shell_registry_getvalinfo(key, valname) def shell_registry_getvalinfo(key, valname)
key = normalize_key(key) key = normalize_key(key)
value = {} value = {}
@ -319,6 +351,10 @@ protected
return value return value
end 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) def shell_registry_setvaldata(key, valname, data, type)
key = normalize_key(key) key = normalize_key(key)
boo = false boo = false
@ -343,6 +379,9 @@ protected
# Meterpreter-specific registry manipulation methods # Meterpreter-specific registry manipulation methods
## ##
#
# Load a registry hive stored in +file+ into +key+
#
def meterpreter_registry_loadkey(key,file) def meterpreter_registry_loadkey(key,file)
begin begin
client.sys.config.getprivs() client.sys.config.getprivs()
@ -376,6 +415,9 @@ protected
end end
#
# Unload the hive file stored in +key+
#
def meterpreter_registry_unloadkey(key) def meterpreter_registry_unloadkey(key)
begin begin
client.sys.config.getprivs() client.sys.config.getprivs()
@ -400,6 +442,9 @@ protected
end end
end end
#
# Create a new registry key
#
def meterpreter_registry_createkey(key) def meterpreter_registry_createkey(key)
begin begin
root_key, base_key = session.sys.registry.splitkey(key) root_key, base_key = session.sys.registry.splitkey(key)
@ -412,6 +457,9 @@ protected
end end
end end
#
# Delete the registry value +valname+ store in +key+
#
def meterpreter_registry_deleteval(key, valname) def meterpreter_registry_deleteval(key, valname)
begin begin
root_key, base_key = session.sys.registry.splitkey(key) root_key, base_key = session.sys.registry.splitkey(key)
@ -424,6 +472,9 @@ protected
end end
end end
#
# Delete the registry key +key+
#
def meterpreter_registry_deletekey(key) def meterpreter_registry_deletekey(key)
begin begin
root_key, base_key = session.sys.registry.splitkey(key) root_key, base_key = session.sys.registry.splitkey(key)
@ -434,6 +485,9 @@ protected
end end
end end
#
# Enumerate the subkeys in +key+
#
def meterpreter_registry_enumkeys(key) def meterpreter_registry_enumkeys(key)
subkeys = [] subkeys = []
begin begin
@ -450,6 +504,9 @@ protected
return subkeys return subkeys
end end
#
# Enumerate the values in +key+
#
def meterpreter_registry_enumvals(key) def meterpreter_registry_enumvals(key)
values = [] values = []
begin begin
@ -467,6 +524,9 @@ protected
return values return values
end end
#
# Get the data stored in the value +valname+
#
def meterpreter_registry_getvaldata(key, valname) def meterpreter_registry_getvaldata(key, valname)
value = nil value = nil
begin begin
@ -481,6 +541,9 @@ protected
return value return value
end end
#
# Enumerate the type and data of the value +valname+
#
def meterpreter_registry_getvalinfo(key, valname) def meterpreter_registry_getvalinfo(key, valname)
value = {} value = {}
begin begin
@ -496,6 +559,9 @@ protected
return value return value
end end
#
# Add the value +valname+ to the key +key+ with the specified +type+ and +data+
#
def meterpreter_registry_setvaldata(key, valname, data, type) def meterpreter_registry_setvaldata(key, valname, data, type)
begin begin
root_key, base_key = session.sys.registry.splitkey(key) root_key, base_key = session.sys.registry.splitkey(key)