Browse Source

1,新增数据库挂马检测功能。
2,新增评论入库接口。
3,角色入库接口支持豆瓣id对应视频。
4,定时任务可以强制执行。
5,支持自定义404页面模板。
6,其他细节。

magicblack 5 years ago
parent
commit
f86927a16c

+ 1 - 0
application/admin/common/auth.php

@@ -255,6 +255,7 @@ return array(
 
 
         '102' => array("show"=>1,'name' => '执行SQL语句', 'controller' => 'database',		'action' => 'sql'),
         '102' => array("show"=>1,'name' => '执行SQL语句', 'controller' => 'database',		'action' => 'sql'),
         '103' => array("show"=>1,'name' => '数据批量替换', 'controller' => 'database',		'action' => 'rep'),
         '103' => array("show"=>1,'name' => '数据批量替换', 'controller' => 'database',		'action' => 'rep'),
+        '104' => array("show"=>1,'name' => '挂马检测', 'controller' => 'database',		'action' => 'inspect'),
     )),
     )),
     '11' => array('name' => '应用', 'icon' => 'xe621', 'sub' => array(
     '11' => array('name' => '应用', 'icon' => 'xe621', 'sub' => array(
         '111' => array("show"=>1,'name' => '应用市场', 'controller' => 'addon',		'action' => 'index', 'param'=>''),
         '111' => array("show"=>1,'name' => '应用市场', 'controller' => 'addon',		'action' => 'index', 'param'=>''),

+ 81 - 0
application/admin/controller/Database.php

@@ -302,4 +302,85 @@ class Database extends Base
         return $this->fetch('admin@database/rep');
         return $this->fetch('admin@database/rep');
     }
     }
 
 
+    public function inspect()
+    {
+        $param = input();
+        if ($param['ck']) {
+            $pre = config('database.prefix');
+            $schema = Db::query('select * from information_schema.columns where table_schema = ?', [config('database.database')]);
+            $col_list = [];
+            $sql = '';
+            foreach ($schema as $k => $v) {
+                $col_list[$v['TABLE_NAME']][$v['COLUMN_NAME']] = $v;
+            }
+            $tables = ['actor', 'art', 'comment','gbook', 'link', 'topic', 'type','user', 'vod'];
+            $param['tbi'] = intval($param['tbi']);
+            if ($param['tbi'] >= count($tables)) {
+                mac_echo('清理结束,可以多次执行,以免有漏掉的数据');
+                die;
+            }
+
+            $check_arr = ["script>"];
+            $rel_val = ["/<script[\s\S]*?<\/script>/is"];
+
+            mac_echo('<style type="text/css">body{font-size:12px;color: #333333;line-height:21px;}span{font-weight:bold;color:#FF0000}</style>');
+
+            foreach ($col_list as $k1 => $v1) {
+                $pre_tb = str_replace($pre, '', $k1);
+                $si = array_search($pre_tb, $tables);
+                if ($pre_tb !== $tables[$param['tbi']]) {
+                    continue;
+                }
+                mac_echo('开始检测' . $k1 . '表...');
+                $where = [];
+                foreach ($v1 as $k2 => $v2) {
+                    if (strpos($v2['DATA_TYPE'], 'int') === false) {
+                        $where[$k2] = ['like', mac_like_arr(join(',', $check_arr)), 'OR'];
+                    }
+                }
+                if (!empty($where)) {
+                    $field = array_keys($where);
+                    $field[] = $tables[$si] . '_id';
+                    $list = Db::name($pre_tb)->field($field)->whereOr($where)->fetchSql(false)->select();
+
+                    mac_echo('共检测到' . count($list) . '条危险数据...');
+                    foreach ($list as $k3 => $v3) {
+                        $update = [];
+                        $col_id = $tables[$si] . '_id';
+                        $col_name = $tables[$si] . '_name';
+                        $val_id = $v3[$col_id];;
+                        $val_name = strip_tags($v3[$col_name]);
+                        $ck = false;
+                        $where2 = [];
+                        $where2[$col_id] = $val_id;
+                        foreach ($v3 as $k4 => $v4) {
+
+                            if ($k4 != $col_id) {
+                                $val = $v4;
+                                foreach ($check_arr as $kk => $vv) {
+                                    $val = preg_replace($rel_val[$kk], "", $val);
+                                }
+                                if ($val !== $v4) {
+                                    $update[$k4] = $val;
+                                    $ck = true;
+                                }
+                            }
+                        }
+
+                        if ($ck) {
+                            $r = Db::name($pre_tb)->where($where2)->update($update);
+                            mac_echo($val_id . '、' . $val_name . ' ok');
+                        }
+                    }
+                }
+            }
+
+            $param['tbi']++;
+            $url = url('database/inspect') . '?' . http_build_query($param);
+            mac_jump($url, 3);
+            exit;
+        }
+        return $this->fetch('admin@database/inspect');
+    }
+
 }
 }

+ 40 - 0
application/admin/view/database/inspect.html

@@ -0,0 +1,40 @@
+{include file="../../../application/admin/view/public/head" /}
+
+<div class="page-container">
+    <form class="layui-form layui-form-pane" method="get" action="">
+        <input name="ck" value="1" type="hidden">
+        <div class="layui-tab">
+            <ul class="layui-tab-title">
+                <li class="layui-this">挂马检测</li>
+            </ul>
+            <div class="layui-tab-content">
+                <div class="layui-tab-item layui-show">
+
+                    <div class="layui-input-block" >
+                        <blockquote class="layui-elem-quote layui-quote-nm">
+                            <strong>挂马检测1.0版本</strong><br>
+                            1,将对分类表,视频表,文章表,会员表等表结构进行检查。<br>
+                            2,检测包含script等特殊字符串。<br>
+                            3,将自动清除挂马代码。<br>
+                            4,不能保证100%清除,如还有问题请自行进入phpmyadmin或其他数据库管理工具里清除。<br>
+                            5,建议清理多次,直到没有出现问题数据。
+                        </blockquote>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <div class="layui-form-item center">
+            <div class="layui-input-block">
+                <button type="submit" class="layui-btn" >确认执行</button>
+            </div>
+        </div>
+    </form>
+</div>
+
+{include file="../../../application/admin/view/public/foot" /}
+<script type="text/javascript">
+
+</script>
+
+</body>
+</html>

+ 7 - 0
application/admin/view/system/config.html

@@ -324,6 +324,13 @@
                     </div>
                     </div>
                     <div class="layui-form-mid layui-word-aux">使用微信、QQ访问将直接显示跳转提示页面</div>
                     <div class="layui-form-mid layui-word-aux">使用微信、QQ访问将直接显示跳转提示页面</div>
                 </div>
                 </div>
+                <div class="layui-form-item">
+                    <label class="layui-form-label">404页面:</label>
+                    <div class="layui-input-inline">
+                        <input type="text" name="app[page_404]" placeholder="" value="{$config['app']['page_404']}" class="layui-input w150">
+                    </div>
+                    <div class="layui-form-mid layui-word-aux">自定义404页面,页面放在模板的public目录下无需后缀名,默认为jump</div>
+                </div>
 
 
                 <div class="layui-form-item">
                 <div class="layui-form-item">
                     <label class="layui-form-label">采集间隔:</label>
                     <label class="layui-form-label">采集间隔:</label>

+ 1 - 0
application/api/controller/Provide.php

@@ -761,4 +761,5 @@ class Provide extends Base
         exit;
         exit;
     }
     }
 
 
+
 }
 }

+ 29 - 2
application/api/controller/Receive.php

@@ -113,8 +113,8 @@ class Receive extends Base
             echo json_encode(['code'=>2002,'msg'=>'演员名必须err'],JSON_UNESCAPED_UNICODE);
             echo json_encode(['code'=>2002,'msg'=>'演员名必须err'],JSON_UNESCAPED_UNICODE);
             exit;
             exit;
         }
         }
-        if(empty($info['vod_name'])){
-            echo json_encode(['code'=>2003,'msg'=>'视频名必须err'],JSON_UNESCAPED_UNICODE);
+        if(empty($info['vod_name']) && empty($info['douban_id'])){
+            echo json_encode(['code'=>2003,'msg'=>'视频名或豆瓣id必须err'],JSON_UNESCAPED_UNICODE);
             exit;
             exit;
         }
         }
 
 
@@ -144,4 +144,31 @@ class Receive extends Base
         $res = model('Collect')->website_data([],$data,0);
         $res = model('Collect')->website_data([],$data,0);
         echo json_encode($res,JSON_UNESCAPED_UNICODE);
         echo json_encode($res,JSON_UNESCAPED_UNICODE);
     }
     }
+
+    public function comment()
+    {
+        $info = $this->_param;
+
+        if(empty($info['comment_name'])){
+            echo json_encode(['code'=>2001,'msg'=>'名称必须err'],JSON_UNESCAPED_UNICODE);
+            exit;
+        }
+        if(empty($info['comment_content'])){
+            echo json_encode(['code'=>2002,'msg'=>'内容必须'],JSON_UNESCAPED_UNICODE);
+            exit;
+        }
+        if(empty($info['comment_mid'])){
+            echo json_encode(['code'=>2004,'msg'=>'mid必须'],JSON_UNESCAPED_UNICODE);
+            exit;
+        }
+        if(empty($info['rel_name']) && empty($info['douban_id'])){
+            echo json_encode(['code'=>2003,'msg'=>'关联数据名rel_name或豆瓣编号douban_id至少填写一项err'],JSON_UNESCAPED_UNICODE);
+            exit;
+        }
+
+
+        $data['data'][] = $info;
+        $res = model('Collect')->comment_data([],$data,0);
+        echo json_encode($res,JSON_UNESCAPED_UNICODE);
+    }
 }
 }

+ 5 - 1
application/common/controller/All.php

@@ -100,7 +100,11 @@ class All extends Controller
         $this->assign('url',$url);
         $this->assign('url',$url);
         $this->assign('wait',$wait);
         $this->assign('wait',$wait);
         $this->assign('msg',$msg);
         $this->assign('msg',$msg);
-        $html = $this->label_fetch('public/jump');
+        $tpl = 'jump';
+        if(!empty($GLOBALS['config']['app']['page_404'])){
+            $tpl = $GLOBALS['config']['app']['page_404'];
+        }
+        $html = $this->label_fetch('public/'.$tpl);
         header("HTTP/1.1 404 Not Found");
         header("HTTP/1.1 404 Not Found");
         header("Status: 404 Not Found");
         header("Status: 404 Not Found");
         exit($html);
         exit($html);

+ 222 - 4
application/common/model/Collect.php

@@ -714,7 +714,7 @@ class Collect extends Base {
                                     $des .= '播放地址相同,跳过。';
                                     $des .= '播放地址相同,跳过。';
                                 } elseif (empty($cj_play_from)) {
                                 } elseif (empty($cj_play_from)) {
                                     $des .= '播放器类型为空,跳过。';
                                     $des .= '播放器类型为空,跳过。';
-                                } elseif (strpos("," . $info['vod_play_from'], $cj_play_from) <= 0) {
+                                } elseif (strpos(','.$info['vod_play_from'].',', ','.$cj_play_from.',') <= 0) {
                                     $color = 'green';
                                     $color = 'green';
                                     $des .= '播放组(' . $cj_play_from . '),新增ok。';
                                     $des .= '播放组(' . $cj_play_from . '),新增ok。';
                                     if(!empty($old_play_from)){
                                     if(!empty($old_play_from)){
@@ -1703,11 +1703,15 @@ class Collect extends Base {
                 $where['role_name'] = $v['role_name'];
                 $where['role_name'] = $v['role_name'];
                 $where['role_actor'] = $v['role_actor'];
                 $where['role_actor'] = $v['role_actor'];
 
 
-
                 $where2 = [];
                 $where2 = [];
-                $where2['vod_name'] = ['eq',$v['vod_name']];
                 $blend = false;
                 $blend = false;
-
+                if(!empty($v['douban_id'])){
+                    $where2['vod_douban_id'] = ['eq',$v['douban_id']];
+                    unset($v['douban_id']);
+                }
+                else{
+                    $where2['vod_name'] = ['eq',$v['vod_name']];
+                }
                 if (strpos($config['inrule'], 'c')!==false) {
                 if (strpos($config['inrule'], 'c')!==false) {
                     $where2['vod_actor'] = ['like', mac_like_arr($v['role_actor']), 'OR'];
                     $where2['vod_actor'] = ['like', mac_like_arr($v['role_actor']), 'OR'];
                 }
                 }
@@ -2140,4 +2144,218 @@ class Collect extends Base {
         }
         }
     }
     }
 
 
+    public function comment_data($param,$data,$show=1)
+    {
+        if($show==1) {
+            mac_echo('当前采集任务<strong class="green">' . $data['page']['page'] . '</strong>/<span class="green">' . $data['page']['pagecount'] . '</span>页 采集地址&nbsp;' . $data['page']['url'] . '');
+        }
+
+        $config = config('maccms.collect');
+        $config = $config['comment'];
+
+        $filter_arr = explode(',',$config['filter']); $filter_arr = array_filter($filter_arr);
+        $pse_rnd = explode('#',$config['words']); $pse_rnd = array_filter($pse_rnd);
+        $pse_syn = mac_txt_explain($config['thesaurus']);
+
+        foreach($data['data'] as $k=>$v){
+
+            $color='red';
+            $des='';
+            $msg='';
+            $tmp='';
+
+            if(empty($v['comment_name']) || empty($v['comment_content']) || empty($v['rel_name']) ) {
+                $des = '数据不完整comment_content,comment_name,rel_name必须,跳过err。';
+            }
+            elseif( mac_array_filter($filter_arr,$v['comment_content']) !==false) {
+                $des = '数据在过滤单中,跳过err';
+            }
+            else {
+                unset($v['comment_id']);
+
+                foreach($v as $k2=>$v2){
+                    if(strpos($k2,'_content')===false) {
+                        $v[$k2] = strip_tags($v2);
+                    }
+                }
+
+                $v['comment_time'] = time();
+                $v['comment_status'] = intval($config['status']);
+                $v['comment_up'] = intval($v['comment_up']);
+                $v['comment_down'] = intval($v['comment_down']);
+                $v['comment_mid'] = intval($v['comment_mid']);
+                if(!empty($v['comment_ip']) && !is_numeric($v['comment_ip'])){
+                    $v['comment_ip'] = ip2long($v['comment_ip']);
+                }
+
+                if($config['updown_start']>0 && $config['updown_end']){
+                    $v['comment_up'] = rand($config['updown_start'], $config['updown_end']);
+                    $v['comment_down'] = rand($config['updown_start'], $config['updown_end']);
+                }
+                if ($config['psernd'] == 1) {
+                    $v['comment_content'] = mac_rep_pse_rnd($pse_rnd, $v['comment_content']);
+                }
+                if ($config['psesyn'] == 1) {
+                    $v['comment_content'] = mac_rep_pse_syn($pse_syn, $v['comment_content']);
+                }
+
+                $where = [];
+                $where2 = [];
+                $blend = false;
+
+                if (strpos($config['inrule'], 'b')!==false) {
+                    $where['comment_content'] = ['eq', $v['comment_content']];
+                }
+                if (strpos($config['inrule'], 'c')!==false) {
+                    $where['comment_name'] = ['eq', $v['comment_name']];
+                }
+
+                if(empty($v['rel_id'])){
+                    if($v['comment_mid']==1){
+                        if(!empty($v['douban_id'])){
+                            $where2['vod_douban_id'] = ['eq',$v['douban_id']];
+                            unset($v['douban_id']);
+                        }
+                        else{
+                            $where2['vod_name'] = ['eq',$v['rel_name']];
+                        }
+                        $rel_info = model('Vod')->where($where2)->find();
+                    }
+                    elseif($v['comment_mid']==2){
+                        $where2['art_name'] = ['eq',$v['rel_name']];
+                        $rel_info = model('Art')->where($where2)->find();
+                    }
+                    elseif($v['comment_mid']==3){
+                        $where2['topic_name'] = ['eq',$v['rel_name']];
+                        $rel_info = model('Topic')->where($where2)->find();
+                    }
+                    elseif($v['comment_mid']==8){
+                        $where2['actor_name'] = ['eq',$v['rel_name']];
+                        $rel_info = model('Actor')->where($where2)->find();
+                    }
+                    elseif($v['comment_mid']==9){
+                        $where2['role_name'] = ['eq',$v['rel_name']];
+                        $rel_info = model('Role')->where($where2)->find();
+                    }
+                    elseif($v['comment_mid']==11){
+                        $where2['website_name'] = ['eq',$v['rel_name']];
+                        $rel_info = model('Website')->where($where2)->find();
+                    }
+
+                    $rel_id = $rel_info[mac_get_mid_code($v['comment_mid']).'_id'];
+                }
+                else{
+                    $rel_id = $v['rel_id'];
+                }
+
+                if(empty($rel_id)){
+                    $des = '未找到相关数据无法关联,跳过。';
+                }
+                else {
+
+                    $v['comment_rid'] = $rel_id;
+                    $info=false;
+
+                    if(!empty($where)) {
+                        $where['comment_rid'] = $rel_id;
+                        $info = model('Comment')->where($where)->find();
+                    }
+                    if (!$info) {
+                        $msg = $tmp['msg'];
+                        $res = model('Comment')->insert($v);
+                        if ($res === false) {
+
+                        }
+                        $color = 'green';
+                        $des = '新加入库,成功ok。';
+                    } else {
+
+                        if(empty($config['uprule'])){
+                            $des = '没有设置任何二次更新项目,跳过。';
+                        }
+                        else {
+                            $rc = true;
+                            if ($rc) {
+                                $update = [];
+
+                                if (strpos(',' . $config['uprule'], 'a') !== false && !empty($v['comment_time']) && $v['comment_time'] != $info['comment_time']) {
+                                    $update['comment_time'] = $v['comment_time'];
+                                }
+
+                                if(count($update)>0){
+                                    $update['comment_time'] = time();
+                                    $where = [];
+                                    $where['comment_id'] = $info['comment_id'];
+                                    $res = model('Comment')->where($where)->update($update);
+                                    $color = 'green';
+                                    if ($res === false) {
+
+                                    }
+                                }
+                                else{
+                                    $des = '无需更新。';
+                                }
+                            }
+
+                        }
+                    }
+                }
+
+            }
+            if($show==1) {
+                mac_echo( ($k + 1) . $v['comment_content'] . "<font color=$color>" .$des .'</font>'. $msg . '');
+            }
+            else{
+                return ['code'=>($color=='red' ? 1001 : 1),'msg'=> $v['comment_content'] .' '.$des ];
+            }
+        }
+
+        $key = $GLOBALS['config']['app']['cache_flag']. '_'.'collect_break_comment';
+        if(ENTRANCE=='api'){
+            Cache::rm($key);
+            if ($data['page']['page'] < $data['page']['pagecount']) {
+                $param['page'] = intval($data['page']['page']) + 1;
+                $res = $this->role($param);
+                if($res['code']>1){
+                    return $this->error($res['msg']);
+                }
+                $this->actor_data($param,$res );
+            }
+            mac_echo('数据采集完成。');
+            die;
+        }
+
+        if(empty($GLOBALS['config']['app']['collect_timespan'])){
+            $GLOBALS['config']['app']['collect_timespan'] = 3;
+        }
+
+        if($show==1) {
+            if ($param['ac'] == 'cjsel') {
+                Cache::rm($key);
+                mac_echo('数据采集完成。');
+                unset($param['ids']);
+                $param['ac'] = 'list';
+                $url = url('api') . '?' . http_build_query($param);
+                $ref = $_SERVER["HTTP_REFERER"];
+                if(!empty($ref)){
+                    $url = $ref;
+                }
+                mac_jump($url, $GLOBALS['config']['app']['collect_timespan']);
+            } else {
+                if ($data['page']['page'] >= $data['page']['pagecount']) {
+                    Cache::rm($key);
+                    mac_echo('数据采集完成。');
+                    unset($param['page']);
+                    $param['ac'] = 'list';
+                    $url = url('api') . '?' . http_build_query($param);
+                    mac_jump($url, $GLOBALS['config']['app']['collect_timespan']);
+                } else {
+                    $param['page'] = intval($data['page']['page']) + 1;
+                    $url = url('api') . '?' . http_build_query($param);
+                    mac_jump($url, $GLOBALS['config']['app']['collect_timespan']);
+                }
+            }
+        }
+    }
+
 }
 }

+ 2 - 5
application/common/validate/Admin.php

@@ -7,20 +7,17 @@ class Admin extends Validate
     protected $rule =   [
     protected $rule =   [
         'admin_name'  => 'require|max:30',
         'admin_name'  => 'require|max:30',
         'admin_pwd'   => 'require',
         'admin_pwd'   => 'require',
-        '__token__'  =>  'require|token',
     ];
     ];
 
 
     protected $message  =   [
     protected $message  =   [
         'admin_name.require' => '名称必须',
         'admin_name.require' => '名称必须',
         'admin_name.max'     => '名称最多不能超过30个字符',
         'admin_name.max'     => '名称最多不能超过30个字符',
         'admin_pwd.require'   => '密码必须',
         'admin_pwd.require'   => '密码必须',
-        '__token__.require' => '非法提交',
-        '__token__.token'   => '请不要重复提交表单'
     ];
     ];
 
 
     protected $scene = [
     protected $scene = [
-        'add'  =>  ['__token__','admin_name','admin_pwd'],
-        'edit'  =>  ['__token__','admin_name'],
+        'add'  =>  ['admin_name','admin_pwd'],
+        'edit'  =>  ['admin_name'],
     ];
     ];
 
 
 }
 }

+ 1 - 1
application/extra/version.php

@@ -3,7 +3,7 @@ return array (
     'name' => '苹果CMS',
     'name' => '苹果CMS',
     'copyright' => 'MacCMS.LA',
     'copyright' => 'MacCMS.LA',
     'url' => '//www.maccms.la/',
     'url' => '//www.maccms.la/',
-    'code' => '2020.1000.1038',
+    'code' => '2020.1000.1039',
     'license' => '免费版',
     'license' => '免费版',
 );
 );
 ?>
 ?>

BIN
说明文档/火车头模块/苹果CMS10.x角色.wpm


BIN
说明文档/火车头模块/苹果CMS10.x评论.wpm