aHR0cHM6Ly93d3cuNTJobnR2LmNvbS8=
帖子包含大量图文, 流量党慎入
正文开始:

0x01: *长资源(aHR0cHM6Ly9jenNwcC5jb20v)
首先打开站点之后F12打开调试工具, 首页推荐这里看到<魔女2>, 那就进去吧, 女主好像是韩版黑凤凰?
aHR0cHM6Ly9jenNwcC5jb20vdl9wbGF5L2JYWmZNVFl6TFc1dFh6RT0uaHRtbA==
嗯????

下载地址直接甩脸上了? 看不到看不到, 我们继续

进去之后调试工具切换到network, 看看下面很多文件被加载出来, 往下右键-新窗口打开, 额, 好像是个完整的视频文件, 这下省事了, 都不用合并ts了, 另外这图(视频?)床好像是抖音的?


把下载链接复制出来, 然后把文件名(7e4ddedad13144d997c2caa255cbbdc2)放进去搜索一下, 第一个文件点进去, 在右边的headers面板里可以看到这条请求的响应码是302, 就是说视频链接(图片里的4)就是通过这条链接302重定向过去的, 只要找到这条链接的来源可以了

把地址复制起来, 然后搜索后面那段, 搜索不到任何结果, 查一下堆栈调用也找不到什么东西(这里卡了好久,主要是没有思绪)

搜索不到值一般是参数加密了, JS混淆等等, 那就搜索解密关键字 decrypt, 第一个结果跟进去一下

格式化后下断点, 这里断点要下在返回结果这里, 因为我们不知道这段解密后的结果是不是想要的, 不然分析了半天加密逻辑, 解出来的结果不是自己想要的岂不是尴尬??

刷新网页, 被断下来了, 鼠标放上去这段return结果里, 显示出来是一段html代码

注意这里的url, 把他记下来, 然后回去network选项卡这里对一下链接是不是一致(每次刷新链接会变, 所以要刷新后回去network重新看), 发现这里啥都看不到

为什么? 因为这段html在插入之前被断下来了, 所以记下记过后要马上放行这个断点, 再回来看可以看到确实有一个94TQ的请求

但是403了, 可能是刚才憋太久了,失效了, 重新刷新, 记下结果之后马上放行, 这次解密后的链接结尾是RtVw

回去network那里看看

确实有这个RtVw的链接被请求了, 而且仔细对比的话,链接是一摸一样的, 也就是说这段解密后的结果就是我们要的
看一下他的加密逻辑, 这里可以看到一段 AES.decrypt, 说明是用AES加密的, 虽然我的JS不咋滴, 但是吧, python里的AES解密需要什么我还是知道的, 16位key、16位IV偏移量(CBC)、加密方式以及密文
IV和加密方式(CBC)以及密文都甩脸上了, 没什么好说的, 这里有一个"23bc7c424c6abc75", 这里假设他是key

这里padding的话查了资料后知道 AES的区块长度固定为128比特, 即是说被AES加密的数据都是128比特, 假如加密数据是256比特, 那就刚好切成两块来加密, 但是需要加密的数据总不可能都是刚好是128的倍数吧, 当数据是250比特的时候就必须找点东西来填充一下保证数据是128倍数, 这个padding就是填充的, 话题走远了, 有兴趣自己搜索AES加密标准
以上数据找到之后不要急着用python去实现, 因为我们都是猜测的, 得先来验证一下是否正确, 找个在线AES加密的网站试试水.
这里的密文是d89e1b(变量名每次刷新会变,以实际网页为准)太长不好复制的话可以在console打印出来

复制出来后把所有数据到网站进行解密

一切都和预想的一致, 多刷新几次网页后IV是写死的, 也就是说不用我们去挖, 直接定义死就行了, KEY需要从网页里匹配出来
接下来就找找这段内容是在那个页面里的, 右键复制文件名, 记得把后面的:formatted删了,这是使用chrome格式化代码后自动产生的后缀, 因为是找文件, 直接在过滤器里过滤一下就行了, 其实这个第一个打开的网页, 看调试器顶部就可以看得出来了

所有东西都找到了, 接下来就是使用python来实现获取这些数据了
1. 获取加密数据和KEY 直接requests请求下来之后用re匹配, re表达式怎么写大家各显神通就行, 能匹配出来就好

2. python 实现AES解密, 代码如下

3. 解密出来的video里的url就是我们需要的 但是要记住, 这个解密出来的链接具有时效性, 几分钟就是失效了, 而且如果访问错一次就会立即失效(别问我怎么知道的!!)

4. 第2那堆<0x0f>什么的, 之前我也有疑惑, 在我上一帖 https://www.52pojie.cn/thread-1680708-2-1.html 的19楼大佬已经给了解答, 有兴趣的自己再去了解吧, 被我注释掉的那一段可以解决这个问题, 但是因为没影响, 所以也就不处理了.

5. 提取解密后的链接, 这个也是re匹配的问题, 没啥好说的.
就这样结束了嘛?
再找一部电影来试试, 选这部"咒"吧, 地址: aHR0cHM6Ly9jenNwcC5jb20vdl9wbGF5L2JYWmZNVEE1TkRjdGJtMWZNUT09Lmh0bWw=
解析出来的结果是m3u8, 那就加个判断把, 如果链接包含m3u8我们就继续发起请求, 把m3u8内容请求下来

复制其中一段ts切片用浏览器打开, 果然放不了, 图片?

右键保存, 直接放winhex看看, 图片伪装, 选中图片头删掉再保存, 用potplayer打开, 完美.


这里怎么切? 切多少? 用python怎么实现? 这个问题我也问过, 也是在我那张帖子里, 11楼大佬提供了一个方案, 这里直接copy他的代码过来(没想到吧,其实我也是菜鸟来着,很多问题我也不会), 这里直接贴代码出来, 有兴趣的去我上一帖慢慢看.
这里只下载一个切片就break循环, 因为只是示范, 没必要全部下载, 运行完之后会在同级目录下生成一个叫做0.ts的文件, 用potplayer打开, 正常播放
再换一个电影试试, 选个神探大战, 运行完播放一下, OK.

再换一部蜘蛛侠英, 也没问题

打完收工了, 至于ts合并问题, 这里就不多说了, 去看上一帖或者用逍遥大佬的m3u8下载器(话说真想下载的话, 网站已经把视频下载地址给出来了啊)
python代码:
[Python] 纯文本查看 复制代码
?
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
import requests import re import os import base64 from Crypto.Cipher import AES def download(url): page_ = requests.get(url) link = re.findall(r 'var w{6}="(.*?)";var' ,page_.text)[ 0 ] key = re.findall(r 'var w{6}=md5.enc.Utf8.parse("(w+)");' ,page_.text)[ 0 ] iv = '1234567890983456' encrypt_ = AES.new(key.encode(),AES.MODE_CBC,IV = iv.encode()) encry_url = base64.decodebytes(link.encode()) decrypt_ = encrypt_.decrypt(encry_url) # decrypt_ = decrypt_[:-decrypt_[-1]] decrypt_ = str (decrypt_, 'utf-8' ) url = re.findall(r 'video: {url: "(.*?)"' ,decrypt_)[ 0 ] print (url) if url.find( '.m3u8' ) = = - 1 : pass else : m3u8 = requests.get(url).text m3u8 = re.sub(r '#EX.*' ,'',m3u8).split() lenght = len (m3u8) for index in range (lenght): with open (f '{index}.ts' , 'wb' ) as f: ts_stream = requests.get(m3u8[index]).content if ts_stream[: 4 ] = = b 'x89PNG' or ts_stream[: 2 ] = = bytes.fromhex( '424D' ) or ts_stream[: 2 ] = = bytes.fromhex( 'FFD8' ): ts_start = ts_stream.find(b 'G@' ) ts_stream = ts_stream[ts_start:] f.write(ts_stream) break url = 'https://{自己换成主域名}/v_play/bXZfMTA5NDctbm1fMQ==.html' download(url) |

0x02: *团影视(aHR0cHM6Ly93d3cuZmFudHVhbmhkLmNvbQ==)
其实一开始是先找到这个网站的, 不过一顿分析之后真的找不出在哪里加密所以就把这个网站搁置了, 这个网站用了混淆, 我没有学过相关处理方法, 所以搞不定, 后来找到了上面那个网站后再回来看这个网站, 发现两个有异曲同工之妙, 所以也就解决了(然而混淆我还是不懂得如何处理!!)
选一部经典的<怦然心动>
aHR0cHM6Ly93d3cuZmFudHVhbmhkLmNvbS9wbGF5L2lkLTMxNi0xLTEuaHRtbA==
老方法, 点开视频之后随便拖动几次进度条, 观察network这里有什么文件被请求下来, 可以看到都是一堆相同文件名且后缀为mp4的, 猜的没错的话应该是完整的视频文件, 不是切片

右键新窗口打开, 确实是完整的视频文件, 图床还是西瓜视频的

接下来找找链接生成位置, 然后链接的一部分去搜索一下, 然而不管我怎么搜都无法搜索到, 堆栈调用这里也是什么都没有



那就只能去翻一翻请求下来的所有文件了, 好在东西不多, 随便晃啊晃, 看到了一个有趣的东西, 这里可以看到很多信息并且还有注释, 但是最重要的urls被加密了

看到有两个等号结尾, 下意识反应就是base64编码, 找个在线解码的网站, 看来不是base64编码的

那就全局搜索decrypt试试, 第一个结果点进去, 看到这个iv啊,mode啊有没有一种很熟悉的感觉?

其实我第一次逆向的时候就已经看到这些了, 但是后面都是一堆加密的JS代码, 看的我头都大了, 所以就选择性忽略掉了
和上面那个网站一样, 这里下个断点, 不过不知道哪里才是解密后的结果, 所以宁杀错不放过, 这个区域都给断下来, 刷新网页, 额, 发现没有触发断点, 那可能是在其他位置也有同样的加密, 再页面里搜索'iv', 有四个结果匹配到, 但是我不知道是在哪个进行加密的, 那就四个位置全部打上断点

再刷新, 这次终于抓到了, 但是都是乱码怎么看呢?

把鼠标放上去, 比如放mode这里, 可以看到这串乱码的值是"CBC"

'mode': CryptoJS['mode'][_0x5bf4('0x945', '$VA#')]
上面代码相当于下面的
'mode': CryptoJS['mode']["CBC"]
同样把鼠标放上去,可以看到

CryptoJS[_0x5bf4('0x93c', '[ZFb')]['decrypt']
等于
CryptoJS["AES"]['decrypt']
答案很明显了, AES加密, 模式为CBC, IV的值同样可以用鼠标来确认为 c487eb12e38a0fa0

需要解密的字符串为 "t9GkQwf" 开头的字符串, key为 0f84ff0c1f252cba


万事俱备, 马上找个在线解密的试试我们的判断, 可以正常解密

解密后的链接也是可以打开, 接下来找找密文的来源, 搜索"t9GkQwf"看看, 结果只有一个, 这个不就是刚才打开的那个页面嘛?

接下来找找这个页面又是从哪里来的, 复制网页链接, 搜索一下, 可以看到来源是网站首页的一个 player_aaaa 后面的内容

所有内容都找到来源来, 轮到python隆重登场了, 挖出出来player_aaaa之后我们只要url里面的, 那就用字典键值取出来就行了


取出来之后在观察一下第二次请求的链接结构, 某个域名+刚取出来的url+一堆参数

先不管参数, 把域名和刚才的url拼接一下试试看, 返回"域名未授权!"

回去浏览器看看他是怎么发起请求的, 这里有一个referer, 我们加回去给他, 这次有内容出来了, 但是我们需要的urls值怎么空了?


链接加个"&from=uploadixigua"回去之后发现可以正常请求了

那就不能偷懒了, 得把from值补齐, 他和url一样来源player_aaaa这里(不信你划上去看看刚才的截图), 补齐后是这样子的, 密文找好了,接下来就开始解密, key和iv试了几次, 发现是写死的, 我们跟着写死就行, urls的匹配不说了(很简单), AES实例化也不说了, 分析上一个网站时说过了, 最后正常解密, 链接可以正常打开, 试了其他视频也能正常解析

有些是m3u8, 要下载就用下载器吧, 不多说了. 打完收工.

python示例:
[Python] 纯文本查看 复制代码
?
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
import requests import re import base64 import os from Crypto.Cipher import AES import json def downlaods(url): page_ = requests.get(url).text data_ = re.findall(r 'player_aaaa=({.*?})</script>' ,page_)[ 0 ] data_ = json.loads(data_) url = data_[ 'url' ] second_url = f 'https://dp.1010dy.cc/?url={url}&from={data_["from"]}' second = requests.get(second_url,headers = { 'referer' : 'https://www.fantuanhd.com/' }).text urls = re.findall(r 'var urls = "(.*?)"' ,second)[ 0 ] print ( 'urls: ' ,urls) key = '0f84ff0c1f252cba' iv = 'c487eb12e38a0fa0' encrypt_ = AES.new(key.encode( 'utf-8' ),AES.MODE_CBC,IV = iv.encode()) encry_url = base64.decodebytes(urls.encode()) url = encrypt_.decrypt(encry_url) url = str (url[: - url[ - 1 ]], 'utf-8' ) print ( '解密结果: ' , url) url = 'https://{换成主域名}/play/id-3989-1-1.html' downlaods(url) |
帖子篇幅已严重超出预期, 下面的内容我会尽量精简

0x03: *B影院(aHR0cHM6Ly9hYnUyMi5jb20v)
网络大电影<目中无人>, 从网大的角度看, 这已经是一部很不错的电影了, 地址: aHR0cHM6Ly9hYnUyMi5jb20vdm9kcGxheS8xMTI0MTAtMS0xLmh0bWw=
打开之后拖动一下进度条, 可以判断出那些文件是视频切片, 选中之后可以看到是一张花屏的图片

明显是图片伪装, 用winhex删掉伪装头后可以正常播放

接下来找m3u8, 找到之后复制链接并搜索一下来源, 可以看到url是在一个请求的返回结果里


那看看这个请求是怎么完成的, 这是一个post请求, 请求参数有url,time,key


接下来找数据来源, 直接搜索看看, 第一个结果进去, url和key全都在了,url找到了,但是这里的key和我们要(7aa开头)的不一样?

去第三个结果点进去看看, 需要的数据都在这里了 url,key,time

这个链接"?url=BYGA-xxxxx"又是怎么来的? 通过首页来的, 这个流程就是(看着图片来)从 1-->2-->3

另外这个 var player_aaaa 有没有很熟悉? 可能他们用的都是同一套模板吧, 下载下来最后的格式bmp乱码图片, 看到这里还不会处理这个问题的, 拉出去弹小jj十分钟

python 示例:
[Python] 纯文本查看 复制代码
?
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
import time import requests import re import base64 import os from Crypto.Cipher import AES import json def downloads(url): # 从首页获取数据 page_ = requests.get(url).text data_ = re.findall(r 'player_aaaa=({.*?})</script>' ,page_)[ 0 ] data_ = json.loads(data_) key = data_[ 'key' ] url_ = data_[ 'url' ] tm = data_[ 'tm' ] # 第二次获取数据 url2 = f 'https://play.shzpin.com/BYGA/?url={url_}&tm={tm}&key={key}' page_2 = requests.get(url2).text data_2 = re.findall(r 'var config = ({.*?})' ,page_2,re.S)[ 0 ] data_2 = json.loads(data_2) url_3 = data_2[ 'url' ] time_3 = data_2[ 'time' ] key_3 = data_2[ 'key' ] # 第三次获取数据 api = 'https://play.shzpin.com/BYGA/API.php' data = { 'url' : url_3, 'time' : time_3, 'key' : key_3} post_data = requests.post(api,data = data).json() # 链接不一定是m3u8,也可能是完整的视频 m3u8 = post_data[ 'url' ] print (m3u8) url = 'https://{换成主域名}/vodplay/112410-1-1.html' downloads(url) |

0x04: *光影院(aHR0cHM6Ly93d3cubGd5eS5jYy8=)
<千与千寻>, 宫佬经典中的经典 aHR0cHM6Ly93d3cubGd5eS5jYy92b2RwbGF5LzU3MzI1LTEtMS5odG1s
直接过滤关键字m3u8,选中链接之后从堆栈调用里进去最后一个

看到关键信息, 下个断点刷新, 成功断下来, 鼠标放上去可以显示结果

复制后打开下载一段m3u8, 文本编辑器打开, 复制一段ts链接下载, 结果是一张1像素的图

拿进去winhex去掉图片头保存, 可以正常播放

确定getVideoInfo(urls)的返回结果是m3u8之后, 先看看urls(密文)来自哪里? 来源于这个
/dplayer.php?url=xxxx 的请求返回结果里

而这条请求连接构造通过搜索可以知道来自于首页的player_aaaa, 有没有发现又是这个参数? 密文来源搞定
接下来看 getVideoInfo这个方法对密文做了什么, 鼠标放上去可以直达函数

进去之后打断点刷新网页, 虽然是加密的, 但是好在表达式不长

鼠标放上去看看, _0x38afx2 为传入的密文, 我们用urls表示, 所以


string = _0x38afx2[__Oxdef43[0x1]](8, _0x38afx2[__Oxdef43[0x0]])
相当于下面的
string = urls["substring"](8, urls["length"])
就是说, string就是把传入的密文去掉前面八个字符, 然后再拿去base64解码, 解码完成后再把前面8个和最后8个字符删掉, 这就是最终的结果的, 这就是整个解密流程.

python 示例:
[Python] 纯文本查看 复制代码
?
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
import requests import re import base64 import os import json def downlaods(url): page_ = requests.get(url).text data_ = re.findall(r 'player_aaaa=({.*?})</script>' ,page_)[ 0 ] data_ = json.loads(data_) url = data_[ 'url' ] url_2 = f 'https://{换成主域名}/static/player/dplayer.php?url={url}' page_2 = requests.get(url_2).text url_3 = re.findall(r 'var urls = '(.*?)'' ,page_2)[ 0 ] url_3_decode = base64.decodebytes(url_3[ 8 :].encode()) url_3_real = str (url_3_decode, 'utf-8' )[ 8 : - 8 ] print (url_3_real) url = 'https://{换成主域名}/vodplay/57862-1-1.html' downlaods(url) |

完结了