XiaoZhis / ProjectSend

0 stars 0 forks source link

ProjectSend-Code execution #1

Open XiaoZhis opened 7 years ago

XiaoZhis commented 7 years ago

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: $postvars = 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'; }

/**

// 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'); $templatesearch = 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 commented 7 years ago

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?