banner
ming5ming

ming5ming

⭐一起去追那遥不可及的星⭐ 正在赛马!

逆向日记0x1

最近在看女高中生的废度日常, 然而 b 站的番剧画质压缩太大,所以找了一个解析网站.
结果发现网站的 js 代码带有混淆,遂逆向之.


逆向目标#

aHR0cHM6Ly9qeC5wbGF5ZXJqeS5jb20v

分析#

Pasted image 20230214195931

可以看出,视频加载出来了,可是没有看见任何有关视频的请求.Pasted image 20230214200144

这几个请求的响应数据没法加载,但是可以猜测出应该是视频片段.
打开文件后显示如下:

Pasted image 20230214200551

那么大致的请求过程是:

request

M3U8 file 是一个保存 video clip 的请求 url 的文本文件.
有了它我们就能拿到整个视频文件的网址.

向上追溯,找到接受 m3u8 file 的请求:

Pasted image 20230214201749
Pasted image 20230214201851

https:// 省略 / 1676376933/4d140af4cb5d1c5466a7491918b43e5b/b3489f29121e97e6dd1dcb1957e5788c-20230214.m3u8?from=https://banyung.pw

请求网址的构成:
https:// 网址域名 / 时间戳 / 未知 / 未知.m3u8 + 固定参数

如果这里不细心的话,很容易就下 xhr 断点去追踪 js 代码了。我自己一开始分析的时候就进入了这个误区,在繁杂的代码和各种加密里转来转去.

Pasted image 20230214202531

然而这个请求不用我们构造,它由上一个请求接受,甚至没有加密,明文传输过来了!

Pasted image 20230214202715

再看这个请求的 playload:

Pasted image 20230214202821

两个参数time, key
time 是时间戳,key 看样子应该是 md5 密文。逆向 js 代码后其实是 CBC 加密,然而让我无语的是,几乎在我分析完 js 代码并开始用 python 模拟请求的时候,我发现 key 和 time 又在上一个请求被明文发过来了!!!

Pasted image 20230214203247

写代码#

#getPram.py
import time
import requests as rq
from lxml import etree
from lxml import html

headers = {

    "referer": "https://jx.playerjy.com/",
    "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36",
    "Cache-Control": "no-cache",
    "Host": "jy.we-vip.com:5433"
}

def getHtml(ep):
    url = "https://jy.we-vip.com:5433/?url=" + ep
    return rq.get(url=url, headers=headers, verify=False).content 
    
# get time and key
def getData(bili_url):
    htmlString = html.fromstring(getHtml(bili_url))
    result = htmlString.xpath('//body/script/text()')
    #gettime
    timebegin = result[0].index('time') + 8
    timeend = int(str(result[0]).index('",', timebegin))
    time = result[0][timebegin:timeend]
    #getkey
    keybegin = result[0].index('key') + 7
    keyend = int(str(result[0]).index('",', keybegin))
    key = result[0][keybegin:keyend]
    return time, key 

if __name__ == "__main__":
    time, key = getData()
    print(f"time is {time}, key is {key}")
import requests as rq
import getPram

time, key = getPram.getData(input("bilibili_url:"))

headers = {
    "authority" : "jy.we-vip.com:5433",
    "accept" : "application/json, text/javascript, */*; q=0.01",
    "content-type" : "application/x-www-form-urlencoded; charset=UTF-8",
    "user-agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36",
    "Host" : "jy.we-vip.com:5433",
    "Content-Length": "115",
    "Cache-Control": "no-cache"
}

url = r"https://jy.we-vip.com:5433/API.php"
data = {
    "url": "https://www.bilibili.com/bangumi/play/ep276690",
    "time": time,
    "key": key
}
rsp = rq.post(url, headers=headers, data=data, verify=False)
print(rsp.content)

反思#

  • 分析的思路像依托答辩,兜兜转转最后连请求过程都没有好好分析,浪费了很多时间。逆向就像高中的数学题,开始只有模糊的方向,需要耐心慢慢溯源追踪.
  • 代码写的依托答辩,逻辑不是很清楚,提取子字符串想到很多种方法,最后选了最简单但是可读性极差的方式...
加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。