【爬虫逆向分析实战】某笔登录算法分析——本地替换分析法

news/2024/7/19 12:00:42 标签: 爬虫, 算法, python

前言

作者最近在做一个收集粉币的项目,可以用来干嘛这里就不展开了😁,需要进行登录换算token从而达到监控收集的作用,手机抓包发现他是通过APP进行计算之后再请求接口的,通过官网分析可能要比APP逆向方便多,但是通过这几天的观察我并没有头绪,这篇文章草稿创建了接近一个月了,无从下笔,借助了人工智能也没有达到效果,可见它的难度不一般(也可能是我JS基础太过薄弱的原因),本次我们用一种分析方法慢慢的瓦解击破他的层层逻辑!

JS启动分析

这里从网站入手,原因如下:

  • 没有验证码
  • JS结构清晰

在这里插入图片描述
观察不难发现,密码是被加密的
在这里插入图片描述
必定是通过js进行加密的,我们查看启动器
在这里插入图片描述
发现有以下几个关键JS
在这里插入图片描述
第一感觉是,main为主方法,其他的是用来调用的,encrypt应该是用于加密的方法,通过上面的启动器证实了main.js的确是优先启动的

找到main.js搜索password
密码通过this.encrypt()进行加密的
在这里插入图片描述

var n = {
phone: this.phone,
verification: this.verification,
password: this.encrypt(this.password)
};

找到encrypt()方法

encrypt(n) {
return window.encrypt(this.publicKey, n)
}

需要用到一个参数publicKey
在这里插入图片描述
到这里我们基本搞清楚了,登录时将原密码,进行调用window.encrypt(this.publicKey, n)加密

猜想

猜测n为原密码,如何证实呢?有很多人想说观察代码的调用,这当然可以,但如果是复杂的代码或者加密的你还能看吗?
这里用了一个浏览器自带的功能本地替换,可以无视代码加密,为什么这么说,因为代码加密最后还是要被执行,不能执行的代码加密了有啥用呢??

我们找到main.js将n弹窗显示

     encrypt(n) {
      alert(n);
      return encrypt(this.publicKey, n)
      }

在这里插入图片描述
替换到本地启用后,我们进行登录模拟,看看有没有效果?
在这里插入图片描述
在这里插入图片描述
这里将我的登录密码弹出来了,猜想正确!

顺藤摸瓜

有了刚刚的思想,我们直接找encrypt.js,因为在main.js中最后调用了

 return encrypt(this.publicKey, n)

而在main.js中没有其他方法了 ,在encrypt.js我们找到了相关方法

 av.encrypt = function(aG, z) {
 
        var t = new N();
        t.setPublic(a(aG), "10001");
        
        return ai(t.encrypt(z))
    }

代码是否运行到这里,和刚刚一样验证一下就可以了
在这里插入图片描述

发现又调用了新的方法ai(t.encrypt(z))

 function ai(aG) {
        var z;
        var aH;
        var t = "";
        for (z = 0; z + 3 <= aG.length; z += 3) {
            aH = parseInt(aG.substring(z, z + 3), 16);
            t += ad.charAt(aH >> 6) + ad.charAt(aH & 63)
        }
        if (z + 1 == aG.length) {
            aH = parseInt(aG.substring(z, z + 1), 16);
            t += ad.charAt(aH << 2)
        } else {
            if (z + 2 == aG.length) {
                aH = parseInt(aG.substring(z, z + 2), 16);
                t += ad.charAt(aH >> 2) + ad.charAt((aH & 3) << 4)
            }
        }
        while ((t.length & 3) > 0) {
            t += Y
        }
        alert(t);
        return t
        
    }

我们在修改代码将t进行弹窗显示,重新来一遍整个登录过程,观察最后的加密密码是否与请求的一致

模拟登录测试

在这里插入图片描述
在这里插入图片描述
经过对比是一致的,由于我们的环境是python,接下来借助GPT进行代码转换

代码转换

通过将涉及到的函数调用方法进行罗列,通过人工智能改写

var publicKey='ANKi9PWuvDOsagwIVvrPx77mXNV0APmjySsYjB1/GtUTY6cyKNRl2RCTt608m9nYk5VeCG2EAZRQmQNQTyfZkw0Uo+MytAkjj17BXOpY4o6+BToi7rRKfTGl6J60/XBZcGSzN1XVZ80ElSjaGE8Ocg8wbPN18tbmsy761zN5S';
var n='密码'
encrypt(publicKey, n)

encrypt(aG, z) {
        var t = new N();
        t.setPublic(a(aG), "10001");
        return ai(t.encrypt(z))
    }

    function a(aI) {
        alert("经过");
        var aG = "";
        var aH;
        var t = 0;
        var z;
        for (aH = 0; aH < aI.length; ++aH) {
            if (aI.charAt(aH) == Y) {
                break
            }
            v = ad.indexOf(aI.charAt(aH));
            if (v < 0) {
                continue
            }
            if (t == 0) {
                aG += aF(v >> 2);
                z = v & 3;
                t = 1
            } else {
                if (t == 1) {
                    aG += aF((z << 2) | (v >> 4));
                    z = v & 15;
                    t = 2
                } else {
                    if (t == 2) {
                        aG += aF(z);
                        aG += aF(v >> 2);
                        z = v & 3;
                        t = 3
                    } else {
                        aG += aF((z << 2) | (v >> 4));
                        aG += aF(v & 15);
                        t = 0
                    }
                }
            }
        }
        if (t == 1) {
            aG += aF(z << 2)
        }
        return aG
    }


        function ai(aG) {
        // alert(aG);
        var z;
        var aH;
        var t = "";
        for (z = 0; z + 3 <= aG.length; z += 3) {
            aH = parseInt(aG.substring(z, z + 3), 16);
            t += ad.charAt(aH >> 6) + ad.charAt(aH & 63)
        }
        if (z + 1 == aG.length) {
            aH = parseInt(aG.substring(z, z + 1), 16);
            t += ad.charAt(aH << 2)
        } else {
            if (z + 2 == aG.length) {
                aH = parseInt(aG.substring(z, z + 2), 16);
                t += ad.charAt(aH >> 2) + ad.charAt((aH & 3) << 4)
            }
        }
        while ((t.length & 3) > 0) {
            t += Y
        }
        alert(t);
        return t
        
    }

http://www.niftyadmin.cn/n/5232158.html

相关文章

AGI智能新时代,大模型为软件开发带来范式变革

导语 | 人工智能作为新一轮科技革命和产业变革的重要驱动力量&#xff0c;尤其是在当下新一轮 AI 大模型、生成式 AI 浪潮背景下&#xff0c;重视通用人工智能&#xff08;AGI&#xff09;成为行业的共识。在当前&#xff0c; AGI 技术背后的逻辑究竟是怎样的&#xff1f;技术创…

http客户端高并发工具

如果报打开文件限制&#xff0c;可以通过ulimit -n 100000 改大 方法一&#xff1a; ab -n 1000000 -c 10000 http://example.com/ ab工具亲测更加好用。 方法二&#xff1a; import asyncio import aiohttpasync def make_request():async with aiohttp.ClientSession() as …

智能配电箱监控系统

智能配电箱监控系统是一种用于实时监控配电箱运行状态和电能质量的系统。它通过集成应用物联网技术&#xff0c;实现对配电箱的数据采集、整合和处理&#xff0c;从而让工作人员能够远程了解和掌握配电箱的情况。通过电力设备的数字化&#xff0c;依托电易云-智慧电力物联网&am…

70 NXOpen Block UI 树列表控件(Tree)(一)

目录 一、树列表控件&#xff08;Tree&#xff09;概述 二、操作树列表的Tree类和Node类 三、树列表插入列(Column ) 四、创建和插入Node节点,并对列表添加数据创建和插入Node节点,并对列表添加数据 五、树列表各种回调函数(Callback ) 六、树列表添加右键菜单 一、树列表…

springboot项目中注入bean后,调用时报n

需求&#xff1a; 在socket接收到上报数据后&#xff0c;在handler中调用工具类中ProtocolAnalyse的conAnalyse(byte[] data, int dataLen)解析数据。解析数据后&#xff0c;将解析后的结果保存至数据库。注入了三个bean&#xff1a; Autowiredprivate PersonTeService person…

Leetcode—704.二分查找【简单】

2023每日刷题&#xff08;四十七&#xff09; Leetcode—704.二分查找 实现代码 int lower_bound(int* arr, int numsSize, int tar) {int left 0, right numsSize;int mid left (right - left) / 2;while(left < right) {mid left (right - left) / 2;if(arr[mid] …

分支定界搜索以及 Python 中的示例和实现

一、说明 我们将尝试了解本文中的一种启发式搜索技术。启发式技术是确定几种替代方案中哪一种最有效实现特定目标的标准。分支定界搜索也称为统一成本搜索。 二、什么是分支定界搜索算法&#xff1f; 分支定界是一种用于组合、离散和一般数学优化问题的搜索算法。它与回溯类似&…

GROM gorm.DB 对象剖析

文章目录 1.GORM 简介2.gorm.DB 简介2.1 定义2.2 初始化2.3 查询方法2.4 事务支持2.5 模型关联2.6 钩子&#xff08;Hooks&#xff09;2.7 自定义数据类型 3.为什么不同请求可以共用一个 gorm.DB 对象&#xff1f;4.链式调用与方法5.小结参考文献 1.GORM 简介 GORM 是一个流行…