banner
ming5ming

ming5ming

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

逆向日記0x1

最近は女高中生の日常を見ていますが、b 站のアニメの画質が圧縮されすぎているため、解析サイトを探しました。
結果、サイトの JavaScript コードが難読化されていることがわかりましたので、逆向きに解析しました。


逆向きの目標#

aHR0cHM6Ly9qeC5wbGF5ZXJqeS5jb20v

分析#

Pasted image 20230214195931

ビデオが読み込まれていることがわかりますが、ビデオに関連するリクエストは見つかりませんでした。Pasted image 20230214200144

これらのリクエストのレスポンスデータは読み込めませんが、おそらくビデオのセグメントであると推測できます。
ファイルを開くと、次のように表示されます:

Pasted image 20230214200551

したがって、おおよそのリクエストプロセスは次のようになります:

request

M3U8 ファイルは、ビデオクリップのリクエスト URL を保存するテキストファイルです。
これにより、ビデオファイル全体の URL を取得できます。

上に遡って、M3U8 ファイルを受け入れるリクエストを見つけます:

Pasted image 20230214201749
Pasted image 20230214201851

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

リクエスト URL の構成:
https:// ウェブサイトのドメイン / タイムスタンプ / 不明 / 不明.m3u8 + 固定パラメータ

ここで注意が必要ですが、ここで注意が必要です。もしもうまくいかない場合、xhr のブレークポイントを追跡して JavaScript コードを追跡してしまうかもしれません。最初に私自身もこの誤った方向に入ってしまいました。複雑なコードとさまざまな暗号化の中で行ったり来たりしています。

Pasted image 20230214202531

ただし、このリクエストは私たちが構築する必要はありません。前のリクエストで受け取られ、暗号化されずに平文で送信されてきました!

Pasted image 20230214202715

このリクエストのプレイロードを見てみましょう:

Pasted image 20230214202821

2 つのパラメータtimekeyがあります。time はタイムスタンプで、key はおそらく MD5 ハッシュです。逆向きの JavaScript コードでは、実際には CBC 暗号化が行われていますが、私が JavaScript コードを分析し、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)

反省#

  • 分析のアプローチは答辯に依存しており、最後までリクエストプロセスをきちんと分析していませんでした。時間を無駄にしました。逆向きは高校の数学の問題のようなもので、最初は曖昧な方向しかなく、忍耐強く徐々に追跡していく必要があります。
  • コードは答辯に依存して書かれており、ロジックがあまり明確ではありません。部分文字列の抽出にはさまざまな方法がありますが、最終的には最も簡単ながらも可読性が非常に低い方法を選びました...
読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。