微信小程序的修炼五脉(如意篇下)

2023-09-25 18:50:14 浏览数 (2)

声明

由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,雷神众测以及文章作者不为此承担任何责任。 雷神众测拥有对此文章的修改和解释权。如欲转载或传播此文章,必须保证此文章的完整性,包括版权声明等全部内容。未经雷神众测允许,不得任意修改或者增减此文章内容,不得以任何方式将其用于商业目的。

No.1

前言

如意如意顺我⼼意,若不能顺我⼼意,我将竭尽全⼒,⽤⾃⼰的技术改变其意。

笔者是⼀位极其“不听话”的⼈,我不想要程序它觉得,我要我⾃⼰觉得;⾃⼰重新定义程序的逻辑以及游戏规则,掌控这其中的数据,让每⼀个环节都顺⾃⼰的⼼意,直到看到⾃⼰想要的结果为⽌。在这篇⽂章中,作者将会带领⼤家寻找微信⼩程序中特有且常⻅的任意⼿机号登录漏洞,并为读者们带来⼀种你从未听说以及利⽤过 并且只有在⼩程序中才会存在的类似于CSRF的漏洞。

此专题由于篇幅较⻓将会拆分为“如意篇 (上)”、“如意篇(下)”两篇⽂章,还请您⻅谅。

No.2

神奇的小程序页面

读者朋友们您⼀定收到过如下图中所示的⼩程序分享消息或者⻅到过如下图中所示的⼩程序⼆维码,点 击或扫描之后便可以进⼊特定的⼩程序⻚⾯,您也有可能使⽤过⼩程序内的分享功能,将特定的⻚⾯分享给您的家⼈以及朋友、同事们。

开发过⼩程序的读者都知道,这每⼀个分享链接指向的地址实际上和URL地址相类似,通过在每⼀个⻚⾯之后使⽤ get 的⽅法向对应的⻚⾯传递数据:

例如点击上图⼩程序进⼊对应的分享⻚⾯,实际的分享⻚⾯路径为:pages/archives/detail.html? id=492&title=HackingDay 2019 HangZhou ,向⼩程序中的“detail”⻚⾯传递了“id”参数获取对应的数 据内容和“title”参数显示为当前⼩程序⻚⾯的标题。

当然并不是所有的⻚⾯都可以分享,例如下图所示有些⻚⾯没有开启分享功能便会显示“当前⻚⾯不可转 发”

只有当前⻚⾯的⼩程序代码中使⽤了如下的分享函数,此⻚⾯才可被转发:

onShareAppMessage: function (obj) {

//函数内⾃定义内容

},

⼩程序⻚⾯中可以通过在函数中引⽤ option 数组来获取此⻚⾯ get 传⼊的变量值,例如传⼊的变量名 为“xxx”,那么其对应的内容则为“option.xxx”:

onLoad: function (option) { console.log(option.xxx);

}

由于微信的这⼀分享机制可以使开发者掌控哪些⻚⾯可被分享,哪些⻚⾯不能被分享;并且微信⼩程序⻚与⻚直接传递参数的⽅法的确很简单并且⾮常的实⽤,所以在⽇常⽣活中被⼤量的使⽤。各位同仁们 ⼀定知道CSRF跨站请求伪造漏洞,他本质是利⽤⽹站对⽤户⽹⻚浏览器的信任使被害者主动向⽹站请求 了攻击者精⼼构造之后的数据包,从⽽导致受害者在⽆意之间执⾏了⼀些攻击者所期望的操作。

由于⼩程序的⻚⾯与⻚⾯之间也可以传递参数,那么在特定情况下也可导致类似CSRF的漏洞存在,我们暂且称之为 -- CWRF:跨微信⼩程序请求伪造(Cross WechatAPP Request Forgery)吧,利⽤⼩程序对⽤户微信身份的信任在获取⻚⾯传⼊的参数之后结合⽤户已经登录的身份信息(储存在本地的数据, 或者⽤户的openid)向⼩程序后端发送对应的数据包,从⽽使⽤户在⽆意间(打开对应分享链接时)完 成⼀次请求操作。

读者们在此时必然会产⽣⼀些疑问,微信⼩程序⻚⾯分享的消息内容如何修改呢?有些⼩程序⻚⾯不是 不能分享吗?哪怕⻚⾯能分享,⻚⾯中的参数值如何修改呢?

⽣成对应参数路径的⼩程序码?不⾏,⼩程序码需要有AppSecret才可⽣成;在⼩程序分享之时修改其 分享内容?下断点调试微信这个过程⽐较麻烦;修改本地聊天记录再发送给别⼈?这是⼀个⾮常好⽤且 简单的⽅法。那么笔者在此以微信Mac客户端为例教⼤家如何修改本地⼩程序分享内容。(Win/IOS/安 卓客户端读取聊天记录⽅式可参考⽹上众多教程)

读取本地微信Mac客户端聊天记录:

微信聊天记录储存在 ~/Library/Containers/com.tencent.xinWeChat/Data/Application Support/com.tencent.xinWeChat/{微信版本号}/{⽤户ID}/Message/ ⽬录下,⽂件名命名⽅式为 msg_{数字}.db 他是⼀个使⽤SQLite 3(SQLCipher)的加密数据库。其解密密码提取⽅式如下,这⾥我们需要⽤到Xcode⾃带的 LLDB 调试器:

♥打开微信Mac版进⼊登录界⾯但不要登录(以便后续让其执⾏解密数据库操作);

♥打开终端输⼊ lldb -p $(pgrep WeChat) 进⼊ LLDB 调试器开始调试微信客户端:

♥接着我们使⽤ breakpoint set --name sqlite3_key 命令在微信客户端调⽤数据库解密函数上下断点;

♥ 此时可以使⽤ breakpoint list 命令看到已经成功下了两处断点;

♥由于现在微信客户端出于中⽌状态,输⼊ continue 命令让程序接着运⾏;

♥ 接着便可以执⾏微信登录操作,可以看到成功触发断点;

♥然后输⼊ memory read --size 32 --format x --count 1 $rsi 提取内存中的解密密码;

♥于是我们可以得到的类似“0x6000028a6c00: 0x1e2233159e583bbe1d46805c4d9bd9ff0817851003e929af05474f84e769bc1d”的内容,我们需要将数据使⽤Python做如下处理:

key = "获取到的值"

print("0x" "".join(list(reversed([key.partition(":")[2].replace(" ", "").replace("0x", "")[i:i 2] for i in xrange(0, len(key)-18, 2)]))))

#例如最终输出:0x1dbc69e7844f4705af29e90310851708ffd99b4d5c80461dbe3b589e1533221e

其原理为将冒号前的“0x6000028a6c00”内容删去,并删去空格以及“0x”,然后将余下内容每两位分组并 反序添加上“0x”标识,形成最终的16进制解密⽤ raw_key 。

♥此时可以使⽤ exit 命令退出 LLDB 调试器,让微信正常运⾏;

♥接着我们可使⽤ brew install sqlitebrowser 在Mac OS上安装能读取SQLCipher的软件;

♥下⼀步我们使⽤ DB Browser for SQLite 软件打开刚刚找到的微信聊天数据库,Encryption settings 选择 SQLCipher 3 defaults ,并将密码⽅式设置为 Raw key (笔者这⾥法语界⾯选择:Clé de Chiàrement),接着输⼊获取到的密码并点击OK按钮;

♥若上述操作⽆误,您便可成功打开微信Mac客户端的本地聊天数据库。

(笔者经历:新版微信在没 装Mac微信⼩助⼿之前貌似⽆法使⽤LLDB,安装上去之后就可以了,同样存在类似问题的读者不 妨安装这个插件试试)

修改微信⼩程序消息记录:

在成功进⼊数据库中,找到对应的对话,可以在 msgContent 字段中看⻅微信聊天记录中⼩程序的消 息,他是以XML的形式保存在数据库中的,例如下图:

其中 <title></title> 决定了⼩程序消息的标题内容;<sourcedisplayname> </sourcedisplayname> 决定了⼩程序本身的名字;这⾥最为关键的是 <pagepath></pagepath> 参 数,他决定了⽤户点击⼩程序消息之后将携带什么参数前往⼩程序哪个指定的⻚⾯,例如上图示例中的⻚⾯路径及参数为:pages/index/index.html?username=ThorSRC 。

我们只要修改 <pagepath></pagepath> 参数的内容就可以不受任何分享限制⾃定义⼩程序路径及传参 内容,这⾥需要注意⼀点:在⼩程序源码中⻚⾯路径为 pages/index/XXX ,⽽在运⾏环境下⼩程序⻚ ⾯后需要添加上“.html”变成 pages/index/XXX.html ,其余均⽆变化。

在修改完⼩程序消息的本地消息内容之后,我们只需要将对应的消息转发给他⼈即可:

CWRF实战的典型案例:

例如在如下示例⼩程序,⽤户来到“我的”⻚⾯时程序会⾃动登录向后端请求 openID 等数据并判断当前 微信⽤户是否已经进⾏了与商场⽹⻚账户的绑定操作,若⽆则前往绑定⻚⾯,若已经绑定则将 openID 写⼊缓存之中:

⼩程序JS实现代码如下:

wx.login({

success: function (loginCode) {

//调⽤request请求api转换登录凭证 wx.request({

url: 'http://demo.c-est.cool/ThorSRC/login.php?js_code=' loginCode.code,

header: {

'content-type': 'application/json'

},

success: function (res) {

if (res.data.isbind == 0) {

wx.showModal({

title: "提示", //前往绑定⻚⾯

content: "请绑定商城账户",

showCancel: !1,

success: function (e) {

wx.navigateTo({

url: "/pages/user/bind" }); } }); }wx.setStorage({ //保存openid到缓存之中 key: "openid", data: res.data.openid

}) }

}) }

});

后端API返回内容如下:

{"openid":"oCzqR4vmnk0isZ8TOwc9i9VPWBdM","isbind":1,"binduser":"Poc Sir"}

可以看到⽤户在此⼩程序内的OpenID已经成功的写⼊了缓存之中:

接着我们点击修改密码按钮,⼩程序会弹出如下让我们修改密码的弹窗:

其功能实现WXML源码如下:

对应功能的JS代码如下:

可以看到上述JS代码中 changeFn 会判断⽤户两次输⼊的密码是否⼀致,若⼀致则将⽤户输⼊的密码作 为参数传⼊⼩程序的“/pages/my/changepwd”⻚⾯中。接着我们来到“/pages/my/changepwd”观察其 核⼼功能函数如下:

⼩程序会将传⼊的密码和保存在本地Storage中的与对应商城⽤户绑定的微信⽤户openid值⼀起传回给 后端服务器,服务器后端通过查询openid对应的⽤户信息来修改对应⽤户的密码。那么我们只需要构造 ⼀个微信⼩程序的⻚⾯指向 /pages/my/changepwd.html?newpwd=XXX⾃⼰预设密码 ,并让其他已绑定商 城账户的⼈点击我们构造好的微信⼩程序消息,那么他在此商城的密码就会被⾃动更改为我们预设的 值。例如下图我们将 <pagepath> 值设置为:/pages/my/changepwd.html?newpwd=Abc@123456 ,预设密码即为 Abc@123456 :

接着我们将构造好的消息转发给被害者,诱导其点击⼩程序消息访问对应的⻚⾯:

⼀但⽤户点击了对应的消息⻚⾯打开微信⼩程序,他的商城账户密码即被修改为了 Abc@123456 ,可以 看到受害者点击之后提示密码修改成功的⻚⾯如下:

⾄此我们完成了⼀次典型且易被利⽤的CWRF攻击,虽然并不是所有的CWRF攻击都能造成⾮常严重的危 害,但这类漏洞并⾮⽆稽之谈,⽬前在很多微信或者其他⼩程序中还隐藏着许多类似的脆弱点。

快速搜索⻚⾯间跳转:

有CWRF漏洞存在的⼩程序⻚⾯,其⻚⾯必然有被有⻚⾯跳转功能的函数所引⽤过,那么只要在项⽬中 找到哪些代码⽚段引⽤了这些函数便可快速判定是否有CWRF漏洞的存在。微信⼩程序JS⽂件中有如下三 个可切换⻚⾯的函数:

♥wx.reLaunch -- 关闭所有⻚⾯,打开到应⽤内的某个⻚⾯

♥wx.navigateTo -- 保留当前⻚⾯,跳转到应⽤内的某个⻚⾯

♥wx.redirectTo -- 关闭当前⻚⾯,跳转到应⽤内的某个⻚⾯

wx.redirectTo({ url: "/pages/frame/frame?id=1" })

也可在微信⼩程序WXML中使⽤ navigator 标签进⾏⻚⾯切换:

<navigator url="/pages/account/info?uid={{uid}}"> ... </navigator>

当然最⽅便的⽅式便是以 /pages/ (有些⼩程序⻚⾯不以此⽂件夹开头,请读者视情况⽽改变)作为关 键字在⼩程序内全局搜索,可以⼀个不落的将所有的结果快速返回出来:

0 人点赞