前言:
最近在学习js逆向,看到一个某网逆向案列,但是因为视频是几年前的了,加密用的是aes,我现在看到的已经变成sm2了,但是思路是一样的,借此分享一下过程。
纯技术交流,无不良引导。
过程:
1.这是网址:登录系统
2.f12打开抓包工具,再随便输账号密码,点击登录。
找到j_acegi的链接,账号密码的请求就在这里
我输入账号名为aa,密码被加密了,j_xxx_code是验证码,我们要做的就是还原出这个密码加密的过程
3.打开搜索,根据这个关键字尝试找到密码相关的。
4.desencrypt可能是一个加密字眼,可以在这打个断点看看。
凡是可能和加密或者密码相关的字眼都可以打上断点看看
5.重新输入账号密码验证一下
如果用的断点上的代码,就会停住。重新登录确实停住了,那说明这个确实极有可能和密码有关
6.这外面看不出什么,我们深入函数定义位置看看
点击那个蓝色的security…,会自动跳转到函数定义位置
7.进入到函数后,分析一下
看到这个函数内容,大致就能猜到这个路口找对了。
这里面大致是个判断,如果sm2走xxx,为aes走xxx,为des走xxx。最后返回d.security + b。
这里可能需要对一些常见加密算法的名称有点印象,aes和des是比较常用的,这边sm2我也不并了解,网上搜一下,是中国国家加密管理局发布的一种算法,简称国密。
8.每个路口断点看看走哪
走的是sm2,
9.深入get函数看看函数内容
断住之后,把鼠标放在get函数上,会有悬浮窗,点击蓝色的security
10.跳转到get后,可以看到又是多个判断
能走进来,a参数就是sm2,必然走的是sm2下面的内容。
第一行是:调用一个getsm2pubkey方法并赋值给b对象的sm2pubkey属性
第二行是:将字节内容赋值给b的security属性
11.打上断点,深入getSM2PubKey函数
12.这个函数就是返回一个长字符串
13.我们可以尝试打印一下这个字节内容
发现这个和加密的内容前三个是一样的
对比一下
我们前进,再回到desEncrypt函数下
此时
断在这里时,我们可以在控制台输入一下d,返回的是个对象
desEncrypt函数返回的d.security + b, d.security就是这种乱码,b是另一个encs函数的返回值,且这个encs函数接收sm2pubkey和b(这个b是密码明文)。断在这里时,可以把鼠标放在b上,会显示出b的内容,可以看到就是密码123
14.深入encs函数看看
可以看到这个函数接受3个参数,返回另一个函数,并把接受的参数作为sm2Encrypt函数的参数。
15.老方法还是断点,继续深入sm2Encrypt函数看看
16.这里可以说就是整个加密的核心了
根据参数能猜出,这个sm2Encrypt接受3个参数(数据,公钥,模式)
17.复制代码到本地,试着复现这个加密过程
逆向本身不需要关心这个算法怎么做的,如果要还原这个算法那太复杂了,我们只需要能复制这些代码到本地,实现这个加密过程即可。
我这里的用的pycharm,这个sm2.js代码全部复制过来
18.运行一下,看下什么反应(补环境,重点)
18-1显示window没有被定义,那就补个window
18-2补上window后,显示CrytoJS没有被定义.
CrytoJS这个是js中加解密的工具包,可以导入,也可以直接复制这边代码
这里用到了CryptoJS,可以直接在这打上断点
跳转到这个aes.js函数里,这里就是他用的CryptoJS,直接复制全部到本地
18-3补上CryptoJS后,显示navigator没被定义,那就补上 navigator
18-3补上navigator后,显示SM2Utils没被定义
那就继续补上SM2Utils
18-4补上SM2Utils后,运行没报错了
那这时我们就要尝试输入密码,调用一下看看密码加密对不对了
18-5 复现desEncrypt的逻辑
这里我自定义了一个sm2函数,因为sm2PubKey和security是定死的,所以直接复制过来,调用SM2Utils.encs(),传入密码和公钥,返回security +b。
这里逻辑回到之前的函数中稍微理一下。总之是复现上述函数中的过程即可
19.最后运行结果
20.对比网站加密结果和本地代码生成结果
经过我多次测试,这里输入的密码不变,但是加密结果却是变化的,说明这加密里有东西在变化。
我找到了这个变化的地方,就是d = c.generateKeyPairHex()
这里**c.generateKeyPairHex()**的返回值是随机的
在控制台尝试,能够看到每次都是变化的。
我只需要在输入密码时,拿到浏览器中c.generateKeyPairHex()的值,复制到本地,密码一样,这个c.generateKeyPairHex()的值一样,那加密结果就应该是一样的,至少这一个变化的地方被我堵死。
21.对比密码成功
21-1 输入密码,准备好断点,拿到**c.generateKeyPairHex()**值
22-2 断住了,去控制台拿值
22-3 复制对象,拿到pycharm本地
22-4 注释掉原来的,把d值定死
22-5 最后对比加密结果:
22.python调用js代码,实现密码加密
使用execjs模块。
但是因为这里面有乱码,execjs调用会报错。
23.解决execjs遇到乱码报错,解决编码问题
导入execjs前,先加上这三行代码,再运行就可以了
成功解决
总结:
这个乱码问题也是第一次遇到,刚开始也是不知道啥原因,我把"\u534d\u3220\u4d45"这段字节去掉后,就能正常运行。