下载Install.php 安装上 这个cms竟然没有数据库先去看了一下文件的功能
文件功能列表 https://www.4hou.com/technology/19138.html
│ build.php│ index.php 整个项目的入口,首先引入核心库mc-core.php,然后进行路由,对路由结果进行相应的渲染,相当于MVC中的C│ install.txt 复制为php文件后,用来安装MiniCMS│ README.md│├─mc-admin 管理功能的实现│ conf.php 用户设置页面,包括接收和保存更改的设置│ editor.php 编辑器的大小、样式调整的库│ foot.php html标签构造│ head.php token验证,html标签构造;若验证失败,跳转至主页│ index.php 后台登陆身份验证页面│ page-edit.php 页面编写处理逻辑,包括显示编辑页面、接收提交的页面、页面序列化储存│ page.php 管理页面的库,声明加载数据、删除页面、还原页面(从回收站还原)│ post-edit.php 文章编写处理逻辑,包括显示编辑页面、接收提交的页面、页面序列化储存│ post.php 管理文章的库,声明加载数据、删除文章、还原文章(从回收站还原)│ style.css 后台用到的CSS│└─mc-files │ markdown.php 一个开源的markdown解析库 │ mc-conf.php 配置文件,包含用户名和密码等敏感信息 │ mc-core.php 引入mc-tags、mc-conf,声明404函数 │ mc-rss.php 订购RSS的链接 │ mc-tags.php 相当于M,引入markdown、包括一些核心函数,包括了加载各种信息的函数(网站名、文章数、前进后退等,中间有各种过滤,可以重点分析) │ ├─pages │ └─index │ delete.php 使用数组储存了删除页面的信息(id、标题、标签等)与data文件夹内的文章数据一一对应 │ draft.php 使用数组储存了草稿页面的信息(id、标题、标签等)与data文件夹内的文章数据一一对应 │ publish.php 使用数组储存了已发布的页面的信息(id、标题、标签等)与data文件夹内的文章数据一一对应 │ ├─posts │ ├─data 储存了文章内容的反序列化数据(文章内容等) │ └─index │ delete.php 使用数组储存了删除的文章的信息(id、标题、标签等)与data文件夹内的文章数据一一对应 │ draft.php 使用数组储存了草稿文章的信息(id、标题、标签等)与data文件夹内的文章数据一一对应 │ publish.php 使用数组储存了已发布文章的信息(id、标题、标签等)与data文件夹内的文章数据一一对应 │ └─theme index.php 主题文件,决定了页面的风格,将C传入的信息显示出来,相当于V style.css 主题使用的CSS风格
安装后访问,首页就只显示了三个功能 还包括一个首页
大体看了一下index.php,这里的Index.php就相当于C(控制路由),大体的逻辑先是根据url后面?后的内容,判断$mc_get_type再根据$mc_get_type 返回指定的内容
XSS1
登陆界面 这里面貌似有xss
mc-admin/index.php
直接输出,有点像xss
试了半天没试出来 我的火狐把
看别的师傅说 用IE能弹窗 但是我经过测试也不能弹窗
去看了一下 登陆的验证过程一种是通过cookie验证,还有一种是账号密码验证,通过后设置cookie
垂直越权
刚开始以为越权漏洞是 把 普通用户的账号当作admin的账号,后来发现,普通用户执行admin的操作也是越权
post页面有编辑 删除 恢复等操作 这就是了解文件结构的作用 根据文件的作用 就能找到常见漏洞在Post.php的52行 有一处删除文件
unlink('../mc-files/posts/data/'.$id.'.dat');
回溯变量
if ($state != 'delete') { $index_file2 = '../mc-files/posts/index/delete.php'; require $index_file2; $mc_posts[$id] = $post; file_put_contents($index_file2, "<?php $mc_posts=".var_export($mc_posts, true)."?>"); } else { unlink('../mc-files/posts/data/'.$id.'.dat'); }
$state=delete就可以绕过if判断
$state变量在load_posts函数处被赋值
else if ($_GET['state'] == 'delete'){ $state = 'delete'; $index_file = '../mc-files/posts/index/delete.php'; }
赋值之后,在就没有变化再去看$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']); }
试一下 访问post.php 结果是302很有可能是没登陆,所以重定向了,但是代码看到这里,没有发现有验证的地方,再往下看看在188行处
<?php require 'head.php' ?>',)
单引号闭合再加上注释符不行,前面说了comment_code中的单引号被var_export转义了,只能利用其他的位置就用网站标题吧最后发现从conf.php传过去的mc_config变量,都经过了var_export
后来看了已有的CVE 是使用了install.php 在安装时 通过设置网站标题为
');<?php phpinfo();?>
实现RCE 一般网站在安装后都会删除install.php
xss3
mc-admin/post.php这里有一个tag参数,最后的输出没有经过转义
if (isset($_GET['tag'])) $filter_tag = $_GET['tag'];
288行有输出点
&date=<?php echo $filter_date;?>&tag=<?php echo $filter_tag; ?>">« &date=<?php echo $filter_date;?>&tag=<?php echo $filter_tag; ?>&page=<?php echo $prev_page; ?>">‹
下面还有一个data参数,同样的道理,也存在xss利用过程和之前的基本一样
xss总结
可能只在一个地方输入,但是会在多个地方显示,也就是说虽然只在编辑页面输入了xss语句,但是会在post.php 以及minicms/?post/4hctsa等多个页面显示还有浏览器可能也会转义标签等xss因为这个cms使用了stripslashes来处理输入数据,那么可以全局搜索一下stripslashes来快速找到,有哪些地方可以输入数据,也就找到了xss输入点
RCE
page-edit.php下面还有一处写入操作file_put_content116行
$data['content'] = $post_content; file_put_contents($file_path, serialize($data));
上面还有一处文件包含109行
代码审计-minicms$index_file = '../mc-files/posts/index/'.$post_state.'.php'; require $index_file;
回溯变量$post_content = $_POST['content']$post_state = $_POST['state']
都可控在测试的时候出现了两个问题content写上<?php phpinfo();?>
第一个还好说 content是存放在data目录下 这里的路径是index 可以用../跳转一下第二个捣鼓了半天 还没弄好 就是写入的文件是有后缀的,dat 而这里自动加上了一个后缀.php 试过%00 # ; ./长度截断 都不行最后把php的版本改为5.2 使用%00截断 实现了文件包含+RCE
一点收获
%00截断适用与php<5.3.29 并且GPC(magic_quotes_gpc)为off
总结
这个cms是一个搭建博客使用的,普通用户能够执行的东西比较少,像文件上传这种漏洞根本就不存在,主要是一个xss这里xss还用到了一个在action参数里输出,虽然没复现出来