最近は女高中生の日常を見ていますが、b 站のアニメの画質が圧縮されすぎているため、解析サイトを探しました。
結果、サイトの JavaScript コードが難読化されていることがわかりましたので、逆向きに解析しました。
逆向きの目標#
aHR0cHM6Ly9qeC5wbGF5ZXJqeS5jb20v
分析#
ビデオが読み込まれていることがわかりますが、ビデオに関連するリクエストは見つかりませんでした。
これらのリクエストのレスポンスデータは読み込めませんが、おそらくビデオのセグメントであると推測できます。
ファイルを開くと、次のように表示されます:
したがって、おおよそのリクエストプロセスは次のようになります:
M3U8 ファイルは、ビデオクリップのリクエスト URL を保存するテキストファイルです。
これにより、ビデオファイル全体の URL を取得できます。
上に遡って、M3U8 ファイルを受け入れるリクエストを見つけます:
リクエスト URL の構成:
https:// ウェブサイトのドメイン / タイムスタンプ / 不明 / 不明.m3u8 + 固定パラメータ
ここで注意が必要ですが、ここで注意が必要です。もしもうまくいかない場合、xhr のブレークポイントを追跡して JavaScript コードを追跡してしまうかもしれません。最初に私自身もこの誤った方向に入ってしまいました。複雑なコードとさまざまな暗号化の中で行ったり来たりしています。
ただし、このリクエストは私たちが構築する必要はありません。前のリクエストで受け取られ、暗号化されずに平文で送信されてきました!
このリクエストのプレイロードを見てみましょう:
2 つのパラメータtimeとkeyがあります。time はタイムスタンプで、key はおそらく MD5 ハッシュです。逆向きの JavaScript コードでは、実際には CBC 暗号化が行われていますが、私が JavaScript コードを分析し、Python でリクエストをシミュレートし始めたときに、key と time が前のリクエストで平文で送られてきたことに気づきました!
コードを書く#
#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)
反省#
- 分析のアプローチは答辯に依存しており、最後までリクエストプロセスをきちんと分析していませんでした。時間を無駄にしました。逆向きは高校の数学の問題のようなもので、最初は曖昧な方向しかなく、忍耐強く徐々に追跡していく必要があります。
- コードは答辯に依存して書かれており、ロジックがあまり明確ではありません。部分文字列の抽出にはさまざまな方法がありますが、最終的には最も簡単ながらも可読性が非常に低い方法を選びました...