74CMS_3.5 后台任意文件写入

/admin/admin_database.php 45行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
elseif($act =='do_backup')
{
check_permissions($_SESSION['admin_purview'],"database");
if (!file_exists("../data/".$backup_dir."/"))adminmsg("备份文件存放目录data/".$backup_dir."不存在!",0);
if (!is_writable("../data/".$backup_dir."/"))adminmsg("备份文件存放目录data/".$backup_dir."不可写!",0);
$limit_size = !empty($_REQUEST['limit_size']) ? intval($_REQUEST['limit_size']) : '2048';
$mysql_type = !empty($_REQUEST['mysql_type']) ? trim($_REQUEST['mysql_type']) : '';
$table_id = !empty($_REQUEST['table_id']) ? intval($_REQUEST['table_id']) : 0;
$file = !empty($_GET['file']) ? trim($_GET['file']) : date("Ymd_", time()) . get_rand_char(5).uniqid();
$num = !empty($_GET['num']) ? intval($_GET['num']) : 1;
$pos = !empty($_GET['pos']) ? intval($_GET['pos']) : 0;
if (!empty($_POST['tables']))
{
$tables = $_POST['tables'];
@file_put_contents("../data/{$backup_dir}/temp.txt", serialize($_POST['tables']));
}

可以往data/backup/temp.txt中写入内容,写一个phpinfo();

本地去查看,的确写入了。

然后找一个require或者include包含他

/admin/admin_crons.php 105行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
elseif($act == 'execution')
{
check_token();
$id=intval($_GET['id']);
$crons=$db->getone("select * from ".table('crons')." WHERE cronid='{$id}' LIMIT 1 ");
if (!empty($crons))
{
if (!file_exists(QISHI_ROOT_PATH."include/crons/".$crons['filename']))
{
adminmsg("任务文件 {$crons['filename']} 不存在!",0);
}
require_once(QISHI_ROOT_PATH."include/crons/".$crons['filename']);
adminmsg("执行成功!",2);
}
}

取出crons表中的输入的id所在行,并require /include/crons/[filename]列

所以后台修改crons表里的filename值

然后执行这个计划,这个文件就被require了。

总结:可控文件写入+可控文件包含
文件包含处要过滤../

支持一下
扫一扫,支持forsigner