笔者博客上的地址
前言
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('' + '' + '
');
this.Height = $('.MacPlayer').get(0).offsetHeight;
this.Width = $('.MacPlayer').get(0).offsetWidth;
document.write(' ')
},
'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 += '' + name + ' '
}
this.RightList += '' + mac_show[from] + '
' + '' + listr + '
'
}
},
'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 = '' + this.RightList + '';
$("#playleft").get(0).innerHTML = '' + this.Html + '';
document.write(' ')
},
'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('');
document.write(' ')
},
'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', '');
更改为:
$this->assign('player_js', '');
曲折的劫持位置分析和修复过程
见作者博客