Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ProjectSend-Code execution #1

Open
XiaoZhis opened this issue Jun 17, 2017 · 1 comment
Open

ProjectSend-Code execution #1

XiaoZhis opened this issue Jun 17, 2017 · 1 comment

Comments

@XiaoZhis
Copy link
Owner

XiaoZhis commented Jun 17, 2017

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';
}

/**

  • 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;
    }
    }

// 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 );

$result = file_put_contents($config_file, $template, LOCK_EX);

01
02

07
Uploading 07.jpg…

@ignacionelson
Copy link

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants