MiniCMS漏洞复现(二)
CVE-2018-18891 部分文件删除
存在位置: /MiniCMS-master/mc-admin/post.php 不用登录即可直接删除文章。
function delete_post($id) {
global $state, $index_file, $mc_posts;
$post = $mc_posts[$id];
$post['prev_state'] = $state;
unset($mc_posts[$id]);
file_put_contents($index_file, "<?php\n$mc_posts=".var_export($mc_posts, true)."\n?>");
if ($state != 'delete') {
$index_file2 = '../mc-files/posts/index/delete.php';
require $index_file2;
$mc_posts[$id] = $post;
file_put_contents($index_file2, "<?php\n$mc_posts=".var_export($mc_posts, true)."\n?>");
} else {
unlink('../mc-files/posts/data/'.$id.'.dat');
}
}
unlink函数这里是删除文件操作,$state=delete时就可以绕过if判断,再往回看,$state变量在load_posts函数处被赋值:
function load_posts() {
global $state, $index_file, $mc_posts;
if (isset($_GET['state'])) {
if ($_GET['state'] == 'draft') {
$state = 'draft';
$index_file = '../mc-files/posts/index/draft.php';
}
else if ($_GET['state'] == 'delete'){
$state = 'delete';
$index_file = '../mc-files/posts/index/delete.php';
}
else {
$state = 'publish';
$index_file = '../mc-files/posts/index/publish.php';
}
}
else {
$state = 'publish';
$index_file = '../mc-files/posts/index/publish.php';
}
require $index_file;
}
$state被赋值之后再没有任何变动。接着对$id变量进行溯源,发现$id从$ids中获得,$ids是由GET传过来的,可以对此进行控制。
if (isset($_GET['delete']) || (isset($_GET['apply']) && $_GET['apply'] == 'delete')) {
if (isset($_GET['apply']) && $_GET['apply'] == 'delete') {
$ids = explode(',', $_GET['ids']);
foreach ($ids as $id) {
if (trim($id) == '')
continue;
delete_post($id);
load_posts();
}
} else {
delete_post($_GET['delete']);
}
ac-admin/head.php中有权限判断,但在ac-admin/post.php中,在前面的函数已经执行后,才会用权限判断,因此这里存在越权行为:
payload: mc-admin/post.php?delete=aaaa&state=delete
删除成功,是一个垂直越权漏洞。