欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

【JS 逆向百例】吾愛破解2022春節(jié)解題領(lǐng)紅包之番外篇 Web 中級(jí)題解

我們提供的服務(wù)有:成都網(wǎng)站設(shè)計(jì)、網(wǎng)站制作、微信公眾號(hào)開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、涼城ssl等。為上千多家企事業(yè)單位解決了網(wǎng)站和推廣的問題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的涼城網(wǎng)站制作公司

關(guān)注微信公眾號(hào):K哥爬蟲,持續(xù)分享爬蟲進(jìn)階、JS/安卓逆向等技術(shù)干貨!

逆向目標(biāo)

本次逆向的目標(biāo)來源于吾愛破解 2022 春節(jié)解題領(lǐng)紅包之番外篇 Web 中級(jí)題,吾愛破解每年都會(huì)有派送紅包活動(dòng)(送吾愛幣),需要大家使出看家逆向本領(lǐng)來分析內(nèi)容獲得口令紅包,今年一共有五個(gè)題,一個(gè)送分題,兩個(gè) Windows 題、一個(gè) Android 題和一個(gè) Web 題,本文分析的正是 Web 題,吾愛有規(guī)定活動(dòng)結(jié)束前不要外泄口令、討論分享分析過程,所以本文在活動(dòng)結(jié)束后才發(fā)出來。

此 Web 題題目是:小 D 最愛看的視頻網(wǎng)站最近關(guān)站了,關(guān)站前他用 Fiddler 和 Web Archive 保存了一位主播的視頻,但他發(fā)現(xiàn)存下來的文件無法播放。你能幫小 D 找回他的回憶嗎?(.saz 與 .wacz 任選其一即可解題)

為防止吾愛后期關(guān)閉解題通道,K哥將 .saz 和 .wacz 文件保存了一份,可在公眾號(hào)后臺(tái)回復(fù)吾愛破解獲?。?/p>

  • 活動(dòng)地址:https://www.52pojie.cn/thread--1-1.html

  • Web 題地址:https://www.52pojie.cn/home.php?mod=task&do=view&id=17

HLS 流媒體傳輸協(xié)議

本題涉及到 HLS 流媒體傳輸協(xié)議,先簡單介紹一下,了解的同志可直接跳過。

HLS 全稱 HTTP Live Streaming,即基于 HTTP 的自適應(yīng)碼率流媒體傳輸協(xié)議,是蘋果研發(fā)的動(dòng)態(tài)碼率自適應(yīng)技術(shù),它包括一個(gè) M3U(8) 的索引文件,若干 TS 視頻流文件,如果視頻流文件是加密的,那就還會(huì)存在一個(gè) key 加密串文件。

M3U8 文件是 M3U 的一種,只不過文件中存儲(chǔ)的文本使用 UTF-8 字符編碼,在極少數(shù)情況下,M3U8 文件可能會(huì)以 M3UP 擴(kuò)展名保存。M3U8 文件是各種音頻和視頻播放程序使用的播放列表文件,它包含了媒體文件或媒體文件夾的路徑或 URL,以及有關(guān)播放列表的相關(guān)信息。

TS 全稱為 MPEG2-TS,TS 即 Transport Stream 傳輸流,又稱 MPEG-TS、MTS、TP,這種格式的特點(diǎn)就是從視頻流的任一片段開始都是可以獨(dú)立解碼的。

針對(duì) TS 格式的文件,如果是未加密的,一般的播放器就能夠直接播放,也可以使用 FFmpeg 等工具轉(zhuǎn)換為其他格式,F(xiàn)Fmpeg 也可以直接處理 M3U8 文件,自動(dòng)解密合并轉(zhuǎn)換 TS 文件,當(dāng)然也有其他大佬寫好的小工具,拖入 M3U8 文件就直接給你處理好了。

M3U8 文件內(nèi)容的大致格式示例如下:

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-ALLOW-CACHE:YES
#EXT-X-KEY:METHOD=AES-128,URI="https://www.example.com/m3u8.key"
#EXT-X-TARGETDURATION:5
#EXTINF:4.,
https://www.example.com/hls/live_00000.ts
#EXTINF:4.,
https://www.example.com/hls/live_00001.ts
#EXTINF:3.,
https://www.example.com/hls/live_00002.ts
#EXTINF:2.,
https://www.example.com/hls/live_00003.ts
#EXTINF:4.,
https://www.example.com/hls/live_00004.ts
#EXTINF:4.,
https://www.example.com/hls/live_00005.ts
#EXTINF:4.,
https://www.example.com/hls/live_00006.ts
#EXTINF:1.,
https://www.example.com/hls/live_00007.ts
#EXT-X-ENDLIST

各標(biāo)簽含義如下:

  • #EXTM3U:m3u文件頭,必須放在第一行,起標(biāo)示作用;
  • #EXT-X-VERSION:播放列表文件的兼容版本。若不存在此標(biāo)記,則默認(rèn)為協(xié)議的第一個(gè)版本;
  • #EXT-X-MEDIA-SEQUENCE: 播放列表中的每個(gè)媒體 URI 都有一個(gè)唯一的整數(shù)序列號(hào)。URI 的序列號(hào)等于它之前的 URI 的序列號(hào)加一;
  • #EXT-X-ALLOW-CACHE:指示客戶端是否可以緩存下載的媒體片段以供以后重播;
  • #EXT-X-KEY:TS 片段可以被加密,該標(biāo)簽指定加密方式(METHOD)、密鑰的 URI 以及偏移量 IV 等信息,沒有此標(biāo)簽表示未加密;
  • #EXT-X-TARGETDURATION:每一份 TS 媒體文件的最大持續(xù)時(shí)間,以秒為單位;
  • #EXTINF:每一份媒體文件的詳細(xì)信息,包括媒體持續(xù)時(shí)間、媒體 URL 地址等;
  • #EXT-X-ENDLIST:表示不再將媒體片段添加到播放列表文件中,一般位于文件結(jié)尾。

完整格式、標(biāo)準(zhǔn)標(biāo)簽可參考 HLS 標(biāo)準(zhǔn)協(xié)議中,對(duì) Playlist file 的介紹:https://datatracker.ietf.org/doc/html/draft-pantos-http-live-streaming-08

SAZ 分析

在 Fiddler 軟件中,使用 SAZ 格式用來保存和讀取 HTTP/HTTPS 請(qǐng)求信息,打開該文件可以注意到一些重要的請(qǐng)求:script.bundle.js、live.m3u8、drm 以及八個(gè) ts 視頻流文件。

先來看看 m3u8 文件,可以看到是 AES-128 加密,加密的 key 文件地址為 key://live,如下圖所示:

一般情況下,要想解密 ts,必然會(huì)去請(qǐng)求 key 的地址,拿到 key 后再解密 ts,很顯然此題的 key 地址不是一個(gè)合法的 URL 地址,當(dāng)然此題的抓包記錄可能是出題人偽造的,因?yàn)檫@個(gè) Host 是 52tube.mmxxii,也不是一個(gè)合法的域名,最主要的是,抓包記錄里沒有 key://live 這條請(qǐng)求,那么很大概率真實(shí)的地址隱藏在 JS 里,從另一個(gè)方面來思考,如果這是完整的抓包記錄,不管真實(shí)的 key 地址是啥,必然會(huì)在記錄里出現(xiàn)!

有經(jīng)驗(yàn)的朋友應(yīng)該一眼就能看出來 drm 這條請(qǐng)求最有可能是拿 key 的操作了,第一是 drm 這個(gè)關(guān)鍵詞在 ts 解密里經(jīng)常會(huì)出現(xiàn),搞得多的朋友應(yīng)該見過不少,第二 ping 請(qǐng)求返回的 success,通過其名稱和返回值來看也不像 key,剩下就只有 drm 了,查看返回值是亂碼的,查看 Hex 值,32 位 16 進(jìn)制數(shù)據(jù),而正常的 key 應(yīng)該是 16 位 16 進(jìn)制數(shù)據(jù),所以你如果直接拿這個(gè)數(shù)據(jù)當(dāng)作 key 去解密,肯定也是失敗的。

到這里我們應(yīng)該有如下猜想:drm 返回的數(shù)據(jù),經(jīng)過了 script.bundle.js 二次處理就能得到正確的 key。

JS 逆向

我們把抓包記錄的 script.bundle.js,右鍵,save - response - response body,保存到本地。

格式化之后有 + 行代碼,又不能動(dòng)態(tài)調(diào)試,從哪里找加密入口呢?可以大膽嘗試一下:

  • JS 里可能會(huì)檢測(cè)到 m3u8 里存在 key 的 URI 之后,發(fā)送 /api/drm/ 這個(gè)請(qǐng)求,可以直接搜索 /api/drm/ 或者 key://live 定位;
  • drm 是一個(gè) post 請(qǐng)求,帶有 h 和 id 兩個(gè)參數(shù),可以直接搜索 post、id、h 定位到大致位置。

通過搜索可以發(fā)現(xiàn)如下可疑代碼片段:

將關(guān)鍵代碼提煉一下:

function n(t) {
    return [...new Uint8Array(t)].map((t => t.toString(16).padStart(2, "0"))).join("")
}

function s(t, e) {
    let r = new Uint8Array(t.length);
    for (let i = 0; i < t.length; i++) r[i] = t[i] ^ e[i];
    return r
}

let e = "/api/ping/",
    i = "/api/drm/";

class a extends t.DefaultConfig.loader {
    let e = await async function() {
        let t = new Uint8Array(16);
        crypto.getRandomValues(t);
        let e = n(t.buffer) + Date.now() + Math.random();
        return new Uint8Array((await async function(t) {
            const e = (new TextEncoder).encode(t);
            return await crypto.subtle.digest("SHA-256", e)
        } (e)).slice(0, 16))
    }();
    var r = new URLSearchParams;
    r.append("h", n(e.buffer)),
        r.append("id", t);
    var a = {
        method: "POST",
        headers: {
            "Content-Type": "application/x-www-form-urlencoded"
        },
        body: r
    };
    let o = await fetch(i, a),
        l = await o.arrayBuffer();
    if (32 !== l.byteLength) throw new Error("Invalid response");
    let u = new Uint8Array(l.slice(0, 16)),
        c = new Uint8Array(l.slice(16, 32));
    return s(s(u, e), c)
}

可以看到事實(shí)上在發(fā)送 /api/drm/ 請(qǐng)求拿到結(jié)果后,先后取前后 16 位數(shù)據(jù),然后經(jīng)過了 s 方法的處理,最后返回的 s(s(u, e), c) 應(yīng)該才是正確的 key,這里的重點(diǎn)在于 e 的值,上面有個(gè)方法,取了當(dāng)前時(shí)間+隨機(jī)值,經(jīng)過 SHA-256 加密,再取前 16 位。

這里可以思考一下,這個(gè) e 的值是不固定的,那么最后的 key 應(yīng)該也是不固定的,同一個(gè) TS 對(duì)應(yīng)有無數(shù)個(gè) key,我反正是沒見過,不信的話嘗試就用那個(gè)方法生成 e,你會(huì)發(fā)現(xiàn)最終的 key 是錯(cuò)誤的。

仔細(xì)看一下,發(fā)送 post 請(qǐng)求對(duì) h 值賦值的地方:r.append("h", n(e.buffer)),n 方法是轉(zhuǎn) 16 進(jìn)制,那么我們直接將 h 值倒推,從16進(jìn)制轉(zhuǎn)為10進(jìn)制,這才是正確的 e 的值!然后 l 的值是 /api/drm/ 請(qǐng)求返回的 32 位 16 進(jìn)制數(shù)據(jù)轉(zhuǎn)為 10 進(jìn)制,剩下的就好說了,直接改寫一下 JS 代碼拿到正確的 key:

function s(t, e) {
    let r = new Uint8Array(t.length);
    for (let i = 0; i < t.length; i++)
        r[i] = t[i] ^ e[i];
    return r
}

function getKey(){
    // /api/drm/ 請(qǐng)求表單的 h 值,16進(jìn)制數(shù)據(jù)
    const h = ["7b", "10", "31", "1e", "6e", "31", "0f", "0d", "f0", "68", "d9", "ed", "e1", "04", "75", "a8"];
    // /api/drm/ 請(qǐng)求返回的32位16進(jìn)制數(shù)據(jù)
    const drm = ["08", "A5", "E6", "C2", "C2", "61", "A8", "AC", "B4", "D7", "9C", "49", "AF", "16", "0A", "3A", "DA", "4E", "5C", "EA", "E1", "6F", "ED", "46", "EB", "6F", "49", "8C", "9B", "63", "D5", "3B"]
    // 轉(zhuǎn)換為10進(jìn)制數(shù)據(jù),為 e 和 l 賦值
    const e = [];
    const l = [];
    for (let i=0; i<h.length; i++)
    {
        e.push(parseInt(h[i],16))
    }
    for (let i=0; i<drm.length; i++)
    {
        l.push(parseInt(drm[i],16))
    }

    const u = new Uint8Array(l.slice(0, 16));
    const c = new Uint8Array(l.slice(16, 32));

    const keyArray = s(s(u, e), c);
    const keyHex = new Buffer.from(keyArray).toString('hex');
    const keyBase64 = new Buffer.from(keyArray).toString('base64');

    console.log("keyArray: ", keyArray)
    console.log("keyHex: ", keyHex)
    console.log("keyBase64: ", keyBase64)
}

getKey()

// 輸出
// keyArray:  Uint8Array(16) [
//   169, 251, 139,  54,  77,
//    63,  74, 231, 175, 208,
//    12,  40, 213, 113, 170,
//   169
// ]
// keyHex:  a9fb8b364d3f4ae7afd00c28d571aaa9
// keyBase64:  qfuLNk0/Suev0Awo1XGqqQ==

TS 解密合并轉(zhuǎn)換

通過 JS 逆向我們拿到了 16進(jìn)制和 base64 形式的 key,不管什么形式都可以拿來解密,這里介紹兩種對(duì) TS 媒體流解密、合并、轉(zhuǎn)換的方法。

第一種方法是使用 FFmpeg 工具,F(xiàn)Fmpeg 是一套可以用來記錄、轉(zhuǎn)換數(shù)字音頻、視頻,并能將其轉(zhuǎn)化為流的開源計(jì)算機(jī)程序。官網(wǎng)地址:https://ffmpeg.org/ ,下載編譯好的程序,將 bin 目錄添加到環(huán)境變量即可,該工具也可以直接在K哥爬蟲公眾號(hào)后臺(tái)回復(fù) M3U8 獲取。

首先我們要把 m3u8 文件和 ts 媒體流保存到同一個(gè)文件夾,由于是虛假的 Host,所以不能直接瀏覽器訪問保存,可以直接在 Fiddler 里,右鍵,save - response - response body,保存到本地,如下圖所示:

然后就是保存密鑰文件,這里要求密鑰文件必須是16進(jìn)制的數(shù)據(jù),如果你直接將 key 以字符串形式保存的話,解密也是失敗的,編輯 16 進(jìn)制文件有專門的工具,比如 HxD、010 editor、winhex 等,以 HxD 為例,新建文件,寫入我們前面通過 JS 逆向得到的 key 的 16 進(jìn)制數(shù)據(jù),存為 .key 文件,如下圖所示:

然后修改 m3u8 文件里 key 的地址、名稱,建議將 key、m3u8、ts 文件都放同一個(gè)文件夾,這樣 m3u8 文件里就不用添加資源路徑了,不容易出錯(cuò)。

然后在當(dāng)前文件夾,打開命令行輸入命令:ffmpeg -allowed_extensions ALL -i live.m3u8 -c copy live.mp4,即可自動(dòng)解密 ts,并合并轉(zhuǎn)換為 .mp4 格式:

第二種方法就是使用大佬寫的第三方小工具,這里推薦吾愛大佬逍遙一仙寫的 M3U8 批量下載器,下載地址、使用方法見原貼:https://www.52pojie.cn/thread--1-1.html ,也可以在K哥爬蟲公眾號(hào)后臺(tái)回復(fù) M3U8 獲取。

我們可以直接拖入處理好的 M3U8 文件,自動(dòng)處理:

也可以選擇其他 - 工具 - 合并助手,添加所有 TS 文件,輸入 key 后自動(dòng)處理:

處理完畢后的 mp4 文件默認(rèn)在軟件目錄的 output 文件夾里面,解密后是一段動(dòng)畫,往后看會(huì)找到 flag:flag{like_sub_52tube} 為正確答案。


新聞名稱:【JS 逆向百例】吾愛破解2022春節(jié)解題領(lǐng)紅包之番外篇 Web 中級(jí)題解
URL地址:http://chinadenli.net/article32/dsojopc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站設(shè)計(jì)、網(wǎng)站維護(hù)微信小程序、建站公司外貿(mào)建站、網(wǎng)站制作

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都seo排名網(wǎng)站優(yōu)化