前言:还记得前些年,刚开始进入互联网时候,所有网站,基本标配jQuery,而且代码也没有任何加密,代码随便看,但是近几年,随着越来越多的人关注网络安全,不仅是服务器安全,各种前端也是开始研究各种压缩、混淆和各种加密,总之是尽一切可能保护自己的网站;当然所有的操作虽然能起到一定程度上保护网站的作用,但是所做的一切只不过是增加门槛而已!
这里我们将分析一系列的解析网站的解析原理,来看一下在他们的站点中前端加解密的应用,为什么选择这类网站呢?仔细分析就会发现在他们网站中充斥着各式各样提高扒代码或资源门槛的方法,很是值得分析,下面我们将从简单的开始一个个看他们的分析技巧。
原理分析:
我们选用一个目标站点来进行分析:
https://www.administratorw.com/index.php?url=
我们只需要在url=后面跟上参数(视频站链接),这种方式几乎是市面上所有解析站的格式。
首先加上视频平台平台播放链接打开,如:
https://www.administratorw.com/index.php?url=https://www.iqiyi.com/v_2ffkwswd6oo.html?vfrm=pcw_home&vfrmblk=L&vfrmrst=712211_dianyingbangbang_title1
这里我们用到的是Chrome浏览器,其他浏览器也是可以的,只不过对于开发者来讲,谷歌浏览器更加友好,我们通过浏览器发现链接打开后可能发现嵌套了一层iframe,这都没有关系,打开后解析网站解析出播放的视频,当然这不是重点,我们的重点是写一个爬虫可以解析任意vip视频的真实播放链接。
接下来我们先打开审查元素(快捷键F12或者Ctrl+Shift+I),打开审查元素的方法有多种,但是很多网站可能会屏蔽快捷键,我们也可以按照下面的截图所示打开开发者工具:
当开发者工具打开的一瞬间,你会发现有一个断点命中了,页面现在没办法操作,这是解析网站的防调试,而且这种操作几乎是是这类网站的标配,过滤掉这个很简单,我们只需要禁止断点执行,按下图操作,就可继续执行,就不会再断点了:
然后我们切换到network选项卡,然后刷新页面,我么会看到看到很多的请求,为了缩小范围,精确找到我们需要的东西我们进一步选择network下的xhr tab,发现请求只剩几个了(如果谷歌浏览器没有network选项,重置一下即可),
而其中有一个m3u8的请求就是我们需要获取的视频播放源地址,再继续往上就可以找到api.php这个接口,而视频播放源正是通过这个接口获取的,
我们看到该接口以post方式发送了7个参数:
url: https://www.iqiyi.com/v_2ffkwswd6oo.html?vfrm=pcw_home
referer: aHR0cHM6Ly93d3cuYWRtaW5pc3RyYXRvcnYuY29tL2lxaXlpL2luZGV4LnBocD91cmw9aHR0cHM6Ly93d3cuaXFpeWkuY29tL3ZfMmZma3dzd2Q2b28uaHRtbD92ZnJtPXBjd19ob21lJnZmcm1ibGs9TCZ2ZnJtcnN0PTcxMjIxMV9kaWFueWluZ2JhbmdiYW5nX3RpdGxlMQ==
ref: 0
time: 1595251830
type:
other: aHR0cHM6Ly93d3cuaXFpeWkuY29tL3ZfMmZma3dzd2Q2b28uaHRtbD92ZnJtPXBjd19ob21lJnZmcm1ibGs9TCZ2ZnJtcnN0PTcxMjIxMV9kaWFueWluZ2JhbmdiYW5nX3RpdGxlMQ==
ios:
除了refer和other字段其他的都很好理解,明文的嘛,其实对于refer和other字段我们一看就应该知道这个是base64编码,
refer解密后是:
https://www.administratorv.com/iqiyi/index.php?url=https://www.iqiyi.com/v_2ffkwswd6oo.html?vfrm=pcw_home&vfrmblk=L&vfrmrst=712211_dianyingbangbang_title1
refer也就是当前我们访问的地址,
other解密后是:
https://www.iqiyi.com/v_2ffkwswd6oo.html?vfrm=pcw_home&vfrmblk=L&vfrmrst=712211_dianyingbangbang_title1
refer正是待解析的vip视频播放地址,但是还有一个问题需要验证的就是time字段是发起请求的时间还是服务端发放的用于校验请求合法性的,通过追踪请求发起的代码我们确认该字段是由服务端发起用于校验的,追踪代码的方法如下:
我们只需要将鼠标移到当前请求的initiator选项上即可看到发起该请求的js堆栈,我们排除掉jquery等库的调用找到真实发起的地方这里是那个比较长的,然后点进去,发现代码是压缩的,我们可以通过浏览器的展开功能来美化代码:
通过这段代码,我们可以发现time字段是不能通过客户端伪造的,需要先拿到这个值才能正常的调用接口,这里有两种选择:
一、所有的请求参数都从页面提取
二、只提取time字段,剩下的字段由客户端生成
这里选择第二种方式,我们用node来演示,先获取服务端发送的time字段。
function getTime(u) {
return new Promise((resolve, reject) => {
request({
url: `https://www.administratorm.com/index.php?url=${u}`,
headers: {
Referer: `https://www.administratorm.com/index.php?url=${u}`
}
}, (err, response, body) => {
if (err) {
return reject(err);
}
const reg = /\'time\'\s*\:\s*\'(\d+)\'/;
if (reg.test(body)) {
return resolve(RegExp.$1);
}
reject();
});
});
}
在获取了time字段后我们就可以正常的发起请求了,我们先实现获取视频源的方法
function getVideoSource(u, time) {
return new Promise((resolve, reject) => {
const formData = {
url: u,
referer: Buffer.from(`https://www.administratorw.com/index.php?url=${u}`).toString('base64'),
ref: 0,
time,
type: '',
other: Buffer.from(u).toString('base64'),
ios: ''
};
request({
url: PARSE_API,
method: 'POST',
headers: {
Referer: `https://www.administratorm.com/index.php?url=${u}`
},
formData
}, (err, response, body) => {
if (err) {
return reject(err);
}
try {
const ret = JSON.parse(body);
if (ret.url) {
return resolve(ret.url);
}
reject();
} catch(e) {
reject(e);
}
});
});
}
然后发起请求,
getTime(url)
.then(time => {
getVideoSource(url, time)
.then(url => {
console.log('视频解析成功,播放源地址:%s', url)
});
})
.catch(err => {
console.log('视频解析失败!');
});
示例源码:
有能力可参考如下代码自行写构造:
没有能力可参考万能JSON视频解析:
本站提供了万能的PHP伪造源码,下载即用,请查看《二次万能JSON视频解析PHP代码》
常见问题:
1、在浏览器中我们可以通过atob方法解密base64字符串,btoa方法来得到解密的base64字符串。
2、伪造请求时如果参数正确但是请求不通,可以尝试看改变headers中字段,比如增加Referer,userAgent,X-Requested-With。
3、如果接口服务端对IP有限制,通过伪造X-Forwarded-For有一定几率可以绕过该限制。