微信小程序渗透测试:如何降低挖洞难度并拖取小程序包

2024-08-05
来源:网络整理

本文最初发表于:

火区社区 ()

0x00 简介

在日常的渗透测试中,在重放或者篡改数据包的时候,会碰到一些对数据进行加密或者签名的站点,这时候我们就需要去寻找签名或者加密的算法,而这个寻找的过程往往是比较困难的。

一般情况下,数据解密或者签名破解难度为:app>web≥,且API接口相同。为了减少不必要挖坑的难度,可以重点关注微信小程序。本次测试在某微信小程序站点进行。

0x01 拖拽微信小程序包

这里简单解释一下,微信小程序好像在PC、Mac上都加密了(//{系统用户名}///com../Data///com../Data///com../{微信版本号}/{用户ID}////{小程序ID}/),(C:\\{系统用户名}\\ \\{小程序ID}\),安卓端我们可以拖拽小程序包进去。

这里需要提前准备一部已经root过的安卓手机或者一个安卓模拟器,先进入目录/data/data/com..mm//{一串十六进制字符}//pkg删除其他小程序包,然后打开微信加载我们需要测试的目标小程序。

请注意,必须等到小程序完全打开后再点击几个功能,以确保所有包都在运行。随着当前小程序的规模逐渐增大,可能会有多个子包。

然后拖出相关的子包。

0x02 反编译小程序获取源代码

把相关的子包拖出来放到我们指定的目录中,然后使用工具对包进行反编译。

node wuWxapkg.js ../20220323/debug_607957350_2_511127914.wxapkg

在小程序原来存放的目录中会出现一个与小程序包同名的子文件夹,反编译后的源代码就在里面。

使用微信官方开发工具打开源代码项目:

1.选择“导入项目”,选择测试编号并导入

2.进入“本地设置”模块,勾选“不验证合法域名”功能

0x03 查找签名加密函数

案件背景

我先介绍一下这个示例案例的背景环境。

通过抓包我们发现该站点使用签名来验证提交数据的完整性,经过人工测试发现修改任意一个有值的参数都会导致服务器报错“签名错误”

这里简单介绍一种快速定位关键加密函数的方法——关键字搜索

关键词搜索

1.1. 项目中全局搜索关键词

常见的通用关键字如key、iv、sign、rsa、aes等。

1.2. 搜索加密接口名称

例如此处的接口名称为//f**//1.0,可以搜索其拆分路由名称:**

1.3. 搜索签名加密相关的参数名称

例如,您可以在这里搜索

介绍完背景和方法之后,我们就可以开始寻找签名功能了。

定位签名功能

在相关的开发者工具中,全局搜索

发现有两个js文件,输入这两个js文件继续定位关键位置。

发现关键字均存在于同一个关键函数中(注:对比两个js文件后发现内容大致相同且app-.js中没有乱码,所以后面就用这个js进行跟踪分析)

该参数存在于方法中,而另一个请求体中的参数也在其中,根据这个命名可以粗略推断该方法可能是用于签名的。

继续搜索这个方法名,看这个方法是否被调用过,发现关键参数:t.data,r。

继续在上下文中搜索t.data,发现一个关键点,阅读相关js代码发现里面的json字符串是从数据包参数中获取的,然后调用.方法将json字符串复制到t.data中。

因为找不到r.,所以我们就试着搜索关键词,看看能不能找到什么。结果发现确实有关键词。所以大致可以确定,我们原本要找的是签名方法。

微信开发工具怎么注释_微信小程序开发怎么注释_微信小程序开发加注释文档

0x04 编写签名函数

本地启动一个js脚本,写入0x03中找到的签名函数,提供必要的参数值,运行测试。

结果提示错误信息:r对象未定义。阅读代码后,我发现r对象只是用来提供其hex()方法。我回到项目源代码中,找到了hex()方法。

然后我跟着代码走,发现这里引用了MD5加密算法。

这里我们直接把src目录下的md5码复制粘贴到我们测试的js文件中。

执行js脚本文件,没有报错。同时发现签名是一致的。至此,已经找到相关签名函数,并可以成功调用运行。

0x05 链接 burp 插件

签名算法已经被破解,为了提高实际渗透测试过程中的效率,可以联动burp插件,这样当我们篡改数据的时候,就可以自动运行签名算法,直接获取相关签名。

这里先尝试了插件,但是发现在调试js阶段总是出错,同时在插件上也没有找到详细的错误信息,而将错误信息直接抛在命令行页面,更利于代码调试,所以这里选择了插件。

插件简单介绍:

使用前端加密函数对数据进行加密,方便对加密数据输入点进行模糊测试,例如可用于前端加密传输爆破等场景。工具本身提供了几种常见的加密算法可以直接参考。当加密和签名算法非常规时,也可以参考我们自定义的算法进行破解。

是一款已停产的无头浏览器,用于自动执行网页交互。它提供了可实现自动导航、屏幕截图、用户行为和断言的 API,使其成为在无头系统(如持续集成环境)中运行基于浏览器的单元测试的流行工具。

使用

我根据插件说明,复制了原来的调用模板,并根据文档注释修改了引用的js文件和后续的调用方法。

在签名所用的js中,复制0x04章节中签名成功的js代码,并为其设置一个get方法,用于返回签名。

function get(pass){     var pass1 = eval("("+pass+")");     var call = test(pass1,t);     var str = 'paramsDigest:'+call.paramsDigest+'-------'+'openapi_sign:'+call.openapi_sign;     return str;     }

在命令行中输入命令并运行

>phantomjs js1.js[*] load js successful[!] ^_^[*] jsEncrypterJS start![+] address: http://127.0.0.1:1664

然后点击bp上的测试,发送数据,可以看到相关的符号值完全正确。(这里的符号值和上图对应)

自动化改进

原来的js脚本只是回显了标志,但在实际过程中我们还需要cv方法把gest和修改后的数据字符串值扔回去,其实我们完全可以使用js正则表达式来修改输出,省去这个步骤。

首先定义一个方法,将json字符串转换成参数字符串。

function unchange(b){  var str = b,p1;  p1 = str.split(':"').join('=');  p1 = p1.split('",').join('&');  p1 = p1.replace('{','');  p1 = p1.replace('"}','');  return p1;}

然后连接+缝合

    var str = unchange(pass)+'¶msDigest='+call.paramsDigest+'&openapi_sign='+call.openapi_sign;     return str;

查看实际效果

可以直接在插件上篡改参数值然后复制结果进行安全测试。

自动化改进 2

但是我们还是需要将数据转换成非标准的json字符串,我尝试在插件的js中修改,但是相关数据本身包含xxx&xxx1&xxx2,而HTTP请求中又以&作为参数分隔符,这样会导致参数传到客户端时只剩下一个xxx参数,其余的都被丢弃了。

本来想先把数据库编码后再传输,但是想了想,其实没必要,需要在调用插件之前编码,在加密之前解码,这样比较复杂,还不如直接写个js,把数据转成json字符串然后扔给插件。

于是我就用了一个迂回救国的办法,写了一个js来自动生成json字符串。

function change(b){  var str = b,p1;  p1 = str.split('=').join(':"');  p1 = p1.split('&').join('",');  p1 = p1.replace(/^/,'{');  p1 = p1.replace(/$/,'"}');  return p1;}
var str = 'secuid=JY208740&udid=&sysVer=5.7.7&appName=&systemInfo=%2C%2C%2C&softName=WXIN_O&tradeClient=H5Trade&device_model=&deviceVers=&hwID=&conn_style=2.460.01.0.0&mip=&mac=&imsi=&iccid=&rNetAddr=&packtm=&reqtime=&operway=W&operorg=&netAddr=13888888888&session=12f4530351a3********7b6d8dec3c36f60dce1e83e03329d42fc269&userCode=334507******1792&pkg=H_117292&fundid=';  console.log(change(str));

到目前为止,除了需要手动将数据字符串转为json字符串外,勉强实现了数据的自动修改(不

0x06 涉及工具的下载方法

以上工具原文可以下载:

包含以下工具:

这是我第一次写文章,如果有错误,还请大家指正。

【火线地带云安全社区群】

加入群与技术大牛交流

加入群组,有机会获得免费节日礼物

分享