搞定那个加密的公众号:一次有点折腾的密钥固定实战

admin 2026-01-30 18:01:03 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文记录了一次针对微信公众号加密流量的渗透实战。面对RSA与AES混合加密,作者分析H5页面JS代码后,通过Burp拦截篡改JS响应,将前端随机生成的AES密钥替换为固定字符串,从而解密流量。文章强调了前端加密的脆弱性,建议开发避免过度依赖前端加密,实施SRI校验并将核心逻辑放服务端。 综合评分: 82 文章分类: 渗透测试,WEB安全,红队,实战经验


cover_image

搞定那个加密的公众号:一次有点折腾的密钥固定实战

adman adman

李白你好

2026年1月30日 08:01 青海

免责声明:由于传播、利用本公众号李白你好所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,公众号李白你好及作者不为此承担任何责任,一旦造成后果请自行承担!如有侵权烦请告知,我们会立即删除并致歉。谢谢!

那天接到一个测试任务,目标看起来挺正经的微信公众号。一上来就给了我个下马威——Burp里抓到的请求,全是一堆加密的乱码。

文章作者:先知社区(adman )

文章来源:https://xz.aliyun.com/news/91362

1

测试过程

流量长这熊样:

典型的“加密三件套”:加密的密钥、加密的数据、外加一个签名。心里大概有数了——八成是前端随机生成个AES密钥,用RSA公钥加密后传过去,数据用AES加密,最后再算个MD5签名。

绕道走:浏览器里看代码

微信里调试是不用想了,听说乱开调试可能封号。不过我发现这个公众号的H5页面,是不是可以直接在浏览器里打开?

从Burp历史记录里翻出地址:/******h5/index.html,往浏览器里一输,还真加载出来了。

F12一开,代码清清楚楚。找到关键处:

// AES 密钥生成function uid() {  return "xxxxxxxxxxxxxxxxxxxxxxxxxxxx".replace(/x/g, function() {    var r = 16 * Math.random() | 0;    return r.toString(16);  });};var securityInterceptor = function(chain) {  var appSecret = "c13w5*****7421";  // 签名盐值  var key = uid();  // 生成随机AES密钥  // RSA加密AES密钥  var keyEncrypt = rsa.encrypt(key);  // AES加密业务数据(ECB模式,PKCS7填充)  var contentEncrypt = aes.encrypt(data, keyHex, {    "mode": mode_ecb_default.a,    "padding": pad_pkcs7_default.a  }).toString();  // 生成签名  var sign = md5(contentEncrypt + appSecret).toString();  return {    "encrypt": 2,    "key": keyEncrypt,    "content": contentEncrypt,    "sign": sign  };};

再看加密逻辑:

  • uid()

    生成随机的32位字符串(就是AES密钥)

  • RSA加密这个密钥 → 变成key字段

  • 用这个密钥使用AES算法加密业务数据 → 变成content字段

  • md5(content + "盐值")

    → 变成sign字段

逻辑是清楚了,但问题来了:在浏览器里能分析代码,却登录不了——需要微信的openid

异想天开:用CE改内存?

记得之前看过篇文章,有人用Cheat Engine改小程序的内存,达到密钥固定的效果。我想着能不能也这么干。

思路很直接:找到Math.random()那行,让它永远返回0,这样uid()每次都生成同一个字符串。

打开CE,挂上微信进程,搜索……然后就卡住了。JS代码在内存里怎么定位,我真不太会。搜了半天,不是找到一堆无关字符串,就是找到地址但改了不起作用。折腾一小时,无果。突然想到一句名言“世上无难事只要肯放弃”,放弃干饭去。

柳暗花明:Burp里改JS

吃完饭回来,突然冒出个想法:这JS文件是从测试对象服务器加载的吧?如果我能改服务器返回的JS……

马上打开Burp的过滤器设置,让其显示js文件。重新打开页面(需要重启微信),果然在历史记录里找到了那个关键的JS文件。

接下来就简单了——在Burp里配一个自动替换规则:

成了!

规则生效后,重新在微信里操作公众号。配置autoDecoder,用固定的密钥,成功解密content并显示。

回头看:为什么能成?

  1. 前端加密的命门

    :只要代码在用户端执行,就有被篡改的可能

  2. JS文件没保护

    :没签名没校验,中间人想改就改

给开发提个醒

如果你在开发类似功能:

  1. 别太相信前端加密

    :它防君子不防小人,只能增加攻击成本

  2. JS文件加个签名

    :用SRI(Subresource Integrity)至少能防篡改

  3. 关键逻辑放服务端

    :前端能做的基本都能被绕过

最后说两句

这次测试让我再次确认:安全是个系统工程。单个环节再强,链条有弱点还是白搭。

对测试人员来说,有时候就得“不按套路出牌”。直接调试不行,就找别的入口;内存修改不会,就试流量层面。条条大路通罗马,就看能不能找到那条能走通的路。

不过得强调一句:所有测试都得在合法授权下进行,别乱来。

2

网络安全情报攻防站

www.libaisec.com

综合性的技术交流与资源共享社区

专注于红蓝对抗、攻防渗透、威胁情报、数据泄露


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:李白你好 adman adman《搞定那个加密的公众号:一次有点折腾的密钥固定实战》

工具|Floweye 网络安全文章

工具|Floweye

文章总结: Floweye是一款专为安全测试人员设计的Web化被动漏洞扫描平台。该工具具备零配置启动、完全嵌入、智能指纹识别及多引擎扫描等功能,支持实时监控与漏
评论:0   参与:  0