小程序动态调试-解密加密数据与签名校验,小程序动态调试,解密加密数据与签名校验揭秘

马肤

温馨提示:这篇文章已超过479天没有更新,请注意相关的内容是否还可用!

摘要:,,本文将探讨小程序动态调试过程中的一个重要环节——解密加密数据与签名校验。通过对小程序运行过程中的加密数据和签名进行深入研究,揭示其背后的工作原理和机制。本文将介绍如何有效解密加密数据,以及如何准确进行签名校验,以确保小程序的安全性和稳定性。通过深入了解这些技术细节,开发者可以更好地进行小程序调试和优化,提升用户体验。

前言:

微信小程序的加密与验签早前大多数情况,要么就是逆向获取源码而后拿到加密秘钥,要么就是逆向拿到源码后使用腾讯自带的小程序开发者功能进行动态调试模拟,今天介绍一款志远大佬的开源工具—WeChatOpenDevTool

工具下载地址: https://github.com/JaveleyQAQ/WeChatOpenDevTools-Python

正文:

首先运行脚本,而后打开微信小程序,注意先后顺序,打开小程序后,打开调试器

小程序动态调试-解密加密数据与签名校验,小程序动态调试,解密加密数据与签名校验揭秘 第1张

小程序动态调试-解密加密数据与签名校验,小程序动态调试,解密加密数据与签名校验揭秘 第2张

小程序动态调试-解密加密数据与签名校验,小程序动态调试,解密加密数据与签名校验揭秘 第3张

本次使用的依然是PC端微信进行小程序抓包,抓包使用的工具就是fiddler+burpsuite ,具体使用方式上文有过介绍,此处不再进行赘述

小程序动态调试-解密加密数据与签名校验,小程序动态调试,解密加密数据与签名校验揭秘 第4张

大家可以看到,首先请求参数是加密的,并且请求头包含nonce、timestamp、signature信息,若是看过笔者的第一篇加密解密文章就知道,这里是一个签名校验,绝大多数的签名校验都是利用以上信息结合body进行加密,少数的还会带上uri或者是一些其他参数,那么我们今天要做的就是获取他请求包包体加密的方式以及签名校验的生成方法

老规矩,直接在开发者调试里面全局搜索requestData参数,这是最快定位的方法,当然了也可以利用网络信息进行断点调试

小程序动态调试-解密加密数据与签名校验,小程序动态调试,解密加密数据与签名校验揭秘 第5张

我们很快就找到了关键信息requestData: n.encrypt(o, r),一眼丁真

小程序动态调试-解密加密数据与签名校验,小程序动态调试,解密加密数据与签名校验揭秘 第6张

通过单步步过,我们可以获知n = require(t(219))为加密函数,所以需要进去看一下加密方法,,F9步入后发现其实是sm4国密算法,sm4大家可以理解为改良版的aes加密

小程序动态调试-解密加密数据与签名校验,小程序动态调试,解密加密数据与签名校验揭秘 第7张

继续进行步过(F10),结果如下:

小程序动态调试-解密加密数据与签名校验,小程序动态调试,解密加密数据与签名校验揭秘 第8张

小程序动态调试-解密加密数据与签名校验,小程序动态调试,解密加密数据与签名校验揭秘 第9张

小程序动态调试-解密加密数据与签名校验,小程序动态调试,解密加密数据与签名校验揭秘 第10张

经过测试,这里面的sm4秘钥是写死的,直接用就行

小程序动态调试-解密加密数据与签名校验,小程序动态调试,解密加密数据与签名校验揭秘 第11张

在获取了加密算法与秘钥的情况下,我们继续调试,幸运的是在进行下断点的时候,看到了这个签名校验的函数

小程序动态调试-解密加密数据与签名校验,小程序动态调试,解密加密数据与签名校验揭秘 第12张

小程序动态调试-解密加密数据与签名校验,小程序动态调试,解密加密数据与签名校验揭秘 第13张

疑似signature

小程序动态调试-解密加密数据与签名校验,小程序动态调试,解密加密数据与签名校验揭秘 第14张

小程序动态调试-解密加密数据与签名校验,小程序动态调试,解密加密数据与签名校验揭秘 第15张

跟进函数l(u, i, n, v)

小程序动态调试-解密加密数据与签名校验,小程序动态调试,解密加密数据与签名校验揭秘 第16张

F9进入到l()函数内,此时函数变为l(e, t, n, r),这里面的e,t,n,r 就相当于u, i, n, v ,这里面就是一个形参,而传入进去的u, i, n, v才是真正的实参

小程序动态调试-解密加密数据与签名校验,小程序动态调试,解密加密数据与签名校验揭秘 第17张

我们可以看到,函数最后一行s(p + e + c + u) ,这里其实才是最终输出的值,所以我们需要关注p/e/c/u这四个参数是怎么来的,s()这个函数做了什么

首先,p这个参数其实是一个三元运算结果,我们传入的r参数此时是-1,他会做一个比较,大于等于0和小于0的时候去输出不同的p值

r >= 0 ? p = [(o = a)(345), o(230), o(211), “RhYqRedo=K7JvcuyjpbyppnZr7qQGs21JQsTNSp5TJm”, o(269), “Tyrcs”][o(343)](1, 5)o(215) : p = d();

由于此时是-1,所以p=d(),大家可以步入d()函数,但是其实无论是大于还是小于,结果都是写死的哈

小程序动态调试-解密加密数据与签名校验,小程序动态调试,解密加密数据与签名校验揭秘 第18张

r >=0 的时候,

p=NBMExPe9iO{WXsAxZMRhYqRedo=K7JvcuyjpbyppnZr7qQGs21JQsTNSp5TJmczO

r var n = 8 * r.length , t = n % 512; t = t = 448 ? 512 - t % 448 - 1 : 448 - t - 1; for (var e = new Array((t - 7) / 8), o = 0, a = e.length; o = 0; u--) if (n.length > 8) { var l = n.length - 8; c[u] = parseInt(n.substr(l), 2), n = n.substr(0, l) } else n.length > 0 ? (c[u] = parseInt(n, 2), n = "") : c[u] = 0; for (var i = [].concat(r, [128], e, c), s = i.length / 64, v = [115, 128, 22, 111, 73, 20, 178, 185, 23, 36, 66, 215, 218, 138, 6, 0, 169, 111, 48, 188, 22, 49, 56, 170, 227, 141, 238, 77, 176, 251, 14, 78], h = 0; h

其实在这里笔者就卡主了,不会了,完全看不出来是什么,这也不是sha1-256,因为笔者去试过了,但是柳暗花明的就是,笔者在第二天清晨看到了这个

小程序动态调试-解密加密数据与签名校验,小程序动态调试,解密加密数据与签名校验揭秘 第19张

山重水复疑无路,柳暗花明又一村,原来是SM3

小程序动态调试-解密加密数据与签名校验,小程序动态调试,解密加密数据与签名校验揭秘 第20张

小程序动态调试-解密加密数据与签名校验,小程序动态调试,解密加密数据与签名校验揭秘 第21张

所以此时问题迎刃而解

小程序动态调试-解密加密数据与签名校验,小程序动态调试,解密加密数据与签名校验揭秘 第22张

s(p + e + c + u) 这个函数就是把p + e + c + u四个参数串起来,然后进行SM3编码

上次说到,e的值其实就是个uuid,所以我们回到上面,看一下e是怎么来的

小程序动态调试-解密加密数据与签名校验,小程序动态调试,解密加密数据与签名校验揭秘 第23张

进入c()函数

function c() {
        for (var e = a, t = [], n = e(306), r = 0; r  

小程序动态调试-解密加密数据与签名校验,小程序动态调试,解密加密数据与签名校验揭秘 第24张

大家不需要完全看得懂,我们只需要知道,他是由啥组成的,在什么位置有横杠就行

小程序动态调试-解密加密数据与签名校验,小程序动态调试,解密加密数据与签名校验揭秘 第25张

这个 JavaScript 函数的作用是生成一个符合 UUID(Universally Unique Identifier)规范的字符串。UUID 是一种用于标识信息或对象的唯一标识符。

现在让我们分解这个 JavaScript 函数的工作原理:

使用一个名为 a 的函数作为参数传入(在这里被省略了)。

创建一个空数组 t,用于存储生成的 UUID。

通过调用函数 e(306) 获取一个随机数生成器。

循环执行 36 次以下操作

生成一个 0 到 15 之间的随机整数,然后转换为十六进制字符。

将生成的字符存储到数组 t 中。

修改数组中的特定索引位置,使得生成的 UUID 符合 UUID 版本 4 的规范:

将第 15 个字符设置为 “4”(UUID 版本号)。

将第 20 个字符的高 4 位设置为 “8”, “9”, “a” 或 “b”(UUID 变体)。

将数组中的特定索引位置设置为连字符 “-”。

使用 join() 方法将数组中的元素连接成一个字符串,并移除其中的连字符 “-”,最终得到 UUID。

下面是相应的 Python 代码:

python
import random
def generate_uuid():
    characters = '0123456789abcdef'
    uuid_list = [random.choice(characters) for _ in range(36)]
    uuid_list[14] = '4'  # UUID version 4
    uuid_list[19] = random.choice('89ab')  # Variant
    uuid_list[8] = uuid_list[13] = uuid_list[18] = uuid_list[23] = '-'
    return ''.join(uuid_list)

测试生成的 UUID

print(generate_uuid())

这个 Python 函数与 JavaScript 函数的实现类似,使用了 random.choice() 函数来从指定的字符集中随机选择字符,并通过字符串操作和列表操作生成 UUID。

最后总结一下,这个如果写脚本的话,一个接口就需要一个脚本,有点不值了,建议能力强的写个ipython写进burp里,只是难度有点…


0
收藏0
文章版权声明:除非注明,否则均为VPS857原创文章,转载或复制请以超链接形式并注明出处。

相关阅读

  • 【研发日记】Matlab/Simulink自动生成代码(二)——五种选择结构实现方法,Matlab/Simulink自动生成代码的五种选择结构实现方法(二),Matlab/Simulink自动生成代码的五种选择结构实现方法详解(二)
  • 超级好用的C++实用库之跨平台实用方法,跨平台实用方法的C++实用库超好用指南,C++跨平台实用库使用指南,超好用实用方法集合,C++跨平台实用库超好用指南,方法与技巧集合
  • 【动态规划】斐波那契数列模型(C++),斐波那契数列模型(C++实现与动态规划解析),斐波那契数列模型解析与C++实现(动态规划)
  • 【C++】,string类底层的模拟实现,C++中string类的模拟底层实现探究
  • uniapp 小程序实现微信授权登录(前端和后端),Uniapp小程序实现微信授权登录全流程(前端后端全攻略),Uniapp小程序微信授权登录全流程攻略,前端后端全指南
  • Vue脚手架的安装(保姆级教程),Vue脚手架保姆级安装教程,Vue脚手架保姆级安装指南,Vue脚手架保姆级安装指南,从零开始教你如何安装Vue脚手架
  • 如何在树莓派 Raspberry Pi中本地部署一个web站点并实现无公网IP远程访问,树莓派上本地部署Web站点及无公网IP远程访问指南,树莓派部署Web站点及无公网IP远程访问指南,本地部署与远程访问实践,树莓派部署Web站点及无公网IP远程访问实践指南,树莓派部署Web站点及无公网IP远程访问实践指南,本地部署与远程访问详解,树莓派部署Web站点及无公网IP远程访问实践详解,本地部署与远程访问指南,树莓派部署Web站点及无公网IP远程访问实践详解,本地部署与远程访问指南。
  • vue2技术栈实现AI问答机器人功能(流式与非流式两种接口方法),Vue2技术栈实现AI问答机器人功能,流式与非流式接口方法探究,Vue2技术栈实现AI问答机器人功能,流式与非流式接口方法详解
  • 发表评论

    快捷回复:表情:
    评论列表 (暂无评论,0人围观)

    还没有评论,来说两句吧...

    目录[+]

    取消
    微信二维码
    微信二维码
    支付宝二维码