## 一、漏洞概述
### 1. 漏洞简介
FreePBX之前被称为Asterisk Management Portal,是IP电话工具Asterisk的标准化实现,可提供Web配置界面和其他工
FreePBX中的`functions.inc.php`文件存在对参数未经过滤直接拼接进`exec`,可导致远程命令执行
### 2. 漏洞影响
攻击者可以在通过构造特定url,在目标系统上执行任意命令并取得返回结果
### 3. 漏洞触发条件
版本:`13.0.35`经过测试,其他版本未知
权限:拥有管理员账号
## 二、漏洞原理分析
`functions.inc.php`中`get_headers_assoc()`:
```
function get_headers_assoc($url) {
global $amp_conf;
if ($amp_conf['MODULEADMINWGET']) {
FreePBX::Curl()->setEnvVariables();
//关键点
exec("wget --spider --server-response -q ".$url." 2>&1", $wgetout, $exitstatus);
$headers = array();
if($exitstatus == 0 && !empty($wgetout)) {
foreach($wgetout as $value) {
$ar = explode(':', $value);
$key = trim($ar[0]);
if(isset($ar[1])) {
$value = trim($ar[1]);
$headers[strtolower($key)] = trim($value);
}
```
`$url`传递给exec前未经任何过滤,导致远程命令执行,继续寻找调用该函数的文件
`libraries/modulefunctions.class.php`中`1539`行:
```
function handledownload($module_location, $progress_callback = null) {
//...................................................
if (!is_array($progress_callback) && function_exists($progress_callback)) {
$progress_callback('getinfo', array('module'=>$modulename));
} else if(is_array($progress_callback) && method_exists($progress_callback[0],$progress_callback[1])) {
$progress_callback[0]->$progress_callback[1]('getinfo', array('module'=>$modulename));
}
$file = basename($module_location);
$filename = $amp_conf['AMPWEBROOT']."/admin/modules/_cache/".$file;
//关键点
$headers = get_headers_assoc($module_location);
if (empty($headers)) {
return array(sprintf(_('Failed download module tarball from %s, server may be down'),$module_location));
}
}
```
调用get_headers_assoc()时传入的参数`$module_location`同样没有过滤
`handledownload()`函数在文件`page.modules.php`被包含时调用,在管理员控制面板中访问`admin/config.php?display=modules`可以使得文件被包含.
`page.modules.php`:
```
Line 174 : switch ($action) {
..............................
Line 643 : case 'upload':
..............................
$displayvars['processed'] = false;
if (isset($_REQUEST['upload']) && isset($_FILES['uploadmod']) && !empty($_FILES['uploadmod']['name'])) {
$displayvars['res'] = $modulef->handleupload($_FILES['uploadmod']);
$displayvars['processed'] = true;
}
//关键点
elseif (isset($_REQUEST['download']) && !empty($_REQUEST['remotemod'])) {
$displayvars['res'] = $modulef->handledownload($_REQUEST['remotemod']);
$displayvars['processed'] = true;
} elseif(isset($_REQUEST['remotemod'])) {
$displayvars['res'][] = 'Nothing to download or upload';
$displayvars['processed'] = true;
}
```
传入`download`时,进入关键点处的判断,参数`$_REQUEST['remotemod']`也未进行任何过滤就传入`handledownload()`,最终这个参数将拼接进`exec()`执行
调用流程:`page.modules.php:handledownload($_REQUEST['remotemod']) ---> get_headers_assoc($module_location) ---> get_headers_assoc($url) ---> exec()`
暂无评论