开篇:小程序安全的冰山一角
微信小程序作为当下最热门的应用形态之一,其混合架构在带来开发便利的同时,也隐藏着大量安全风险。作为一名安全研究员,我在实际渗透测试中发现,许多开发者对小程序的安全机制存在明显误解。今天,我们就来揭开小程序渗透测试的神秘面纱,从信息收集到业务逻辑漏洞,系统化剖析30个实战技巧。
一、信息收集:从蛛丝马迹中寻找突破口
(一)源码提取:隐藏在缓存中的秘密
每次打开微信小程序时,系统都会在本地缓存一份wxapkg包。这个看似不起眼的缓存文件,却藏着渗透测试的入口。
实战技巧:
-
在Mac系统中,缓存路径位于 ~/Library/Containers/com.tencent.xinWeChat/Data/.wxapplet/packages/
。 -
使用unveilr工具解密后,你可以直接查看小程序的源码结构。
意外收获:有时会在app.js
中发现明文存储的API密钥,或者在config.json
中找到云环境ID。这些敏感信息往往是渗透测试的起点。
(二)云环境指纹识别:伪装者的破绽
小程序的云开发环境并非完全隐蔽。通过发送特定的HTTP请求,可以轻松识别出云函数的调用路径。
实战操作:
-
发送 GET /_/cloudbaserun HTTP/1.1
请求到ap-shanghai.app.tcloudbase.com
。 -
检查响应头中的 X-TCB-Source
字段,这个标识会暴露云环境的存在。
转折点:在某次测试中,我们发现一个小程序的云函数路径未按默认配置,而是被开发者手动修改。这种自定义路径反而降低了自动化扫描工具的检测率。
(三)WXSS样式表:开发注释的陷阱
样式表中的开发注释,可能是渗透测试的意外收获。比如,某开发者曾在样式表中直接写下了测试账号。
案例重现:
.test-account {content: "admin/Test@2024";}
工具推荐:使用css-secretscanner扫描工具,可以快速定位此类敏感信息。
(四)分包加载路径爆破:隐藏模块的暴露
小程序的分包加载机制,虽然优化了性能,却也埋下了安全隐患。
攻击思路:
-
分析 __APP__.json
中的subpackages配置。 -
构造URL路径,尝试加载未授权的模块。
实战脚本:
for path in ['sub1', 'sub2', 'vip']: url = f'https://{host}/{path}/__bundle__.js' print(requests.get(url).status_code)
意外发现:在某次测试中,我们发现一个分包路径竟直接暴露了数据库配置文件。
二、逆向工程:突破小程序的技术防线
(一)WXML模板注入:危险的动态绑定
动态绑定是小程序开发的便捷功能,却也是安全的薄弱环节。
攻击场景:
<view>{{ userInput }}</view>
利用方法:
userInput = "{{1==alert(1)}}"
防御建议:使用{{{ }}}
替代{{}}
,可以有效防止模板注入。
(二)全局数据窃取:隐藏的宝藏
通过注入代码读取getApp().globalData
,可以轻松获取小程序的全局变量。
实战代码:
const app = getApp()console.log(app.globalData.token)
防御策略:对敏感数据进行加密存储,避免直接暴露在全局对象中。
(三)加密算法逆向:破解签名生成
签名生成算法往往是渗透测试的关键目标。
技术路径:
-
定位 wx.request
的sign参数生成逻辑。 -
使用Hook技术拦截CryptoJS方法。 -
模拟执行加密函数,获取签名值。
意外收获:在某次测试中,我们发现开发者竟直接将密钥硬编码在源码中。
三、API接口渗透:隐藏在请求中的漏洞
(一)云函数未授权调用:开发者的疏忽
许多开发者忘记为云函数配置权限校验,这为渗透测试提供了绝佳机会。
漏洞验证:
POST /tcb/invoke/unauth-function HTTP/1.1{"action": "getUserList"}
防御建议:开启云函数权限校验,并限制调用来源。
(二)GraphQL接口注入:灵活的攻击面
GraphQL的灵活性,使其成为渗透测试的重点目标。
攻击示例:
query { users(filter: "id=1 OR 1=1") { id, phone }}
防御策略:使用参数化查询,并限制查询深度。
(三)支付逻辑漏洞:金额篡改的陷阱
支付逻辑中的金额参数,往往是渗透测试的突破点。
攻击模式:
-
拦截创建订单请求。 -
修改amount值为负数。 -
触发余额异常增长。
检测方法:服务端必须对金额参数进行严格校验。
四、客户端安全突破:从调试到数据窃取
(一)调试模式残留:开发者的疏忽
许多小程序在上线后未关闭调试模式,这为渗透测试提供了便利。
检测代码:
try {debugger;console.log("Debug mode enabled!");} catch(e) {}
利用方法:启用vConsole,获取敏感日志信息。
(二)本地缓存窃取:Storage的隐患
小程序的本地缓存机制,可能泄露大量敏感数据。
实战代码:
const keys = wx.getStorageInfoSync().keyskeys.forEach(key => {console.log(wx.getStorageSync(key))})
防御建议:开启Storage加密,并限制缓存数据的敏感性。
(三)XSS进阶利用:富文本的威胁
富文本编辑器是XSS攻击的重灾区。
攻击Payload:
<web-viewsrc="javascript:alert(document.cookie)">
防御策略:对动态渲染内容进行严格过滤,并使用CSP策略。
五、云环境渗透:从越权到权限提升
(一)云数据库越权访问:开发者的陷阱
未配置权限规则的云数据库,可能允许任意用户读取敏感数据。
漏洞代码:
const db = wx.cloud.database()db.collection('users').where({ role: 'admin' }).get()
加固建议:配置安全规则,限制数据访问范围。
{"read": "auth.uid != null"}
(二)云存储桶ACL错误:公开的危险
云存储桶的错误配置,可能导致敏感文件被公开访问。
检测方法:
PUT /files/secret.txt HTTP/1.1Host: tcb-id.cos.ap-shanghai.myqcloud.com
响应示例:
<AccessControlPolicy><AccessControlList><Grant>AllUsers</Grant></AccessControlList></AccessControlPolicy>
(三)云函数环境变量泄露:隐藏的密钥
云函数环境变量是敏感数据的常见存储位置。
利用方法:
const exec = require('child_process').execexec('env', (err, stdout) => {console.log(stdout) // 显示数据库密码})
防御建议:使用云加密环境变量,并限制代码执行权限。
六、业务逻辑漏洞:从邀请码到无限领取
(一)邀请码逻辑缺陷:熵值过低的隐患
低熵值的邀请码,可能被暴力枚举。
测试用例:
-
生成邀请码时未绑定用户。 -
重复使用单次有效码。 -
暴力枚举6位数字码。
防御策略:提高邀请码的熵值,并在服务端进行绑定验证。
(二)抽奖活动篡改:概率参数的猫腻
前端传递的中奖概率参数,可能被恶意篡改。
攻击方法:
-
修改中奖概率参数。 -
重放中奖请求包。
防御建议:服务端计算概率并签名,避免前端篡改。
(三)虚拟资产无限领取:防重放机制的缺失
缺乏防重放机制的领取接口,可能被无限调用。
漏洞模式:
-
拦截领取优惠券请求。 -
删除请求中的防重放token。 -
使用Burp Intruder批量重放。
防御策略:使用全局唯一事务ID,并限制请求频率。
七、防御体系构建:从技术到管理的全方位防护
(一)技术防护:加固的三重屏障
-
源码混淆加固:使用wcc/wasm进行字节码编译,增加逆向难度。 -
动态运行时保护:注入RASP检测内存修改,防止调试器接入。 -
网络通信加密:禁用HTTP明文传输,强制使用HTTPS。
(二)管理防护:流程与监控的双重保障
-
安全开发生命周期(SDL):将渗透测试纳入上线流程,确保代码质量。 -
第三方组件审计:维护许可组件白名单,避免引入高危依赖。 -
威胁情报监控:订阅微信官方安全通告,及时修复已知漏洞。
结语:安全是一场永无止境的博弈
小程序的安全防护,不仅仅是技术的较量,更是开发者安全意识的体现。从源码提取到业务逻辑漏洞,每一个环节都可能成为渗透测试的突破口。希望这些实战技巧,能帮助开发者更好地理解小程序的安全风险,构建更加坚固的防护体系。毕竟,在安全领域,只有攻得破,才能守得牢。
原文始发于微信公众号(网络侦查研究院):微信小程序渗透实战:30个高阶技巧深度解析
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论