本文章中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关。
二、目标地址
aHR0cHM6Ly93d3cuZGFtaXlzLmNjL3ZvZHBsYXkvMjItMy0xLmh0bWw=
三、解析思路
1、对于一般的免费影视站点,真实播放地址一般都可以通过Ctrl + U查看HTML源码找到。
① 在打开的源码标签页(即view-source:网址)中,通过Ctrl + F查找”.m3u8“或”.mp4“。
如果能找到”.m3u8“或”.mp4“URL地址并通过验证,那么恭喜你,证明这网站基本没有对视频地址加密.
比如以下这种:

m3u8.jpg (28.96 KB, 下载次数: 0)
下载附件
2025-5-24 17:13 上传
② 如果没找到”.m3u8“或”.mp4“相关明码视频地址,尝试搜索”aaa="。
(为什么?问就是见多了,很多免费影视站点都是var player_aaaa=声明载入明文或加密的播放地址)
2、通过HTML源码搜索”aaa="找到的是加密的播放地址,则需要F12 打开开发工具分析
本次目标网站就是通过”aaa="关键词找到相关加密地址.
这种就需要找出解密算法。
四、解密加密地址分析
1、先从HTML查找
对于本次目标站点地址,Ctrl + U的时候,遇到反调试检测机制。
没关系,咱们直接(view-source:aHR0cHM6Ly93d3cuZGFtaXlzLmNjL3ZvZHBsYXkvMjItMy0xLmh0bWw=)打开HTML源码搜索
尝试搜索”aaa="得到这段疑似被加密的播放地址:"JTY4JTc0JTc0JTcwJTczJTNBJTJGJTJGJTc2JTJFJTcxJTcxJTJFJTYzJTZGJTZEJTJGJTc4JTJGJTYzJTZGJTc2JTY1JTcyJTJGJTMyJTc3JTMyJTZDJTY1JTY3JTc0JTMwJTY3JTM4JTdBJTMyJTM2JTYxJTZDJTJGJTc1JTMwJTMwJTMyJTM5JTM2JTcwJTM2JTc0JTM1JTMwJTJFJTY4JTc0JTZEJTZD"

jiami.jpg (164.49 KB, 下载次数: 0)
下载附件
jiema
2025-5-25 02:41 上传
根据经验,这应该是Base64加密了,直接在当前窗口F12打开控制台使用atob(),比如输入atob("JTY4JTc0JTc0JTcwJTczJTNBJTJGJTJGJTc2JTJFJTcxJTcxJTJFJTYzJTZGJTZEJTJGJTc4JTJGJTYzJTZGJTc2JTY1JTcyJTJGJTMyJTc3JTMyJTZDJTY1JTY3JTc0JTMwJTY3JTM4JTdBJTMyJTM2JTYxJTZDJTJGJTc1JTMwJTMwJTMyJTM5JTM2JTcwJTM2JTc0JTM1JTMwJTJFJTY4JTc0JTZEJTZD"),得到明显是被转码的URL地址,再通过unescape()反转码,得到明文地址,但这个明显是某TX的播放地址,并非可以直接下载的真实地址。

atob.jpg (183.53 KB, 下载次数: 0)
下载附件
2025-5-25 02:43 上传
2、HTML找到的并非真实地址,需要F12打开浏览器开发工具调试解密
遭遇F12快捷键打不开(即反调试检测),我们直接手动打开。

你知道.jpg (25.42 KB, 下载次数: 0)
下载附件
2025-5-25 02:44 上传
发现反调试debugger代码是硬编码在HTML网页中的,咱们直接将相关代码注释掉(暴力破解方法),很幸运跳过反调试检测,没有进一步保护机制。

debugger.jpg (219.24 KB, 下载次数: 0)
下载附件
d1
2025-5-25 02:45 上传
比如修改成// debugger;,或者删除相关debugger代码然后保存。

debugger2.jpg (21.08 KB, 下载次数: 0)
下载附件
d2
2025-5-25 02:46 上传
刷新网页发现注释掉debugger生效,不再阻塞我们调试。
这时打开开发工具“网络”标签,刷新当前播放页重载,发现可疑的API入口https://jiexi.shipinbofang.net:7898/api.php ,而且名称就是请求地址包含“jiexi”(解析)字符串。

api.jpg (147.83 KB, 下载次数: 0)
下载附件
api1
2025-5-25 02:46 上传
这个时候,不管它是什么,我们都需要验证它的响应数据是不是真实地址数据包。
from DrissionPage import SessionPage
page = SessionPage()
def fetch_video_data():
"""
发送 POST 请求到指定的 URL,并返回响应数据
"""
url = "https://jiexi.shipinbofang.net:7898/api.php"
headers = {
"accept": "application/json, text/javascript, */*; q=0.01",
"accept-language": "zh-CN,zh;q=0.9,en;q=0.8",
"cache-control": "no-cache",
"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
"pragma": "no-cache",
"priority": "u=1, i",
"sec-ch-ua": "\"Chromium\";v=\"136\", \"Microsoft Edge\";v=\"136\", \"Not.A/Brand\";v=\"99\"",
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": "\"Windows\"",
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-origin",
"sec-fetch-storage-access": "active",
"x-requested-with": "XMLHttpRequest",
"User-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0"
}
body = "url=https://v.qq.com/x/cover/2w2legt0g8z26al/u00296p6t50.html&time=1748103938&key=5655407d56b0b456686eb2da7b620b21"
page.post(url, headers=headers, data=body)
return page.json
response_data = fetch_video_data()
print(response_data)
打印出的结果数据:
{'code': 200, 'msg': '请求成功', 'url': 'n8DB0IMAq13Am1RbWthn17mGLk1OnfZv2xHDeWUzc2QlBpQ1dkmNAgpC3FBy8bQCV4jb47ZB3uvKp2Eq8hVrHnrF+jQkGkTf9HOId/3bJzgPwfXKn4h2g5fVTVJZZHu39+Q5OnoUstVa8w5jLufcp896FJ/FUlxYQa3tWIzOhiZgC8nDaBN/Y+txr2b5u3ZVWnUkM7AB6wBDoDCjhc2OX/jRdBDArq6tOPu6iXb8emtUiNNlcsSggPprYlhLfrXXDGNeqkFjPqIqhkXFWBDHOCoEkMPQ8S91iZm47Q1p95Bk8F2VfcoPqkrsziEq7S91', 'type': 'm3u8', 'success': 1, 'time': '2025-05-25 00:44:01', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0', 'ip': '192.168.1.1'} # 为了保护隐私,IP地址已修改
一目了然,返回的数据包里面就包含了加密的真实地址,地址类型type:m3u8。
整理解码流程,发现就差找到key和time的生成方法,然后再找到解密被加密的真实地址url字符串,应该就大功告成了。
即:
五、寻找解密真实地址url的算法或方法
如何寻找?既然真实地址数据包是由https://jiexi.shipinbofang.net:7898/api.php 请求的发送的,那就看看它的上一级发起进程,即“发起程序”是什么。
在“发起程序”请求调用堆栈里面,看到了这个匿名的栈方法,点击进去。

匿用.jpg (79.92 KB, 下载次数: 0)
下载附件
匿用
2025-5-25 02:48 上传
真是太流畅了,基本没有做防护混淆的机制,直接就看到了key和time。

key.jpg (104.66 KB, 下载次数: 0)
下载附件
key
2025-5-25 03:04 上传
而且发现它的请求地址是https://jiexi.shipinbofang.net:7898/?url=https://v点qq点com/x/cover/XXX.html。
接下来我们只需要再次通过request或DrissionPage库的SessionPage请求网页响应内容,然后XPath或正则或其他方法,拿到key和time这两个字段:
from DrissionPage import SessionPage
page = SessionPage()
import re
def get_body_field(unescape_url: str) -> str | None:
api_url = f"https://jiexi.shipinbofang.net:7898/?url={unescape_url}"
headers = {"Referer": "https://jiexi.789jiexi.com/", "User-Agent": "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0"}
page.get(api_url, headers=headers, timeout=20, verify=False)
final_html_content = page.html
key_str = re.findall(r'"key":"(.*?)"', final_html_content)
time_str = re.findall(r'"time":"(.*?)"', final_html_content)
vkey = re.findall(r'"vkey":"(.*?)"', final_html_content)
if key_str and vkey:
key_str = key_str[0]
time_str = time_str[0]
vkey = vkey[0]
else:
return None
return key_str, time_str, vkey
key_str, time_str, vkey = get_body_field("https://v.qq.com/x/cover/2w2legt0g8z26al/u00296p6t50.html")
print("key_str: ", key_str, "time_str:", time_str, "vkey:", vkey)
打印结果:
key_str: 321ef14ec93dfe619f1803f29e49be10 time_str: 1748108226 vkey: cce139bcce3280bea8ed4626369b47da
将上述的结果key_str和time_str输入fetch_video_data()方法中的body负载,验证是否是API接口 https://jiexi.shipinbofang.net:7898/api.php 需要的time和key负载。验过发现'请求成功',并且返回了真实地址数据包:
{'code': 200, 'msg': '请求成功', 'url': 'n8DB0IMAq13Am1RbWthn17mGLk1OnfZv2xHDeWUzc2RAxgkcU1Xq6jmCHgycEIHKMwqGgVuafTQGpYmDB9xEOXE6yRXcawiUod7z1e2JeMxU2klBcUP95AcO3VDQXc5DkX6sLn3QFk/dV8h4E3guWjA0eRggAhokFVZkTNLIUp4b/mquxtgkpgv4rrH+HWY2Lx+u/1RFAlYlrt6wT+tq6SwHe3hiIQ4Upmzp9Zk/oIPte+w/fYViBhjoyRpTZd+ZNj1t96ItrKGgnTlyVjuHBv/vRtR8NunPGgFlOxaH3wF4KuBL4R4YjdNpT8WJB8D/', 'type': 'm3u8', 'success': 1, 'time': '2025-05-25 01:43:36', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0', 'ip': 'XXXX'}
到了这一步:
最后,就差从数据包中提取到的加密url如何解密了,即“n8DB0IMAq13Am1RbWthn17mGLk1OnfZv2xHDeWUzc2RAxgkcU1Xq6jmCHgycEIHKMwqGgVuafTQGpYmDB9xEOXE6yRXcawiUod7z1e2JeMxU2klBcUP95AcO3VDQXc5DkX6sLn3QFk/dV8h4E3guWjA0eRggAhokFVZkTNLIUp4b/mquxtgkpgv4rrH+HWY2Lx+u/1RFAlYlrt6wT+tq6SwHe3hiIQ4Upmzp9Zk/oIPte+w/fYViBhjoyRpTZd+ZNj1t96ItrKGgnTlyVjuHBv/vRtR8NunPGgFlOxaH3wF4KuBL4R4YjdNpT8WJB8D/"
(其实有经验的话,一看就知道是AES加密的)
别急,理清头绪,因为这个数据包是由API接口"https://jiexi.shipinbofang.net:7898/api.php" 解析得到的,重新返回查看API的调用“发起程序”,发现请求调用堆栈”start“(为什么选择这个?因为按照堆栈顺序来,key和time是从”匿名"程序栈得到的,它的上一级就是“start",而且字面意思也太明显了,就是解析的”开始“)。

start.jpg (76.47 KB, 下载次数: 0)
下载附件
2025-5-25 02:50 上传
不得不说,这个网站的加密防护手段实在是太“高级”了,生怕别人不知道。
这个就是 -> url: decrypt(stray.url), /视频播放地址/

start1.jpg (42.57 KB, 下载次数: 0)
下载附件
start2
2025-5-25 02:51 上传
废话不多说,直接Ctrl + F查找“decrypt”,找到了解密的方法!如下:

start3.jpg (41.14 KB, 下载次数: 0)
下载附件
start3
2025-5-25 02:52 上传
转成Python的方法,并且同时打印验证,就是:
from Crypto.Cipher import AES
import base64
def decrypt_aes_cbc_base64(text: str) -> str:
"""
使用 AES-CBC 解密 Base64 编码的密文。
:param text: Base64 编码的密文
:return: 解密后的明文
"""
key = b'ARTPLAYERliUlanG' # key16位
iv = b'ArtplayerliUlanG' # iv16位
ciphertext = base64.b64decode(text)
cipher = AES.new(key, AES.MODE_CBC, iv)
padded = cipher.decrypt(ciphertext)
pad_len = padded[-1]
return padded[:-pad_len].decode("utf-8")
print(decrypt_aes_cbc_base64("n8DB0IMAq13Am1RbWthn17mGLk1OnfZv2xHDeWUzc2RAxgkcU1Xq6jmCHgycEIHKMwqGgVuafTQGpYmDB9xEOXE6yRXcawiUod7z1e2JeMxU2klBcUP95AcO3VDQXc5DkX6sLn3QFk/dV8h4E3guWjA0eRggAhokFVZkTNLIUp4b/mquxtgkpgv4rrH+HWY2Lx+u/1RFAlYlrt6wT+tq6SwHe3hiIQ4Upmzp9Zk/oIPte+w/fYViBhjoyRpTZd+ZNj1t96ItrKGgnTlyVjuHBv/vRtR8NunPGgFlOxaH3wF4KuBL4R4YjdNpT8WJB8D/"))
得到的解密结果,获得真实视频地址(可下载,可使用MPV播放):
https://ts.key.shipinbofang.net:4433/vod/b3nfBCJhTIVrub7CBjiBF%2F97ychxYHKnq3g6e4Q6dL1jy2FU91oO%2BKzmt8B%2BTBSqxF0wPPkWMvgKTwrrAdzADh%2ByqGuo69%2FEvchMa6J%2FeLKJZqQu5Ssu6GYlEjZ1y%2FwysqrLRBuF9q7w1cbQwmbAcpQ2IsdLLhHJzWs2DIGIJK0%3D.m3u8

start4.jpg (222.28 KB, 下载次数: 0)
下载附件
2025-5-25 02:52 上传