odmin 发表于 2022-11-2 09:19

js逆向某视频VIP

环境:
python 3.9
nodejs 18.12

开发工具:
pycharm

流程:
1. 过debug
2. 分析
3. 抠代码
4. 解析m3u8
5. 下载

url:
aHR0cHM6Ly9qeC5ib3pyYy5jb206NDQzMy9wbGF5ZXIvP3VybD1odHRwczovL3YucXEuY29tL3gvY292ZXIvbXpjMDAyMDBrcjhuMzFpL3MwMDQ0aTNidTJiLmh0bWw=

function _0x3d38b4(_0xaf0521){
                let _0xfe4b29='abcdefghijklmnopqrstuvwxyz9876543210';
                let _0x473192='',_0x2715b9=0,_0x4b86ce=_0xfe4b29.length;
                for(_0x2715b9=0;_0x2715b9<_0xaf0521;_0x2715b9++){
                        _0x473192+=_0xfe4b29.charAt(Math.floor(Math.random()*_0x4b86ce));
                }
                return _0x473192;
        }
function _0x46c9ca(_0x56b67e,_0x5523a9){
                return Math.floor(Math.random()*(_0x5523a9+1-_0x56b67e))+_0x56b67e;
        }
function _0x522c25(){
                _keyStr='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
                this.encode=function(_0x2a3435){
                        var _0x1772d2={'shmAY':function(_0x5bd14e,_0x54153a){
                                return _0x5bd14e(_0x54153a);
                        }};
                        var _0xb3b21c='';
                        var _0x271dcd,_0x4de8b7,_0x233f5b,_0x25bca6,_0x3476bf,_0x2548ae,_0x2a5ccd;
                        var _0xe359fc=0;
                        _0x2a3435=_utf8_encode(_0x2a3435);
                        while(_0xe359fc<_0x2a3435.length){
                                _0x271dcd=_0x2a3435.charCodeAt(_0xe359fc++);
                                _0x4de8b7=_0x2a3435.charCodeAt(_0xe359fc++);
                                _0x233f5b=_0x2a3435.charCodeAt(_0xe359fc++);
                                _0x25bca6=_0x271dcd>>0x2;
                                _0x3476bf=(_0x271dcd&0x3)<<0x4|_0x4de8b7>>0x4;
                                _0x2548ae=(_0x4de8b7&0xf)<<0x2|_0x233f5b>>0x6;
                                _0x2a5ccd=_0x233f5b&0x3f;
                                if(isNaN(_0x4de8b7)){
                                        _0x2548ae=_0x2a5ccd=64;
                                }else if(isNaN(_0x233f5b)){
                                        _0x2a5ccd=64;
                                }
                                _0xb3b21c=_0xb3b21c+_keyStr.charAt(_0x25bca6)+_keyStr.charAt(_0x3476bf)+_keyStr.charAt(_0x2548ae)+_keyStr.charAt(_0x2a5ccd);
                        }
                        return _0xb3b21c;
                };
                this.decode=function(_0xfb19ef){
                        var _0x462b86='';
                        var _0x15defb,_0x3d585f,_0x50b56d;
                        var _0x1659a2,_0x1a932c,_0xee6c97,_0x1b2405;
                        var _0x3de4d4=0;
                        _0xfb19ef=_0xfb19ef.replace(/[^A-Za-z0-9\+\/\=]/g,'');
                        while(_0x3de4d4<_0xfb19ef.length){
                                _0x1659a2=_keyStr.indexOf(_0xfb19ef.charAt(_0x3de4d4++));
                                _0x1a932c=_keyStr.indexOf(_0xfb19ef.charAt(_0x3de4d4++));
                                _0xee6c97=_keyStr.indexOf(_0xfb19ef.charAt(_0x3de4d4++));
                                _0x1b2405=_keyStr.indexOf(_0xfb19ef.charAt(_0x3de4d4++));
                                _0x15defb=_0x1659a2<<0x2|_0x1a932c>>0x4;
                                _0x3d585f=(_0x1a932c&0xf)<<0x4|_0xee6c97>>0x2;
                                _0x50b56d=(_0xee6c97&0x3)<<0x6|_0x1b2405;
                                _0x462b86=_0x462b86+String.fromCharCode(_0x15defb);
                                if(_0xee6c97!=64){
                                        _0x462b86=_0x462b86+String.fromCharCode(_0x3d585f);
                                }
                                if(_0x1b2405!=64){
                                        _0x462b86=_0x462b86+String.fromCharCode(_0x50b56d);
                                }
                        }
                        _0x462b86=_utf8_decode(_0x462b86);
                        return _0x462b86;
                };
                _utf8_encode=function(_0x2f4dc5){
                        _0x2f4dc5=_0x2f4dc5.replace(/\r\n/g,'\n');
                        var _0x58b823='';
                        for(var _0x3ab16c=0;_0x3ab16c<_0x2f4dc5.length;_0x3ab16c++){
                                var _0xcf99ac=_0x2f4dc5.charCodeAt(_0x3ab16c);
                                if(_0xcf99ac<128){
                                        _0x58b823+=String.fromCharCode(_0xcf99ac);
                                }else if(_0xcf99ac>127&&_0xcf99ac<2048){
                                        _0x58b823+=String.fromCharCode(_0xcf99ac>>0x6|0xc0);
                                        _0x58b823+=String.fromCharCode(_0xcf99ac&0x3f|0x80);
                                }else{
                                        _0x58b823+=String.fromCharCode(_0xcf99ac>>0xc|0xe0);
                                        _0x58b823+=String.fromCharCode(_0xcf99ac>>0x6&0x3f|0x80);
                                        _0x58b823+=String.fromCharCode(_0xcf99ac&0x3f|0x80);
                                }
                        }
                        return _0x58b823;
                };
                _utf8_decode=function(_0x567571){
                        var _0x2c22cb='';
                        var _0xf0adb0=0;
                        var _0x5c70f4=c1=c2=0;
                        while(_0xf0adb0<_0x567571.length){
                                _0x5c70f4=_0x567571.charCodeAt(_0xf0adb0);
                                if(_0x5c70f4<128){
                                        _0x2c22cb+=String.fromCharCode(_0x5c70f4);
                                        _0xf0adb0++;
                                }else if(_0x5c70f4>191&&_0x5c70f4<224){
                                        c2=_0x567571.charCodeAt(_0xf0adb0+1);
                                        _0x2c22cb+=String.fromCharCode((_0x5c70f4&0x1f)<<0x6|c2&0x3f);
                                        _0xf0adb0+=2;
                                }else{
                                        c2=_0x567571.charCodeAt(_0xf0adb0+1);
                                        c3=_0x567571.charCodeAt(_0xf0adb0+2);
                                        _0x2c22cb+=String.fromCharCode((_0x5c70f4&0xf)<<0xc|(c2&0x3f)<<0x6|c3&0x3f);
                                        _0xf0adb0+=3;
                                }
                        }
                        return _0x2c22cb;
                };
        }
function _0x3d38f8(_0x535b29,_0x4bb6ff,_0x54f9f3){
                var _0x25a3b2=parseInt(_0x535b29.decode(_0x54f9f3));
                return _0x4bb6ff.slice(0,-_0x25a3b2);
}
function _0x16755c(_0x3fb941,_0x3962ee,_0x3c91f1,_0x1bdd9e){
                var _0x460ebb=parseInt(_0x3fb941.decode(_0x1bdd9e));
                var _0x194268=_0x3962ee.substring(_0x3962ee.length-_0x460ebb);
                var _0x340e80=_0x425fb1(_0x194268,_0x3c91f1,true);
                var _0x3674bc='';
                _0x340e80=_0x340e80.split('').reverse().join('');
                _0x340e80=_0x3fb941.decode(_0x340e80);
                _0x340e80=JSON.parse(_0x340e80);
                for(var _0x2715cb=0;_0x2715cb<_0x340e80.length;_0x2715cb++){
                        if(_0x2715cb!==0){
                                _0x3674bc+='_';
                        }
                        _0x3674bc+=_0x340e80.split('').reverse().join('');
                }
                return _0x3674bc;
        }
function _0x425fb1(_0x139a72,_0x387b6c,_0x3dd579){
                _0x387b6c=CryptoJS.MD5(_0x387b6c).toString();
                var _0x1d4217=CryptoJS.enc.Utf8.parse(_0x387b6c.substring(0,16));
                var _0x294cf8=CryptoJS.enc.Utf8.parse(_0x387b6c.substring(16));
                if(_0x3dd579){
                        return CryptoJS.AES.decrypt(_0x139a72,_0x294cf8,{'iv':_0x1d4217,'padding':CryptoJS.pad.Pkcs7}).toString(CryptoJS.enc.Utf8);
                }
                return CryptoJS.AES.encrypt(_0x139a72,_0x294cf8,{'iv':_0x1d4217,'mode':CryptoJS.mode.CBC,'padding':CryptoJS.pad.Pkcs7}).toString();
        }

function enparams(url) {
    //参数加密算法
    var _0x27f346=_0x46c9ca(7,9);
    var _0x4d01ae=_0x3d38b4(_0x27f346);
    var _0x1f2b5b={'domain':'https://jx.bozrc.com:4433/','url':url,'referrer':''};
    _0x1f2b5b=_0x425fb1(JSON.stringify(_0x1f2b5b),_0x4d01ae);
    _0x1f2b5b+=_0x4d01ae.split('').reverse().join('');
    _0x1f2b5b+=_0x27f346;
    return encodeURIComponent(_0x1f2b5b)
}

function deurl(endata) {
    //解密URL
    var _0x165d62=new _0x522c25();
    var _0x14a536 = JSON.parse(endata)
    var _0x2ebeb2=_0x425fb1(_0x3d38f8(_0x165d62,_0x14a536.url,_0x14a536.v),_0x16755c(_0x165d62,_0x14a536.url,_0x14a536.key,_0x14a536.v),true);
    return _0x2ebeb2
}


import requests
import execjs


ctx = execjs.compile(open('js.js', mode='r', encoding='utf-8').read())

def js(js_path):
    return (str(ctx.eval(js_path)))


def m3u8(url):
    cmd = 'enparams("'+url+'")'
    params = js(cmd)
    pdat = '{"params": "'+params+'"}'
    print(pdat)
    resp = requests.post('https://110.42.2.115:9090/player/api.php', data=pdat)
    cmd = "deurl('"+resp.text+"')"
    deurl = js(cmd)
    print(deurl)


if __name__ == '__main__':
   url = 'aHR0cHM6Ly92LnFxLmNvbS94L2NvdmVyL216YzAwMjAwa3I4bjMxaS9zMDA0NGkzYnUyYi5odG1s'
   m3u8(url)

kiopc 发表于 2022-11-2 15:13

本帖最后由 kiopc 于 2022-11-2 15:17 编辑

odmin 发表于 2022-11-2 15:00
js中没有引入 crypto-js



感谢大佬,不报crypto的错误了
UnicodeDecodeError: 'gbk' codec can't decode byte 0xa6 in position 92: illegal multibyte sequence

像这种错误的话,是不是需要去修改anaconda中源代码啊?

kiopc 发表于 2022-11-2 14:50

odmin 发表于 2022-11-2 14:49
node 安装了没?

node装的是v16.17.0,Python 3.8.8,

Hiraly333 发表于 2022-11-3 18:14

你好,我不太明白输入和输出的内容分别是什么呢,我看楼主用的输入是一个视频地址base64后的地址,最后打印的也是相同的地址,如图所示。麻烦解释下输入内容是什么呢

Hiraly333 发表于 2022-11-3 18:34

https://110.42.2.115:9092/c/qq_301/3c38ef3c9348671911fceb7b3e568aae.m3u8?vkey=f3f94hbDQYq-6DUQC-cvxmkioWtgnviS5-Q4omFw返回的链接是这个,但是在下载时,提示资源不存在

jxccs99 发表于 2022-11-2 11:27

{:1_921:}涨知识涨知识

8970665 发表于 2022-11-2 12:11

太高深了,

kiopc 发表于 2022-11-2 14:33

本帖最后由 kiopc 于 2022-11-2 14:36 编辑

Traceback (most recent call last):
File "D:/study/pyTest/q视/qVideo.py", line 32, in <module>
    m3u8(url)
File "D:/study/pyTest/q视/qVideo.py", line 21, in m3u8
    params = js(cmd)
File "D:/study/pyTest/q视/qVideo.py", line 16, in js
    return (str(ctx.eval(js_path)))
File "F:\anaconda\lib\site-packages\execjs\_abstract_runtime_context.py", line 27, in eval
    return self._eval(source)
File "F:\anaconda\lib\site-packages\execjs\_external_runtime.py", line 78, in _eval
    return self.exec_(code)
File "F:\anaconda\lib\site-packages\execjs\_abstract_runtime_context.py", line 18, in exec_
    return self._exec_(source)
File "F:\anaconda\lib\site-packages\execjs\_external_runtime.py", line 88, in _exec_
    return self._extract_result(output)
File "F:\anaconda\lib\site-packages\execjs\_external_runtime.py", line 167, in _extract_result
    raise ProgramError(value)
execjs._exceptions.ProgramError: ReferenceError: CryptoJS is not defined
Process finished with exit code 1

这种错误是为什么?代码原样copy的,CryptoJS也用npm安装过了,难道是软件版本的问题?
哪位大佬解答下,谢谢

odmin 发表于 2022-11-2 14:49

kiopc 发表于 2022-11-2 14:33
Traceback (most recent call last):
File "D:/study/pyTest/q视/qVideo.py", ...

node 安装了没?

odmin 发表于 2022-11-2 14:51

import execjs


print(execjs.get().name)

显示是什么?
需要使用本地Node.js (V8)

kiopc 发表于 2022-11-2 14:56

本帖最后由 kiopc 于 2022-11-2 15:00 编辑

odmin 发表于 2022-11-2 14:51
显示是什么?
...
是本地的,返回结果是:Node.js (V8)
----------------------------------------
您要是方便的话,我私你我的xx号可以吗?(已私发)

odmin 发表于 2022-11-2 15:00

kiopc 发表于 2022-11-2 14:56
是本地的,返回结果是:Node.js (V8)
----------------------------------------
您要是方便的话,我私 ...

js中没有引入 crypto-js

pip install crypto-js

js 头部加引用

const CryptoJS = require('crypto-js')
页: [1] 2 3 4
查看完整版本: js逆向某视频VIP