点点数据 js逆向(超详细)

前言:

        天几天出了一个js逆向环境搭建的博文,因为涉及到pycharm专业版破解,审核不通过,敏感部分全部删掉了,官方给出的说法是涉及到大厂软件破解😀😀😀

        今天肝一个点点数据js逆向,后续网页结构可能更新,本博文只提供思路参考

1.数据接口分析

        第一步:

        打开网站按 f12 打开开发者工具,我这里用的中文版开发者工具界面,因为感觉中文对菜鸡比较友好,找英文选项的可以直接挨个翻译

        如下图,切换到网络选项,并点击清除网络日志(ctrl+l),没有网络选项的需要点击箭头右边的加号添加网络选项才有

        第二步:

        随便点一个分类,换页,因为这样才会出现新的数据包(下图框起来的就叫数据包)

        第三步:

        全局搜索,搜索页面内数据

搜索出来只有一个数据包包含这个游戏的名字,也就是说这个就是我们要拿到的数据包

接下来打开他的负载,看一下它都携带了什么参数发送请求

        再次切换网页分类,再进去全局搜索搜刚才那个游戏,仔细观察这两个数据包的负载,是有变化的,这个k值发生了变化,这个k就是我们需要进行逆向的东西

2.详解异步栈堆跟栈分析与断点

        异步操作在JavaScript中很常见,比如Promise、async/await等。在进行逆向工程时,理解异步栈堆和栈的分析是至关重要的。

  1. 异步栈堆:异步栈堆是指在JavaScript引擎中用于管理异步任务的数据结构。异步任务包括Promise回调、setTimeout、事件处理器等。当这些任务被调度执行时,它们会进入异步栈堆中等待执行。异步栈堆的管理使得JavaScript能够处理并发任务,保证了代码的顺序执行。

  2. 栈分析:栈是JavaScript引擎中用于管理执行上下文的数据结构,执行上下文包括函数调用、变量声明等。在进行逆向工程时,栈的分析可以帮助理解代码的执行流程和上下文切换情况。通过分析栈的调用关系和变量作用域,可以更好地理解代码的逻辑和结构。

        将选项切换到标头,将他的路径复制下来,然后将开发者工具切换到源代码选项,按图所示的箭头操作,添加断点

添加好断点后,再次切换网页分类,成功断住

3.详解头部签名多参数栈堆分析

        接下来我们开始找他的网络拦截器,也是为了进一步去找k值加密的位置

网络拦截器通常是指一种网络安全技术,用于阻止恶意攻击者利用 HTTP 请求中的头部、参数以及栈堆信息来进行攻击。这种拦截器可以在网络通信过程中对请求进行监控和分析,检测是否存在异常或恶意的请求,并在必要时拦截这些请求,从而保护网络系统的安全。

网络拦截器一般都是配合异步栈使用

滚轮往下,找到这个request点进去,在高亮那一行打上断点,再次切换分类(前面打的断点要释放掉,才可以在这里断住)

断住之后,查看他的这个m列表,这个列表储存了很多方法,都是回调方法

回调方法是指在异步操作完成后执行的函数。回调函数通常作为参数传递给异步函数,以便在异步操作完成后被调用。

在 JavaScript 中,常见的异步操作包括网络请求、定时器、事件处理等。当执行这些异步操作时,JavaScript 不会等待其完成,而是继续执行后续的代码。一旦异步操作完成,系统会调用预先定义好的回调函数,以便处理异步操作的结果或执行相关的逻辑。

        一共有十几个,点进去第一个方法(网络拦截器就在里面)

一共有四个拦截器

后面两个是异常的时候才会用到的,不是我们要找的

前两个一个是请求一个是响应,我们需要找的是请求拦截器(因为先请求才会有响应)

在拦截器里面打上断点,释放程序(前面的断点要先释放掉),此时k值还没有出现

在拦截器外面设置断点,释放程序,此时k值出现了,说明这个t方法就是生成k值的

继续往里面进,查看t方法的具体内容

隔四行打一个断点,进一步找出生成k值的地方(一边调试一边观察右侧k值是否出现),有些地方一直循环的,可以把断点往下放一点

调试过后得出是由M生成的,于是按上面的方法,继续点进去M看内容(步骤较多,主要是为了掌握调试方法,用多了就很快了)

进去M之后,还需要继续找一下,截图截不全,太长了

function M(e, t, n) {
            e = e.replace("/user/api/", "/common/v1/").replace("/web/api/", "/".concat("app", "/v1/")).replace("/web/api2/", "/".concat("app", "/v2/")).replace("/web/api3/", "/".concat("app", "/v3/")).replace("/video/api/", "/videotest/v1/").replace("/user/order/", "/put/v1/");
            var r = [{
                proxy: "/".concat("app"),
                target: "",
                sort: "dd",
                num: 10,
                s: n.state.u.s,
                k: n.state.u.k,
                l: n.state.u.l,
                d: n.state.u.d
            }, {
                proxy: "/common",
                target: "",
                sort: "dc",
                num: 10,
                s: n.state.u.s,
                k: n.state.u.k,
                l: n.state.u.l,
                d: n.state.u.d
            }, {
                proxy: "/videotest/",
                target: "/",
                sort: "dv",
                server: !0,
                num: 10,
                s: n.state.u.s,
                k: n.state.u.k,
                l: n.state.u.l,
                d: n.state.u.d
            }];
            return "/track/baidu_ocps" === e && (t.baseURL = "/"),
            ["/common/v1/config/basic", "/common/v1/config/system"].includes(e) || r.forEach((function(n) {
                if (e.includes(n.proxy)) {
                    var path = e.replace(n.proxy, n.target);
                    if ("get" === t.method) {
                        t.paramsSerializer = function(e) {
                            return _.a.stringify(e, {
                                arrayFormat: "repeat"
                            })
                        }
                        ,
                        t.params = h()(t.params, !1) || {};
                        var r = h()(t.params, !1)
                          , o = Object(y.a)(r, path, {
                            s: n.s,
                            k: n.k,
                            l: n.l,
                            d: n.d,
                            sort: n.sort,
                            num: n.num
                        }, "get");
                        t.params.k = o
                    } else if ("post" === t.method || "delete" === t.method || "put" === t.method) {
                        t.data = h()(t.data, !1) || {};
                        var data = h()(t.data, !1)
                          , d = Object(y.a)(data, path, {
                            s: n.s,
                            k: n.k,
                            l: n.l,
                            d: n.d,
                            sort: n.sort,
                            num: n.num
                        }, "post");
                        t.data.k = d
                    }
                }
            }
            )),
            t
        }

4.详解js逆向定位与调试

  继续打断点调试,找他的k值生成位置(同上,前面打的断点要先释放掉),这里很多地方打不进去断点,因为有些代码是一整行的,能打就打,然后一边调试一边观察k值就可以了

调试过后找到加密的地方在接近最下面的地方,把断点放到M结尾处,其他断点放掉,切换分类,这里是生成了o值,最后赋值给了k,变成k值

可以到控制台验证一下输出是否为加密好的o值(断点要打对控制台才能正常输出)

最后通过分析加密方法,得出是一个标准的MD5加密算法,自行解密即可

  • 31
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
根据提供的引用内容,似乎是在讨论对于一个加密的网址进行解密的问题。其中使用了AES加密算法和CryptoJS库来实现解密操作。具体代码如下: const CryptoJS = require('crypto-js'); function getRealUrl(hh) { var s = "qnbyzzwmdgghmcnm"; var aa = hh.split("/"); var aaa = aa.length; var bbb = aa[aaa - 1].split('.'); var ccc = bbb; var cccc = bbb; var r = /^\ ?[1-9][0-9]*$/; if (r.test(ccc) && cccc.indexOf('jhtml') != -1) { var srcs = CryptoJS.enc.Utf8.parse(ccc); var k = CryptoJS.enc.Utf8.parse(s); var en = CryptoJS.AES.encrypt(srcs, k, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 }); var ddd = en.toString(); ddd = ddd.replace(/\//g, "^"); ddd = ddd.substring(0, ddd.length - 2); var bbbb = ddd + '.' + bbb; return bbbb; } } getRealUrl() 这段代码是用于对加密的网址进行解密,具体的解密过程如下: 1. 将加密前的字符串cc分割成数组aa,获取数组长度aaa和数组最后一个元素bbb。 2. 判断最后一个元素bbb是否符合一定的格式要求。 3. 如果符合要求,则将cc转换成CryptoJS的Utf8格式的srcs,并生成一个Utf8格式的密钥k。 4. 使用AES加密算法将srcs和k进行加密操作,采用ECB模式和Pkcs7填充方式。 5. 将加密结果转换成字符串ddd,并替换其中的'/'字符为'^'。 6. 截取ddd中除去最后两个字符的部分,然后与bbb拼接起来,得到解密后的网址bbbb。 7. 返回解密后的网址bbbb。 关于js逆向深圳信数据服务的问题,根据提供的引用内容,目前并没有相关的信息来回答该问题。请提供更多相关的信息,以便更好地回答您的问题。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [js逆向-某市公共资源交易网](https://blog.csdn.net/weixin_46672080/article/details/126003502)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [aqistudy真气网JS逆向 + 数据采集(20220801)](https://blog.csdn.net/zhu6201976/article/details/126124548)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值