记苹果CMS播放页被劫持跳转至棋牌网站的解决方案

笔者博客上的地址

前言

2019年五月下旬,苹果CMS建站用户陆续出现播放页被劫持至棋牌网站的现象。本文将从笔者自身的分析方式出发,剖析CMS作者有意留下的JS漏洞位置和活加载外部JS的全部过程。多事之秋,以华为为代表的一批我国创新型企业不惧外部施压,用铁打的技术和超脱常人的眼界证明了中华儿女的不屈于人,从保险柜里拿出的自主研发备份芯片与操作系统展现了中华民族的铮铮铁骨。我作为一名流淌着中华血液的开发者为此感到深深的自豪,反观苹果CMS开发者,明知自己CMS的用户基础水平不足,却有意在源码中留下漏洞,不顾源码口碑和未来发展,强制劫持用户的访问,将罪恶之手伸向本国同胞。其心态之扭曲,实为汉语言文化圈开发者的最大耻辱。Shame On You!疑似苹果CMS作者老王前日在笔者blog留言称是苹果CMS网站域名17号晚遭到劫持所致。但正是因为苹果CMS在使用者不知情的情况下使用加密的js文件调用了外部地址才为这次影响广泛的劫持事件埋下了伏笔,笔者建议大家无论怎样都要修改相关文件并本地化全部资源以防以后再出现其他情况!

解决方案

22日再次更新:预加载页面也被劫持,须在后台--系统设置--播放器参数设置下将 预加载广告:缓冲广告:两项的内容全部删除,版本不同也相应寻找预加载和缓冲地址类似的选项删除即可
为了方便大家对两个页面的调用,同时也将无广告版本的干净页面上传到了GitHub上,大家本地化这两个文件即可~

为节省大家的时间笔者先贴出解决方案如下:
为节省大家时间,两个文件均已上传GitHub,大家直接下载即可!
Github地址:
点击此处
1.更改网站根目录/static/js/player.js下的文件,为如下内容
对于v10版本用户

var MacPlayer = {
    'GetUrl': function(s, n) {
        return this.Link.replace('{sid}', s).replace('{sid}', s).replace('{nid}', n).replace('{nid}', n)
    },
    'Go': function(s, n) {
        location.href = this.GetUrl(s, n)
    },
    'Show': function() {
        $('#buffer').attr('src', this.Prestrain);
        setTimeout(function() {
            MacPlayer.AdsEnd()
        }, this.Second * 1000);
        $("#playleft").get(0).innerHTML = this.Html + '';
        var a = document.createElement('script');
        a.type = 'text/javascript';
        a.async = true;
        a.charset = 'utf-8';
        a.src = '';
        var b = document.getElementsByTagName('script')[0];
        b.parentNode.insertBefore(a, b)
    },
    'AdsStart': function() {
        if ($("#buffer").attr('src') != this.Buffer) {
            $("#buffer").attr('src', this.Buffer)
        }
        $("#buffer").show()
    },
    'AdsEnd': function() {
        $('#buffer').hide()
    },
    'Install': function() {
        this.Status = false;
        $('#install').show()
    },
    'Play': function() {
        document.write('<style>.MacPlayer{background: #000000;font-size:14px;color:#F6F6F6;margin:0px;padding:0px;position:relative;overflow:hidden;width:100%;height:100%;min-heigh:300px;}.MacPlayer table{width:100%;height:100%;}.MacPlayer #playleft{position:inherit;!important;width:100%;height:100%;}</style><div class="MacPlayer">' + '<iframe id="buffer" src="" frameBorder="0" scrolling="no" width="100%" height="100%" style="position:absolute;z-index:99998;"></iframe><iframe id="install" src="" frameBorder="0" scrolling="no" width="100%" height="100%" style="position:absolute;z-index:99998;display:none;"></iframe>' + '<table border="0" cellpadding="0" cellspacing="0"><tr><td id="playleft" valign="top" style="">&nbsp;</td></table></div>');
        this.Height = $('.MacPlayer').get(0).offsetHeight;
        this.Width = $('.MacPlayer').get(0).offsetWidth;
        document.write('<scr' + 'ipt src="' + this.Path + this.PlayFrom + '.js"></scr' + 'ipt>')
    },
    'Down': function() {},
    'Init': function() {
        this.Status = true;
        this.Parse = '';
        if (player_data.encrypt == '1') {
            player_data.url = unescape(player_data.url);
            player_data.url_next = unescape(player_data.url_next)
        } else if (player_data.encrypt == '2') {
            player_data.url = unescape(base64decode(player_data.url));
            player_data.url_next = unescape(base64decode(player_data.url_next))
        }
        this.Prestrain = MacPlayerConfig.prestrain;
        this.Buffer = MacPlayerConfig.buffer;
        this.Second = MacPlayerConfig.second;
        this.Flag = player_data.flag;
        this.Trysee = player_data.trysee;
        this.Points = player_data.points;
        this.Link = decodeURIComponent(player_data.link);
        this.PlayFrom = player_data.from;
        this.PlayNote = player_data.note;
        this.PlayServer = player_data.server == 'no' ? '' : player_data.server;
        this.PlayUrl = player_data.url;
        this.PlayUrlNext = player_data.url_next;
        this.PlayLinkNext = player_data.link_next;
        this.PlayLinkPre = player_data.link_pre;
        if (MacPlayerConfig.server_list[this.PlayServer] != undefined) {
            this.PlayServer = MacPlayerConfig.server_list[this.PlayServer].des
        }
        if (MacPlayerConfig.player_list[this.PlayFrom] != undefined) {
            if (MacPlayerConfig.player_list[this.PlayFrom].ps == "1") {
                this.Parse = MacPlayerConfig.player_list[this.PlayFrom].parse == '' ? MacPlayerConfig.parse : MacPlayerConfig.player_list[this.PlayFrom].parse;
                this.PlayFrom = 'parse'
            }
        }
        this.Path = maccms.path + '/static/player/';
        if (this.Flag == "down") {
            MacPlayer.Down()
        } else {
            MacPlayer.Play()
        }
    }
};

MacPlayer.Init();

对于v8版本用户:

window.onresize = function() {
    if (window.name == "macopen1") {
        MacPlayer.Width = $(window).width() - $(".MacPlayer").offset().left - 15;
        MacPlayer.HeightAll = $(window).height() - $(".MacPlayer").offset().top - 15;
        MacPlayer.Height = MacPlayer.HeightAll;
        if (mac_showtop == 1) {
            MacPlayer.Height -= 20
        }
        $(".MacPlayer").width(MacPlayer.Width);
        $(".MacPlayer").height(MacPlayer.HeightAll);
        $("#buffer").width(MacPlayer.Width);
        $("#buffer").height(MacPlayer.HeightAll);
        $("#Player").width(MacPlayer.Width);
        $("#Player").height(MacPlayer.Height)
    }
}
;
var MacPlayer = {
    'GoPreUrl': function() {
        if (this.Num > 0) {
            this.Go(this.Src + 1, this.Num)
        }
    },
    'GetPreUrl': function() {
        return this.Num > 0 ? this.GetUrl(this.Src + 1, this.Num) : ''
    },
    'GoNextUrl': function() {
        if (this.Num + 1 != this.PlayUrlLen) {
            this.Go(this.Src + 1, this.Num + 2)
        }
    },
    'GetNextUrl': function() {
        return this.Num + 1 <= this.PlayUrlLen ? this.GetUrl(this.Src + 1, this.Num + 2) : ''
    },
    'GetUrl': function(s, n) {
        return mac_link.replace('{src}', s).replace('{src}', s).replace('{num}', n).replace('{num}', n)
    },
    'Go': function(s, n) {
        location.href = this.GetUrl(s, n)
    },
    'GetList': function() {
        this.RightList = '';
        for (i = 0; i < this.Data.from.length; i++) {
            from = this.Data.from[i];
            url = this.Data.url[i];
            listr = "";
            sid_on = 'h2';
            sub_on = 'none';
            urlarr = url.split('#');
            for (j = 0; j < urlarr.length; j++) {
                urlinfo = urlarr[j].split('$');
                name = '';
                url = '';
                list_on = '';
                from1 = '';
                if (urlinfo.length > 1) {
                    name = urlinfo[0];
                    url = urlinfo[1];
                    if (urlinfo.length > 2) {
                        from1 = urlinfo[2]
                    }
                } else {
                    name = "第" + (j + 1) + "集";
                    url = urlinfo[0]
                }
                if (this.Src == i && this.Num == j) {
                    sid_on = 'h2_on';
                    sub_on = 'block';
                    list_on = "list_on";
                    this.PlayUrlLen = urlarr.length;
                    this.PlayUrl = url;
                    this.PlayName = name;
                    if (from1 != '') {
                        this.PlayFrom = from1
                    }
                    if (j < urlarr.length - 1) {
                        urlinfo = urlarr[j + 1].split('$');
                        if (urlinfo.length > 1) {
                            name1 = urlinfo[0];
                            url1 = urlinfo[1]
                        } else {
                            name1 = "第" + (j + 1) + "集";
                            url1 = urlinfo[0]
                        }
                        this.PlayUrl1 = url1;
                        this.PalyName1 = name1
                    }
                }
                listr += '<li><a class="' + list_on + '" href="javascript:void(0)" onclick="MacPlayer.Go(' + (i + 1) + ',' + (j + 1) + ');return false;" >' + name + '</a></li>'
            }
            this.RightList += '<div id="main' + i + '" class="' + sid_on + '"><h2 onclick="MacPlayer.Tabs(' + i + ',' + (this.Data.from.length - 1) + ')">' + mac_show[from] + '</h2>' + '<ul id="sub' + i + '" style="display:' + sub_on + '">' + listr + '</ul></div>'
        }
    },
    'ShowList': function() {
        $('#playright').toggle()
    },
    'Tabs': function(a, n) {
        var b = $('#sub' + a).css('display');
        for (var i = 0; i <= n; i++) {
            $('#main' + i).attr('className', 'h2');
            $('#sub' + i).hide()
        }
        if (b == 'none') {
            $('#sub' + a).show();
            $('#main' + a).attr('className', 'h2_on')
        } else {
            $('#sub' + a).hide()
        }
    },
    'Show': function() {
        if (mac_showtop == 0) {
            $("#playtop").hide()
        }
        if (mac_showlist == 0) {
            $("#playright").hide()
        }
        setTimeout(function() {
            MacPlayer.AdsEnd()
        }, this.Second * 1000);
        $("#topdes").get(0).innerHTML = '' + '正在播放:' + this.PlayName + '';
        $("#playright").get(0).innerHTML = '<div class="rightlist" id="rightlist" style="height:' + this.Height + 'px;">' + this.RightList + '</div>';
        $("#playleft").get(0).innerHTML = '<iframe id="buffer" src="' + this.Prestrain + '" frameBorder="0" scrolling="no" width="100%" height="' + this.Height + '" style="position:absolute;z-index:99998;"></iframe>' + this.Html + '';
        document.write('<scr' + 'ipt src="' + '//union.maccms.com/html/top.js' + '"></scr' + 'ipt>')
    },
    'ShowBuffer': function() {
        var w = this.Width - 100;
        var h = this.Height - 100;
        var l = (this.Width - w) / 2;
        var t = (this.Height - h) / 2 + 20;
        $(".MacBuffer").css({
            'width': w,
            'height': h,
            'left': l,
            'top': t
        });
        $(".MacBuffer").toggle()
    },
    'AdsEnd': function() {
        $('#buffer').hide()
    },
    'Install': function() {
        this.Status = false;
        $('#install').parent().show();
        $('#install').show()
    },
    'Play': function() {
        var a = mac_colors.split(',');
        document.write('<style>.MacPlayer{background: #' + a[0] + ';font-size:14px;color:#' + a[1] + ';margin:0px;padding:0px;position:relative;overflow:hidden;width:' + (this.Width == 0 ? '100%' : this.Width + 'px') + ';height:' + this.HeightAll + 'px;}.MacPlayer a{color:#' + a[2] + ';text-decoration:none}a:hover{text-decoration: underline;}.MacPlayer a:active{text-decoration: none;}.MacPlayer table{width:100%;height:100%;}.MacPlayer ul,li,h2{ margin:0px; padding:0px; list-style:none}.MacPlayer #playtop{text-align:center;height:20px; line-height:21px;font-size:12px;}.MacPlayer #topleft{width:150px;}.MacPlayer #topright{width:100px;} .MacPlayer #topleft{text-align:left;padding-left:5px}.MacPlayer #topright{text-align:right;padding-right:5px}.MacPlayer #playleft{width:100%;height:100%;overflow:hidden;}.MacPlayer #playright{height:100%;overflow-y:auto;}.MacPlayer #rightlist{width:120px;overflow:auto;scrollbar-face-color:#' + a[7] + ';scrollbar-arrow-color:#' + a[8] + ';scrollbar-track-color: #' + a[9] + ';scrollbar-highlight-color:#' + a[10] + ';scrollbar-shadow-color: #' + a[11] + ';scrollbar-3dlight-color:#' + a[12] + ';scrollbar-darkshadow-color:#' + a[13] + ';scrollbar-base-color:#' + a[14] + ';}.MacPlayer #rightlist ul{ clear:both; margin:5px 0px}.MacPlayer #rightlist li{ height:21px; line-height:21px;overflow: hidden; text-overflow: ellipsis; white-space: nowrap;}.MacPlayer #rightlist li a{padding-left:15px; display:block; font-size:12px}.MacPlayer #rightlist h2{ cursor:pointer;font-size:13px;font-family: "宋体";font-weight:normal;height:25px;line-height:25px;background:#' + a[3] + ';padding-left:5px; margin-bottom:1px}.MacPlayer #rightlist .h2{color:#' + a[4] + '}.MacPlayer #rightlist .h2_on{color:#' + a[5] + '}.MacPlayer #rightlist .ul_on{display:block}.MacPlayer #rightlist .list_on{color:#' + a[6] + '} </style><div class="MacPlayer"><table border="0" cellpadding="0" cellspacing="0"><tr><td colspan="2"><table border="0" cellpadding="0" cellspacing="0" id="playtop"><tr><td width="100" id="topleft"><a target="_self" href="javascript:void(0)" onclick="MacPlayer.GoPreUrl();return false;">上一集</a> <a target="_self" href="javascript:void(0)" onclick="MacPlayer.GoNextUrl();return false;">下一集</a></td><td id="topcc"><div id="topdes" style="height:26px;line-height:26px;overflow:hidden"></div></td><td width="100" id="topright"><a target="_self" href="javascript:void(0)" onClick="MacPlayer.ShowList();return false;">开/关列表</a></td></tr></table></td></tr><tr style="display:none"><td colspan="2" id="install" style="display:none"></td></tr><tr><td id="playleft" valign="top">&nbsp;</td><td id="playright" valign="top">&nbsp;</td></tr></table></div>');
        document.write('<scr' + 'ipt src="' + this.Path + this.PlayFrom + '.js"></scr' + 'ipt>')
    },
    'Down': function() {},
    'Init': function() {
        this.Status = true;
        this.Url = location.href;
        this.Par = location.search;
        this.Data = {
            'from': mac_from.split('$$$'),
            'server': mac_server.split('$$$'),
            'note': mac_note.split('$$$'),
            'url': mac_url.split('$$$')
        };
        var c = navigator.userAgent.toLowerCase();
        this.Width = window.name == 'macopen1' ? mac_widthpop : (mac_width == 0 ? '100%' : mac_width);
        this.HeightAll = window.name == 'macopen1' ? mac_heightpop : mac_height;
        if (c.indexOf("android") > 0 || c.indexOf("mobile") > 0 || c.indexOf("ipod") > 0 || c.indexOf("ios") > 0 || c.indexOf("iphone") > 0 || c.indexOf("ipad") > 0) {
            this.Width = window.name == 'macopen1' ? mac_widthpop : (mac_widthmob == 0 ? '100%' : mac_widthmob);
            this.HeightAll = window.name == 'macopen1' ? mac_heightpop : mac_heightmob
        }
        this.Height = this.HeightAll;
        if (mac_showtop == 1) {
            this.Height -= 20
        }
        if (this.Url.indexOf('#') > -1) {
            this.Url = this.Url.substr(0, this.Url.indexOf('#'))
        }
        this.Prestrain = mac_prestrain;
        this.Buffer = mac_buffer;
        this.Second = mac_second;
        this.Flag = mac_flag;
        var a = this.Url.match(/\d+.*(htm)/g)[0].match(/\d+/g);
        if (a.length < 3) {
            a = this.Url.match(/\d+.*/g)[0].match(/\d+/g)
        }
        var b = a.length;
        this.Id = a[(b - 3)] * 1;
        this.Src = a[(b - 2)] * 1 - 1;
        this.Num = a[(b - 1)] * 1 - 1;
        this.PlayFrom = this.Data.from[this.Src];
        this.PlayServer = this.Data.server[this.Src] == 'no' ? '' : mac_show_server[this.Data.server[this.Src]];
        this.PlayNote = this.Data.note[this.Src];
        this.GetList();
        this.NextUrl = this.GetNextUrl();
        this.PreUrl = this.GetPreUrl();
        this.Path = SitePath + 'player/';
        if (this.Flag == "down") {
            MacPlayer.Down()
        } else {
            MacPlayer.Play()
        }
    }
};

2.(非必须项,此项的目的是让js的更改忽略部分CDN和浏览器缓存,此处以v10为例)更改/application/common/controller/all.php中的第429行以使得JS更改即时对所有用户生效
原429行为:

 $this->assign('player_js', '<script src="' . MAC_PATH . 'static/js/playerconfig.js"></script><script src="' . MAC_PATH . 'static/js/player.js"></script>');

更改为:

 $this->assign('player_js', '<script src="' . MAC_PATH . 'static/js/playerconfig.js?'. date("Ymdhis") . '"></script><script src="' . MAC_PATH . 'static/js/player.js?'. date("Ymdhis") . '"></script>');

曲折的劫持位置分析和修复过程

见作者博客

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容