The attacker can change the content of configuration file and constructing the dbprefix parameter to replace the TABLES_PREFIX of the configuration file with malicious code. So attacker can run malicious code remotely.
// parse all variables in the above array and fill in whatever is sent via POST
foreach ($post_vars as $var=>$value) {
if (isset($_POST[$var])) {
$post_vars[$var] = trim(stripslashes((string) $_POST[$var]));
}
}
// only mysql driver is available, let's force it
if ($pdo_mysql_available && !$pdo_mssql_available) {
$post_vars['dbdriver'] = 'mysql';
}
// only mysql driver is available, let's force it
if (!$pdo_mysql_available && $pdo_mssql_available) {
$post_vars['dbdriver'] = 'mssql';
}
/**
Check host connection
This function can take a few seconds to respond
*/
if ($pdo_driver_available) {
$dsn = $post_vars['dbdriver'] . ':host=' . $post_vars['dbhost'] . ';dbname=' . $post_vars['dbname'];
try{
$db = new PDO($dsn, $post_vars['dbuser'], $post_vars['dbpassword'], array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
$pdo_connected = true;
}
catch(PDOException $ex){
$pdo_connected = false;
}
}
Thanks for your report!
I've just added commit b275af8 which I hope fixes this problem. I've had no problems on my tests.
Can you please try again and let me know if it's fixed for you?
USE CVE-2017-9741
The attacker can change the content of configuration file and constructing the dbprefix parameter to replace the TABLES_PREFIX of the configuration file with malicious code. So attacker can run malicious code remotely.
code:
$post_vars = array(
'dbdriver' => 'mysql',
'dbname' => 'projectsend',
'dbuser' => 'root',
'dbpassword' => 'root',
'dbhost' => 'localhost',
'dbprefix' => 'tbl_',
'dbreuse' => 'no',
'lang' => 'en'
);
// parse all variables in the above array and fill in whatever is sent via POST
foreach ($post_vars as $var=>$value) {
if (isset($_POST[$var])) {
$post_vars[$var] = trim(stripslashes((string) $_POST[$var]));
}
}
//check PDO status
$pdo_available_drivers = PDO::getAvailableDrivers();
$pdo_mysql_available = in_array('mysql', $pdo_available_drivers);
$pdo_mssql_available = in_array('dblib', $pdo_available_drivers);
$pdo_driver_available = $pdo_mysql_available || $pdo_mssql_available;
// only mysql driver is available, let's force it
if ($pdo_mysql_available && !$pdo_mssql_available) {
$post_vars['dbdriver'] = 'mysql';
}
// only mysql driver is available, let's force it
if (!$pdo_mysql_available && $pdo_mssql_available) {
$post_vars['dbdriver'] = 'mssql';
}
/**
*/
if ($pdo_driver_available) {
$dsn = $post_vars['dbdriver'] . ':host=' . $post_vars['dbhost'] . ';dbname=' . $post_vars['dbname'];
try{
$db = new PDO($dsn, $post_vars['dbuser'], $post_vars['dbpassword'], array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
$pdo_connected = true;
}
catch(PDOException $ex){
$pdo_connected = false;
}
}
// names of reserved tables
$table_names = array(
'actions_log',
'categories',
'categories_relations',
'downloads',
'files',
'files_relations',
'folders',
'groups',
'members',
'notifications',
'options',
'password_reset',
'users',
);
// check if tables exists
$table_exists = false;
if ($pdo_connected) {
foreach ($table_names as $name) {
$table_exists = $table_exists || table_exists($db, $post_vars['dbprefix'].$name);
}
}
$reuse_tables = $post_vars['dbreuse'] == 'reuse';
// scan for language files
$langs = get_available_languages();
// ok if selected language has a .po file associated
$lang_ok = array_key_exists($post_vars['lang'], $langs);
// check file & folders are writable
$config_file = ROOT_DIR.'/includes/sys.config.php';
$config_file_writable = is_writable($config_file) || is_writable(dirname($config_file));
$upload_dir = ROOT_DIR.'/upload';
$upload_files_dir = ROOT_DIR.'/upload/files';
$upload_files_dir_writable = is_writable($upload_files_dir) || is_writable($upload_dir);
$upload_temp_dir = ROOT_DIR.'/upload/temp';
$upload_temp_dir_writable = is_writable($upload_temp_dir) || is_writable($upload_dir);
// retrieve user data for web server
if (function_exists('posix_getpwuid')) {
$server_user_data = posix_getpwuid(posix_getuid());
$server_user = $server_user_data['name'] . ' (uid=' . $server_user_data['uid'] . ' gid=' . $server_user_data['gid'] . ')';
} else {
$server_user = getenv('USERNAME');
}
// if everything is ok, we can proceed
$ready_to_go = $pdo_connected && (!$table_exists || $reuse_tables) && $lang_ok && $config_file_writable && $upload_files_dir_writable && $upload_temp_dir_writable;
// if the user requested to write the config file AND we can proceed, we try to write the new configuration
if (isset($POST['submit-start']) && $ready_to_go) {
$template = file_get_contents(ROOT_DIR . '/includes/sys.config.sample.php');
$template_search = array(
"'mysql'",
"'database'",
"'localhost'",
"'username'",
"'password'",
"'tbl'",
"'en'"
);
$template_replace = array(
"'" . $post_vars['dbdriver'] . "'",
"'" . $post_vars['dbname'] . "'",
"'" . $post_vars['dbhost'] . "'",
"'" . $post_vars['dbuser'] . "'",
"'" . $post_vars['dbpassword'] . "'",
"'" . $post_vars['dbprefix'] . "'",
"'" . $post_vars['lang'] . "'",
);
$template = str_replace( $template_search, $template_replace, $template );
The text was updated successfully, but these errors were encountered: