Samsung Web Viewer DVR Default Credentials (HTTP)
🗓️ 12 Nov 2018 00:00:00Reported by Copyright (C) 2018 Greenbone AGType
openvas🔗 plugins.openvas.org👁 67 Views
| Source | Link |
|---|---|
| customvideosecurity | www.customvideosecurity.com/blog/tag/default-password-axis/ |
# SPDX-FileCopyrightText: 2018 Greenbone AG
# Some text descriptions might be excerpted from (a) referenced
# source(s), and are Copyright (C) by the respective right holder(s).
#
# SPDX-License-Identifier: GPL-2.0-only
if(description)
{
script_oid("1.3.6.1.4.1.25623.1.0.114047");
script_version("2023-07-20T05:05:18+0000");
script_tag(name:"cvss_base", value:"9.0");
script_tag(name:"cvss_base_vector", value:"AV:N/AC:L/Au:N/C:C/I:P/A:P");
script_tag(name:"last_modification", value:"2023-07-20 05:05:18 +0000 (Thu, 20 Jul 2023)");
script_tag(name:"creation_date", value:"2018-11-12 19:25:24 +0100 (Mon, 12 Nov 2018)");
script_category(ACT_ATTACK);
script_copyright("Copyright (C) 2018 Greenbone AG");
script_family("Default Accounts");
script_name("Samsung Web Viewer DVR Default Credentials (HTTP)");
script_dependencies("gb_samsung_web_viewer_dvr_detect.nasl", "gb_default_credentials_options.nasl");
script_require_ports("Services/www", 80);
script_mandatory_keys("samsung/web_viewer/dvr/detected");
script_exclude_keys("default_credentials/disable_default_account_checks");
script_xref(name:"URL", value:"https://customvideosecurity.com/blog/tag/default-password-axis/");
script_tag(name:"summary", value:"The remote installation of Samsung Web Viewer DVR is using known
and default credentials for the web interface.");
script_tag(name:"impact", value:"This issue may be exploited by a remote attacker to gain access
to sensitive information or modify system configuration.");
script_tag(name:"insight", value:"The installation of Samsung Web Viewer DVR is lacking a proper
password configuration, which makes critical information and actions accessible to anyone.");
script_tag(name:"vuldetect", value:"Checks if a successful login to Samsung Web Viewer DVR is possible.");
script_tag(name:"solution", value:"Change the default credentials.");
script_tag(name:"solution_type", value:"Mitigation");
script_tag(name:"qod_type", value:"remote_vul");
exit(0);
}
if(get_kb_item("default_credentials/disable_default_account_checks"))
exit(0);
include("host_details.inc");
include("misc_func.inc");
include("string_hex_func.inc");
include("http_func.inc");
include("http_keepalive.inc");
include("dump.inc");
CPE = "cpe:/a:samsung:web_viewer_dvr";
if(!port = get_app_port(cpe: CPE, service: "www"))
exit(0);
if(!get_app_location(cpe: CPE, port: port, nofork: TRUE))
exit(0);
#Because we can't use multiple keys, the first part(key) is the password and the second part(value) is the username.
creds = make_array("4321", "admin",
"111111", "admin",
"admin", "root");
url = "/cgi-bin/webviewer_login_page?loginvalue=0&port=0";
loginUrl = "/cgi-bin/webviewer_cgi_login2";
res = http_get_cache(port: port, item: url);
func = eregmatch(pattern: "(function [sS]et[Cc]ookie\(\)\{[^\}]+\})", string: res);
if(isnull(func[1])) exit(99);
funcSetCookie = func[1];
#Identification of the host's specific authentication mechanism based on the source code
if("document.login_page_submit.data2.value = do_encrypt(document.login_page.data2.value);" >< funcSetCookie) {
authType = "RSA";
}
else if("document.login_page_submit.data2.value = sha256_digest(document.login_page.data2.value);" >< funcSetCookie) {
authType = "SHA256"; #Values are random
}
else if("'&PWD='+encode64(document.login_page.pwd.value)" >< funcSetCookie) {
authType = "Base64";
loginUrl = "/cgi-bin/webviewer_cgi_login";
}
else if("document.login_page_submit.data2.value = hex_func_five(document.login_page.data2.value);" >< funcSetCookie) {
authType = "MD5";
}
else {
exit(99);
}
foreach cred(keys(creds)) {
#To avoid confusion with previous scripts, because of the reversed order:
username = creds[cred];
password = cred;
#GET request to acquire current random values if they are provided
req = http_get_req(port: port, url: url);
res = http_send_recv(port: port, data: req);
func = eregmatch(pattern: "(function [sS]et[Cc]ookie\(\)\{[^\}]+\})", string: res);
#No need to check, it is guaranteed to match at this point.
funcSetCookie = func[1];
#Generation of random values for data3
#Case1: Value has to be generated by the user
if("document.login_page_submit.data3.value = val_rand;" >< funcSetCookie) {
data3Num = "0." + rand_str(charset: "0123456789", length: 16);
} #Case 2: Value can be extracted
else if((randNum = eregmatch(pattern: "document.login_page_submit.data3.value\s*=\s*([0-9.]+);", string: funcSetCookie)) && authType != "RSA") {
data3Num = randNum[1];
} #Case 3: Value has to be generated by the user and was expected in the url from before
else if("document.login_page_submit.data3.value" >< funcSetCookie) { #Value can be extracted
data3Num = "0." + rand_str(charset: "0123456789", length: 16);
} #Case 4: None of the criteria apply - just generate a random number
else {
data3Num = "0." + rand_str(charset: "0123456789", length: 16);
}
if(authType == "RSA") {
#Generation of random values for data4
#Case 1: Value has to be generated by the user
if("document.login_page_submit.data4.value = val_rand;" >< funcSetCookie) {
data4Num = "0." + rand_str(charset: "0123456789", length: 16);
} #Case 2: Value can be extracted
else if(randNum = eregmatch(pattern: "document.login_page_submit.data4.value\s*=\s*([0-9.]+);", string: funcSetCookie)) {
data4Num = randNum[1];
} #Case 3: Value has to be generated by the user and was expected in the url from before
else if("document.login_page_submit.data4.value" >< funcSetCookie) { #Value can be extracted
data4Num = "0." + rand_str(charset: "0123456789", length: 16);
} #Case 4: None of the criteria apply - just generate a random number
else {
data4Num = "0." + rand_str(charset: "0123456789", length: 16);
}
}
if(authType == "RSA") {
# nb: Available since r25570 of libs 9.0
if(!defined_func("rsa_public_encrypt")) exit(0);
#Acquiring both the RSA modulus based on our random string, as well as the RSA exponent
url = "/cgi-bin/webviewer_login_page?lang=en&loginvalue=3&port=0&data3=" + data3Num;
req = http_get_req(port: port, url: url, add_headers: make_array("Accept-Encoding", "gzip, deflate",
"Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8"));
res = http_keepalive_send_recv(port: port, data: req);
#var rsa_modulus='CB21A70D02393C18CD551468E473A06DD85EA13C91CF51CAB5A39C1E33B1C62B55E7B10D2A4BD304B69C2C11CF84EF3CB36E30DB6CA0D0CC0C68E63B17C3293F';
modu = eregmatch(pattern: "var rsa_modulus='([0-9a-fA-F]+)';", string: res);
if(isnull(modu[1]))
continue;
#This is due to hex2raw stripping the first character from uneven strings for some reason.
#We need to make the string of even length.
if(strlen(modu[1]) % 2) {
#Just prepend a 0-character, which does not change the raw value of this string overall.
#This is a workaround until hex2raw has been modified.
modu[1] = '0' + modu[1];
}
rsa_modulus = hex2raw(s: modu[1]);
#var rsa_exponent='010001';
exp = eregmatch(pattern: "var rsa_exponent='([0-9]+)';", string: res);
if(isnull(exp[1]))
continue;
#This is due to hex2raw stripping the first character from uneven strings for some reason.
#We need to make the string of even length.
if(strlen(exp[1]) % 2) {
#Just prepend a 0-character, which does not change the raw value of this string overall.
#This is a workaround until hex2raw has been modified.
exp[1] = '0' + exp[1];
}
rsa_exponent = hex2raw(s: exp[1]);
#<input type=hidden name=remote_addr value=1.2.3.4>
rem_addr = eregmatch(pattern: "<input type=hidden name=remote_addr\s*value=([0-9.]+)>", string: res);
if(isnull(rem_addr[1])) continue;
remote_address = rem_addr[1];
#Note: Change 'pad: "TRUE"' to 'pad: TRUE' once GVM 9 is retired!
pass = hexstr(rsa_public_encrypt(data: password, e: rsa_exponent, n: rsa_modulus, pad: "TRUE"));
data = "lang=en&port=0&close_user_session=0&data1=" + base64(str: username) + "%3D&data2=" + pass + "&data3=" + data3Num + "&data4=" + data4Num + "&remote_addr=" + remote_address;
req = http_post_put_req(port: port, url: loginUrl, data: data, add_headers: make_array("Accept-Encoding", "gzip, deflate",
"Cache-Control", "max-age=0",
"Upgrade-Insecure-Requests", "1",
"Content-Type", "application/x-www-form-urlencoded",
"Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8"));
res = http_send_recv(port: port, data: req);
}
else if(authType == "SHA256") {
#<input type=hidden name=remote_addr value=1.2.3.4>
rem_addr = eregmatch(pattern: "<input type=hidden name=remote_addr\s*value=([0-9.]+)>", string: res);
if(isnull(rem_addr[1])) continue;
remote_address = rem_addr[1];
#lang=en&port=0&close_user_session=0&data1=YWRtaW4%3D&data2=...SHA256(password)&data3=0.34000497427989473&data4=0.34000497427989473&remote_addr=1.2.3.4
data = "lang=en&port=0&close_user_session=0&data1=" + base64(str: username) + "%3D&data2=" + hexstr(SHA256(password))
+ "&data3=" + data3Num + "&data4=" + data3Num + "&remote_addr=" + remote_address;
req = http_post_put_req(port: port, url: loginUrl, data: data, add_headers: make_array("Accept-Encoding", "gzip, deflate",
"Cache-Control", "max-age=0",
"Upgrade-Insecure-Requests", "1",
"Content-Type", "application/x-www-form-urlencoded",
"Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8"));
res = http_send_recv(port: port, data: req);
}
else if(authType == "Base64") {
#The sessionID is data3 or 4
#close_user_session=0&lang=en&port=0&id=admin&pwd=4321
data = "close_user_session=0&lang=en&port=0&id=" + username + "&pwd=" + password;
#ID=YWRtaW4=&PWD=NDMyMQ==&SessionID=0.5762652428478185
auth = "ID=" + base64(str: username) + "=&PWD=" + base64(str: password) + "==&SessionID=" + data3Num;
req = http_post_put_req(port: port, url: loginUrl, data: data, add_headers: make_array("Accept-Encoding", "gzip, deflate",
"Cache-Control", "max-age=0",
"Upgrade-Insecure-Requests", "1",
"Content-Type", "application/x-www-form-urlencoded",
"Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
"Cookie", auth));
res = http_send_recv(port: port, data: req);
}
else if(authType == "MD5") {
#lang=en&port=0&close_user_session=0&data1=YWRtaW4%3D&data2=21232f297a57a5a743894a0e4a801fc3
data = "lang=en&port=0&close_user_session=0&data1=" + base64(str: username) + "%3D&data2=" + hexstr(MD5(password));
#DATA1=YWRtaW4=&DATA2=YWRtaW4=&SDATA3=0.4896536714730517
auth = "DATA1=" + base64(str: username) + "&DATA2=" + base64(str: password) + "&SDATA3=" + data3Num;
req = http_post_put_req(port: port, url: loginUrl, data: data, add_headers: make_array("Accept-Encoding", "gzip, deflate",
"Cache-Control", "max-age=0",
"Upgrade-Insecure-Requests", "1",
"Content-Type", "application/x-www-form-urlencoded",
"Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
"Cookie", auth));
res = http_send_recv(port: port, data: req);
}
if(res =~ "top.document.location.href='../index.htm\?port=[0-9]+';" && res !~ "<\s*body\s*onload\s*=\s*'movetoauth\(\)'\s*>") {
VULN = TRUE;
report += '\nusername: "' + username + '", password: "' + password + '"';
}
}
if(VULN) {
report = "It was possible to login with the following default credentials: " + report;
security_message(port: port, data: report);
exit(0);
}
exit(99);
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
20 Jul 2023 00:00Current
7.6High risk
Vulners AI Score7.6